Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Browse files Browse the repository at this point in the history
Pull SCSI target fixes from Nicholas Bellinger:
 "Here are the target-pending fixes for v4.12-rc4:

   - ibmviscsis ABORT_TASK handling fixes that missed the v4.12 merge
     window. (Bryant Ly and Michael Cyr)

   - Re-add a target-core check enforcing WRITE overflow reject that was
     relaxed in v4.3, to avoid unsupported iscsi-target immediate data
     overflow. (nab)

   - Fix a target-core-user OOPs during device removal. (MNC + Bryant
     Ly)

   - Fix a long standing iscsi-target potential issue where kthread exit
     did not wait for kthread_should_stop(). (Jiang Yi)

   - Fix a iscsi-target v3.12.y regression OOPs involving initial login
     PDU processing during asynchronous TCP connection close. (MNC +
     nab)

  This is a little larger than usual for an -rc4, primarily due to the
  iscsi-target v3.12.y regression OOPs bug-fix.

  However, it's an important patch as MNC + Hannes where both able to
  trigger it using a reduced iscsi initiator login timeout combined with
  a backend taking a long time to complete I/Os during iscsi login
  driven session reinstatement"

* git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
  iscsi-target: Always wait for kthread_should_stop() before kthread exit
  iscsi-target: Fix initial login PDU asynchronous socket close OOPs
  tcmu: fix crash during device removal
  target: Re-add check to reject control WRITEs with overflow data
  ibmvscsis: Fix the incorrect req_lim_delta
  ibmvscsis: Clear left-over abort_cmd pointers
  • Loading branch information
Linus Torvalds committed Jun 1, 2017
2 parents a374846 + 5e0cf5e commit 393bcfa
Show file tree
Hide file tree
Showing 9 changed files with 241 additions and 92 deletions.
27 changes: 23 additions & 4 deletions drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1170,6 +1170,8 @@ static struct ibmvscsis_cmd *ibmvscsis_get_free_cmd(struct scsi_info *vscsi)
cmd = list_first_entry_or_null(&vscsi->free_cmd,
struct ibmvscsis_cmd, list);
if (cmd) {
if (cmd->abort_cmd)
cmd->abort_cmd = NULL;
cmd->flags &= ~(DELAY_SEND);
list_del(&cmd->list);
cmd->iue = iue;
Expand Down Expand Up @@ -1774,6 +1776,7 @@ static void ibmvscsis_send_messages(struct scsi_info *vscsi)
if (cmd->abort_cmd) {
retry = true;
cmd->abort_cmd->flags &= ~(DELAY_SEND);
cmd->abort_cmd = NULL;
}

/*
Expand All @@ -1788,6 +1791,25 @@ static void ibmvscsis_send_messages(struct scsi_info *vscsi)
list_del(&cmd->list);
ibmvscsis_free_cmd_resources(vscsi,
cmd);
/*
* With a successfully aborted op
* through LIO we want to increment the
* the vscsi credit so that when we dont
* send a rsp to the original scsi abort
* op (h_send_crq), but the tm rsp to
* the abort is sent, the credit is
* correctly sent with the abort tm rsp.
* We would need 1 for the abort tm rsp
* and 1 credit for the aborted scsi op.
* Thus we need to increment here.
* Also we want to increment the credit
* here because we want to make sure
* cmd is actually released first
* otherwise the client will think it
* it can send a new cmd, and we could
* find ourselves short of cmd elements.
*/
vscsi->credit += 1;
} else {
iue = cmd->iue;

Expand Down Expand Up @@ -2962,10 +2984,7 @@ static long srp_build_response(struct scsi_info *vscsi,

rsp->opcode = SRP_RSP;

if (vscsi->credit > 0 && vscsi->state == SRP_PROCESSING)
rsp->req_lim_delta = cpu_to_be32(vscsi->credit);
else
rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit);
rsp->req_lim_delta = cpu_to_be32(1 + vscsi->credit);
rsp->tag = cmd->rsp.tag;
rsp->flags = 0;

Expand Down
30 changes: 24 additions & 6 deletions drivers/target/iscsi/iscsi_target.c
Original file line number Diff line number Diff line change
Expand Up @@ -3790,6 +3790,8 @@ int iscsi_target_tx_thread(void *arg)
{
int ret = 0;
struct iscsi_conn *conn = arg;
bool conn_freed = false;

/*
* Allow ourselves to be interrupted by SIGINT so that a
* connection recovery / failure event can be triggered externally.
Expand All @@ -3815,12 +3817,14 @@ int iscsi_target_tx_thread(void *arg)
goto transport_err;

ret = iscsit_handle_response_queue(conn);
if (ret == 1)
if (ret == 1) {
goto get_immediate;
else if (ret == -ECONNRESET)
} else if (ret == -ECONNRESET) {
conn_freed = true;
goto out;
else if (ret < 0)
} else if (ret < 0) {
goto transport_err;
}
}

transport_err:
Expand All @@ -3830,8 +3834,13 @@ int iscsi_target_tx_thread(void *arg)
* responsible for cleaning up the early connection failure.
*/
if (conn->conn_state != TARG_CONN_STATE_IN_LOGIN)
iscsit_take_action_for_connection_exit(conn);
iscsit_take_action_for_connection_exit(conn, &conn_freed);
out:
if (!conn_freed) {
while (!kthread_should_stop()) {
msleep(100);
}
}
return 0;
}

Expand Down Expand Up @@ -4004,6 +4013,7 @@ int iscsi_target_rx_thread(void *arg)
{
int rc;
struct iscsi_conn *conn = arg;
bool conn_freed = false;

/*
* Allow ourselves to be interrupted by SIGINT so that a
Expand All @@ -4016,7 +4026,7 @@ int iscsi_target_rx_thread(void *arg)
*/
rc = wait_for_completion_interruptible(&conn->rx_login_comp);
if (rc < 0 || iscsi_target_check_conn_state(conn))
return 0;
goto out;

if (!conn->conn_transport->iscsit_get_rx_pdu)
return 0;
Expand All @@ -4025,7 +4035,15 @@ int iscsi_target_rx_thread(void *arg)

if (!signal_pending(current))
atomic_set(&conn->transport_failed, 1);
iscsit_take_action_for_connection_exit(conn);
iscsit_take_action_for_connection_exit(conn, &conn_freed);

out:
if (!conn_freed) {
while (!kthread_should_stop()) {
msleep(100);
}
}

return 0;
}

Expand Down
6 changes: 5 additions & 1 deletion drivers/target/iscsi/iscsi_target_erl0.c
Original file line number Diff line number Diff line change
Expand Up @@ -930,8 +930,10 @@ static void iscsit_handle_connection_cleanup(struct iscsi_conn *conn)
}
}

