Do not lock istate_lock except directly around i_state modifications.
Put entire ISTATE_SEND_DATAIN path within first switch statement, in prep
for further refactoring.
All other cases set use_misc = 1 and will not be using sendpage, so just
use send_tx_data for these and set use_misc param to 1.
map_sg, sent_status, use_misc, and se_cmd vars no longer needed.
Signed-off-by: Andy Grover <agrover@xxxxxxxxxx>
---
drivers/target/iscsi/iscsi_target.c | 158 ++++++++++++++---------------------
1 files changed, 63 insertions(+), 95 deletions(-)
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 2f44af8..c0e839a 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -2433,10 +2433,19 @@ static int iscsit_send_conn_drop_async_message(
return 0;
}
+static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn)
+{
+ if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
+ (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
+ wait_for_completion_interruptible_timeout(
+ &conn->tx_half_close_comp,
+ ISCSI_TX_THREAD_TCP_TIMEOUT * HZ);
+ }
+}
+
static int iscsit_send_data_in(
struct iscsi_cmd *cmd,
- struct iscsi_conn *conn,
- int *eodr)
+ struct iscsi_conn *conn)
{
int iov_ret = 0, set_statsn = 0;
u32 iov_count = 0, tx_size = 0;
@@ -2444,6 +2453,8 @@ static int iscsit_send_data_in(
struct iscsi_datain_req *dr;
struct iscsi_data_rsp *hdr;
struct kvec *iov;
+ int eodr = 0;
+ int ret;
memset(&datain, 0, sizeof(struct iscsi_datain));
dr = iscsit_get_datain_values(cmd, &datain);
@@ -2576,13 +2587,26 @@ static int iscsit_send_data_in(
cmd->init_task_tag, ntohl(hdr->statsn), ntohl(hdr->datasn),
ntohl(hdr->offset), datain.length, conn->cid);
+ /* sendpage is preferred but can't insert markers */
+ if (!conn->conn_ops->IFMarker)
+ ret = iscsit_fe_sendpage_sg(cmd, conn);
+ else
+ ret = iscsit_send_tx_data(cmd, conn, 0);
+
+ iscsit_unmap_iovec(cmd);
+
+ if (ret < 0) {
+ iscsit_tx_thread_wait_for_tcp(conn);
+ return ret;
+ }
+
if (dr->dr_complete) {
- *eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ?
+ eodr = (cmd->se_cmd.se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) ?
2 : 1;
iscsit_free_datain_req(cmd, dr);
}
- return 0;
+ return eodr;
}
static int iscsit_send_logout_response(
@@ -2704,16 +2728,6 @@ static int iscsit_send_logout_response(
return 0;
}
-static void iscsit_tx_thread_wait_for_tcp(struct iscsi_conn *conn)
-{
- if ((conn->sock->sk->sk_shutdown & SEND_SHUTDOWN) ||
- (conn->sock->sk->sk_shutdown & RCV_SHUTDOWN)) {
- wait_for_completion_interruptible_timeout(
- &conn->tx_half_close_comp,
- ISCSI_TX_THREAD_TCP_TIMEOUT * HZ);
- }
-}
-
/*
* Unsolicited NOPIN, either requesting a response or not.
*/
@@ -3497,11 +3511,7 @@ static inline void iscsit_thread_check_cpumask(
int iscsi_target_tx_thread(void *arg)
{
u8 state;
- int eodr = 0;
int ret = 0;
- int sent_status = 0;
- int use_misc = 0;
- int map_sg = 0;
struct iscsi_cmd *cmd = NULL;
struct iscsi_conn *conn;
struct iscsi_queue_req *qr = NULL;
@@ -3517,7 +3527,7 @@ restart:
if (!conn)
goto out;
- eodr = map_sg = ret = sent_status = use_misc = 0;
+ ret = 0;
while (!kthread_should_stop()) {
/*
@@ -3581,45 +3591,50 @@ restart:
state = qr->state;
kmem_cache_free(lio_qr_cache, qr);
- spin_lock_bh(&cmd->istate_lock);
check_rsp_state:
switch (state) {
case ISTATE_SEND_DATAIN:
- spin_unlock_bh(&cmd->istate_lock);
- ret = iscsit_send_data_in(cmd, conn,
- &eodr);
- map_sg = 1;
+ ret = iscsit_send_data_in(cmd, conn);
+ if (ret < 0)
+ goto transport_err;
+ else if (!ret)
+ /* more drs */
+ goto check_rsp_state;
+ else if (ret == 1) {
+ /* all done */
+ spin_lock_bh(&cmd->istate_lock);
+ cmd->i_state = ISTATE_SENT_STATUS;
+ spin_unlock_bh(&cmd->istate_lock);
+ continue;
+ } else if (ret == 2) {
+ /* Still must send status,
+ SCF_TRANSPORT_TASK_SENSE was set */
+ spin_lock_bh(&cmd->istate_lock);
+ cmd->i_state = ISTATE_SEND_STATUS;
+ spin_unlock_bh(&cmd->istate_lock);
+ state = ISTATE_SEND_STATUS;
+ goto check_rsp_state;
+ }
+
break;
case ISTATE_SEND_STATUS:
case ISTATE_SEND_STATUS_RECOVERY:
- spin_unlock_bh(&cmd->istate_lock);
- use_misc = 1;
ret = iscsit_send_status(cmd, conn);
break;
case ISTATE_SEND_LOGOUTRSP:
- spin_unlock_bh(&cmd->istate_lock);
- use_misc = 1;
ret = iscsit_send_logout_response(cmd, conn);
break;
case ISTATE_SEND_ASYNCMSG:
- spin_unlock_bh(&cmd->istate_lock);
- use_misc = 1;
ret = iscsit_send_conn_drop_async_message(
cmd, conn);
break;
case ISTATE_SEND_NOPIN:
- spin_unlock_bh(&cmd->istate_lock);
- use_misc = 1;
ret = iscsit_send_nopin_response(cmd, conn);
break;
case ISTATE_SEND_REJECT:
- spin_unlock_bh(&cmd->istate_lock);
- use_misc = 1;
ret = iscsit_send_reject(cmd, conn);
break;
case ISTATE_SEND_TASKMGTRSP:
- spin_unlock_bh(&cmd->istate_lock);
- use_misc = 1;
ret = iscsit_send_task_mgt_rsp(cmd, conn);
if (ret != 0)
break;
@@ -3628,8 +3643,6 @@ check_rsp_state:
iscsit_fall_back_to_erl0(conn->sess);
break;
case ISTATE_SEND_TEXTRSP:
- spin_unlock_bh(&cmd->istate_lock);
- use_misc = 1;
ret = iscsit_send_text_rsp(cmd, conn);
break;
default:
@@ -3637,94 +3650,49 @@ check_rsp_state:
" 0x%08x, i_state: %d on CID: %hu\n",
cmd->iscsi_opcode, cmd->init_task_tag,
state, conn->cid);
- spin_unlock_bh(&cmd->istate_lock);
goto transport_err;
}
if (ret < 0)
goto transport_err;
- if (map_sg && !conn->conn_ops->IFMarker) {
- if (iscsit_fe_sendpage_sg(cmd, conn) < 0) {
- iscsit_tx_thread_wait_for_tcp(conn);
- iscsit_unmap_iovec(cmd);
- goto transport_err;
- }
- } else {
- if (iscsit_send_tx_data(cmd, conn, use_misc) < 0) {
- iscsit_tx_thread_wait_for_tcp(conn);
- iscsit_unmap_iovec(cmd);
- goto transport_err;
- }
+ if (iscsit_send_tx_data(cmd, conn, 1) < 0) {
+ iscsit_tx_thread_wait_for_tcp(conn);
+ iscsit_unmap_iovec(cmd);
+ goto transport_err;
}
- map_sg = 0;
iscsit_unmap_iovec(cmd);
- spin_lock_bh(&cmd->istate_lock);
switch (state) {
- case ISTATE_SEND_DATAIN:
- if (!eodr)
- goto check_rsp_state;
-
- if (eodr == 1) {
- cmd->i_state = ISTATE_SENT_LAST_DATAIN;
- sent_status = 1;
- eodr = use_misc = 0;
- } else if (eodr == 2) {
- cmd->i_state = state =
- ISTATE_SEND_STATUS;
- sent_status = 0;
- eodr = use_misc = 0;
- goto check_rsp_state;
- }
- break;
+ case ISTATE_SEND_LOGOUTRSP:
+ if (!iscsit_logout_post_handler(cmd, conn))
+ goto restart;
+ /* fall through */
case ISTATE_SEND_STATUS:
- use_misc = 0;
- sent_status = 1;
- break;
case ISTATE_SEND_ASYNCMSG:
case ISTATE_SEND_NOPIN:
case ISTATE_SEND_STATUS_RECOVERY:
case ISTATE_SEND_TEXTRSP:
- use_misc = 0;
- sent_status = 1;
+ case ISTATE_SEND_TASKMGTRSP:
+ spin_lock_bh(&cmd->istate_lock);
+ cmd->i_state = ISTATE_SENT_STATUS;
+ spin_unlock_bh(&cmd->istate_lock);
break;
case ISTATE_SEND_REJECT:
- use_misc = 0;
if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) {
cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN;
- spin_unlock_bh(&cmd->istate_lock);
complete(&cmd->reject_comp);
goto transport_err;
}
complete(&cmd->reject_comp);
break;
- case ISTATE_SEND_TASKMGTRSP:
- use_misc = 0;
- sent_status = 1;
- break;
- case ISTATE_SEND_LOGOUTRSP:
- spin_unlock_bh(&cmd->istate_lock);
- if (!iscsit_logout_post_handler(cmd, conn))
- goto restart;
- spin_lock_bh(&cmd->istate_lock);
- use_misc = 0;
- sent_status = 1;
- break;
default:
pr_err("Unknown Opcode: 0x%02x ITT:"
" 0x%08x, i_state: %d on CID: %hu\n",
cmd->iscsi_opcode, cmd->init_task_tag,
cmd->i_state, conn->cid);
- spin_unlock_bh(&cmd->istate_lock);
goto transport_err;
}
- if (sent_status) {
- cmd->i_state = ISTATE_SENT_STATUS;
- sent_status = 0;
- }
- spin_unlock_bh(&cmd->istate_lock);
-
if (atomic_read(&conn->check_immediate_queue))
break;
}
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Linux SCSI]
[Kernel Newbies]
[Linux SCSI Target Infrastructure]
[Share Photos]
[IDE]
[Security]
[Git]
[Netfilter]
[Bugtraq]
[Photos]
[Yosemite]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Linux ATA RAID]
[Linux IIO]
[Samba]
[Video 4 Linux]
[Device Mapper]
[Linux Resources]