void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn, bool *conn_freed)
{
*conn_freed = false;

spin_lock_bh(&conn->state_lock);
if (atomic_read(&conn->connection_exit)) {
spin_unlock_bh(&conn->state_lock);
Expand All @@ -942,6 +944,7 @@ void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
if (conn->conn_state == TARG_CONN_STATE_IN_LOGOUT) {
spin_unlock_bh(&conn->state_lock);
iscsit_close_connection(conn);
*conn_freed = true;
return;
}

Expand All @@ -955,4 +958,5 @@ void iscsit_take_action_for_connection_exit(struct iscsi_conn *conn)
spin_unlock_bh(&conn->state_lock);

iscsit_handle_connection_cleanup(conn);
*conn_freed = true;
}
2 changes: 1 addition & 1 deletion drivers/target/iscsi/iscsi_target_erl0.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ extern int iscsit_stop_time2retain_timer(struct iscsi_session *);
extern void iscsit_connection_reinstatement_rcfr(struct iscsi_conn *);
extern void iscsit_cause_connection_reinstatement(struct iscsi_conn *, int);
extern void iscsit_fall_back_to_erl0(struct iscsi_session *);
extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *);
extern void iscsit_take_action_for_connection_exit(struct iscsi_conn *, bool *);

#endif /*** ISCSI_TARGET_ERL0_H ***/
4 changes: 4 additions & 0 deletions drivers/target/iscsi/iscsi_target_login.c
Original file line number Diff line number Diff line change
Expand Up @@ -1464,5 +1464,9 @@ int iscsi_target_login_thread(void *arg)
break;
}

while (!kthread_should_stop()) {
msleep(100);
}

return 0;
}
Loading

0 comments on commit 393bcfa

Please sign in to comment.