]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Aug 2013 23:28:02 +0000 (07:28 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 1 Aug 2013 23:28:02 +0000 (07:28 +0800)
added patches:
iscsi-target-fix-iscsit_add_reject-usage-for-iser.patch
iscsi-target-fix-iscsit_sequence_cmd-reject-handling-for-iser.patch
perf-tools-revert-regression-in-configuration-of-python-support.patch
radeon-kms-do-not-flush-uninitialized-hotplug-work.patch
xen-evtchn-avoid-a-deadlock-when-unbinding-an-event-channel.patch

queue-3.10/iscsi-target-fix-iscsit_add_reject-usage-for-iser.patch [new file with mode: 0644]
queue-3.10/iscsi-target-fix-iscsit_sequence_cmd-reject-handling-for-iser.patch [new file with mode: 0644]
queue-3.10/perf-tools-revert-regression-in-configuration-of-python-support.patch [new file with mode: 0644]
queue-3.10/radeon-kms-do-not-flush-uninitialized-hotplug-work.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/xen-evtchn-avoid-a-deadlock-when-unbinding-an-event-channel.patch [new file with mode: 0644]

diff --git a/queue-3.10/iscsi-target-fix-iscsit_add_reject-usage-for-iser.patch b/queue-3.10/iscsi-target-fix-iscsit_add_reject-usage-for-iser.patch
new file mode 100644 (file)
index 0000000..594bc3c
--- /dev/null
@@ -0,0 +1,806 @@
+From nab@linux-iscsi.org  Fri Aug  2 06:54:09 2013
+From: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
+Date: Tue, 30 Jul 2013 04:04:01 +0000
+Subject: iscsi-target: Fix iscsit_add_reject* usage for iser
+To: target-devel <target-devel@vger.kernel.org>
+Cc: Greg-KH <gregkh@linuxfoundation.org>, Stable <stable@vger.kernel.org>, Nicholas Bellinger <nab@linux-iscsi.org>, Or Gerlitz <ogerlitz@mellanox.com>, Mike Christie <michaelc@cs.wisc.edu>
+Message-ID: <1375157042-25935-2-git-send-email-nab@linux-iscsi.org>
+
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit ba159914086f06532079fc15141f46ffe7e04a41 upstream
+
+This patch changes iscsit_add_reject() + iscsit_add_reject_from_cmd()
+usage to not sleep on iscsi_cmd->reject_comp to address a free-after-use
+usage bug in v3.10 with iser-target code.
+
+It saves ->reject_reason for use within iscsit_build_reject() so the
+correct value for both transport cases.  It also drops the legacy
+fail_conn parameter usage throughput iscsi-target code and adds
+two iscsit_add_reject_cmd() and iscsit_reject_cmd helper functions,
+along with various small cleanups.
+
+(v2: Re-enable target_put_sess_cmd() to be called from
+     iscsit_add_reject_from_cmd() for rejects invoked after
+     target_get_sess_cmd() has been called)
+
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Cc: Or Gerlitz <ogerlitz@mellanox.com>
+Cc: Mike Christie <michaelc@cs.wisc.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/ulp/isert/ib_isert.c  |    5 
+ drivers/target/iscsi/iscsi_target.c      |  251 ++++++++++++-------------------
+ drivers/target/iscsi/iscsi_target.h      |    2 
+ drivers/target/iscsi/iscsi_target_core.h |    4 
+ drivers/target/iscsi/iscsi_target_erl0.c |    7 
+ drivers/target/iscsi/iscsi_target_erl1.c |   20 +-
+ drivers/target/iscsi/iscsi_target_util.c |    1 
+ include/target/iscsi/iscsi_transport.h   |    2 
+ 8 files changed, 116 insertions(+), 176 deletions(-)
+
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -957,11 +957,6 @@ sequence_cmd:
+       if (!rc && dump_payload == false && unsol_data)
+               iscsit_set_unsoliticed_dataout(cmd);
+-      if (rc == CMDSN_ERROR_CANNOT_RECOVER)
+-              return iscsit_add_reject_from_cmd(
+-                         ISCSI_REASON_PROTOCOL_ERROR,
+-                         1, 0, (unsigned char *)hdr, cmd);
+-
+       return 0;
+ }
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -628,25 +628,18 @@ static void __exit iscsi_target_cleanup_
+ }
+ static int iscsit_add_reject(
++      struct iscsi_conn *conn,
+       u8 reason,
+-      int fail_conn,
+-      unsigned char *buf,
+-      struct iscsi_conn *conn)
++      unsigned char *buf)
+ {
+       struct iscsi_cmd *cmd;
+-      struct iscsi_reject *hdr;
+-      int ret;
+       cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
+       if (!cmd)
+               return -1;
+       cmd->iscsi_opcode = ISCSI_OP_REJECT;
+-      if (fail_conn)
+-              cmd->cmd_flags |= ICF_REJECT_FAIL_CONN;
+-
+-      hdr     = (struct iscsi_reject *) cmd->pdu;
+-      hdr->reason = reason;
++      cmd->reject_reason = reason;
+       cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
+       if (!cmd->buf_ptr) {
+@@ -662,23 +655,16 @@ static int iscsit_add_reject(
+       cmd->i_state = ISTATE_SEND_REJECT;
+       iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
+-      ret = wait_for_completion_interruptible(&cmd->reject_comp);
+-      if (ret != 0)
+-              return -1;
+-
+-      return (!fail_conn) ? 0 : -1;
++      return -1;
+ }
+-int iscsit_add_reject_from_cmd(
++static int iscsit_add_reject_from_cmd(
++      struct iscsi_cmd *cmd,
+       u8 reason,
+-      int fail_conn,
+-      int add_to_conn,
+-      unsigned char *buf,
+-      struct iscsi_cmd *cmd)
++      bool add_to_conn,
++      unsigned char *buf)
+ {
+       struct iscsi_conn *conn;
+-      struct iscsi_reject *hdr;
+-      int ret;
+       if (!cmd->conn) {
+               pr_err("cmd->conn is NULL for ITT: 0x%08x\n",
+@@ -688,11 +674,7 @@ int iscsit_add_reject_from_cmd(
+       conn = cmd->conn;
+       cmd->iscsi_opcode = ISCSI_OP_REJECT;
+-      if (fail_conn)
+-              cmd->cmd_flags |= ICF_REJECT_FAIL_CONN;
+-
+-      hdr     = (struct iscsi_reject *) cmd->pdu;
+-      hdr->reason = reason;
++      cmd->reject_reason = reason;
+       cmd->buf_ptr = kmemdup(buf, ISCSI_HDR_LEN, GFP_KERNEL);
+       if (!cmd->buf_ptr) {
+@@ -709,8 +691,6 @@ int iscsit_add_reject_from_cmd(
+       cmd->i_state = ISTATE_SEND_REJECT;
+       iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
+-
+-      ret = wait_for_completion_interruptible(&cmd->reject_comp);
+       /*
+        * Perform the kref_put now if se_cmd has already been setup by
+        * scsit_setup_scsi_cmd()
+@@ -719,12 +699,19 @@ int iscsit_add_reject_from_cmd(
+               pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n");
+               target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
+       }
+-      if (ret != 0)
+-              return -1;
++      return -1;
++}
++
++static int iscsit_add_reject_cmd(struct iscsi_cmd *cmd, u8 reason,
++                               unsigned char *buf)
++{
++      return iscsit_add_reject_from_cmd(cmd, reason, true, buf);
++}
+-      return (!fail_conn) ? 0 : -1;
++int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8 reason, unsigned char *buf)
++{
++      return iscsit_add_reject_from_cmd(cmd, reason, false, buf);
+ }
+-EXPORT_SYMBOL(iscsit_add_reject_from_cmd);
+ /*
+  * Map some portion of the allocated scatterlist to an iovec, suitable for
+@@ -844,8 +831,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_c
+           !(hdr->flags & ISCSI_FLAG_CMD_FINAL)) {
+               pr_err("ISCSI_FLAG_CMD_WRITE & ISCSI_FLAG_CMD_FINAL"
+                               " not set. Bad iSCSI Initiator.\n");
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_BOOKMARK_INVALID, buf);
+       }
+       if (((hdr->flags & ISCSI_FLAG_CMD_READ) ||
+@@ -865,8 +852,8 @@ int iscsit_setup_scsi_cmd(struct iscsi_c
+               pr_err("ISCSI_FLAG_CMD_READ or ISCSI_FLAG_CMD_WRITE"
+                       " set when Expected Data Transfer Length is 0 for"
+                       " CDB: 0x%02x. Bad iSCSI Initiator.\n", hdr->cdb[0]);
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_BOOKMARK_INVALID, buf);
+       }
+ done:
+@@ -875,62 +862,62 @@ done:
+               pr_err("ISCSI_FLAG_CMD_READ and/or ISCSI_FLAG_CMD_WRITE"
+                       " MUST be set if Expected Data Transfer Length is not 0."
+                       " Bad iSCSI Initiator\n");
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_BOOKMARK_INVALID, buf);
+       }
+       if ((hdr->flags & ISCSI_FLAG_CMD_READ) &&
+           (hdr->flags & ISCSI_FLAG_CMD_WRITE)) {
+               pr_err("Bidirectional operations not supported!\n");
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_BOOKMARK_INVALID, buf);
+       }
+       if (hdr->opcode & ISCSI_OP_IMMEDIATE) {
+               pr_err("Illegally set Immediate Bit in iSCSI Initiator"
+                               " Scsi Command PDU.\n");
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_BOOKMARK_INVALID, buf);
+       }
+       if (payload_length && !conn->sess->sess_ops->ImmediateData) {
+               pr_err("ImmediateData=No but DataSegmentLength=%u,"
+                       " protocol error.\n", payload_length);
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_PROTOCOL_ERROR, buf);
+       }
+-      if ((be32_to_cpu(hdr->data_length )== payload_length) &&
++      if ((be32_to_cpu(hdr->data_length) == payload_length) &&
+           (!(hdr->flags & ISCSI_FLAG_CMD_FINAL))) {
+               pr_err("Expected Data Transfer Length and Length of"
+                       " Immediate Data are the same, but ISCSI_FLAG_CMD_FINAL"
+                       " bit is not set protocol error\n");
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_PROTOCOL_ERROR, buf);
+       }
+       if (payload_length > be32_to_cpu(hdr->data_length)) {
+               pr_err("DataSegmentLength: %u is greater than"
+                       " EDTL: %u, protocol error.\n", payload_length,
+                               hdr->data_length);
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_PROTOCOL_ERROR, buf);
+       }
+       if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
+               pr_err("DataSegmentLength: %u is greater than"
+                       " MaxXmitDataSegmentLength: %u, protocol error.\n",
+                       payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_PROTOCOL_ERROR, buf);
+       }
+       if (payload_length > conn->sess->sess_ops->FirstBurstLength) {
+               pr_err("DataSegmentLength: %u is greater than"
+                       " FirstBurstLength: %u, protocol error.\n",
+                       payload_length, conn->sess->sess_ops->FirstBurstLength);
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+-                              1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_BOOKMARK_INVALID, buf);
+       }
+       data_direction = (hdr->flags & ISCSI_FLAG_CMD_WRITE) ? DMA_TO_DEVICE :
+@@ -985,9 +972,8 @@ done:
+               dr = iscsit_allocate_datain_req();
+               if (!dr)
+-                      return iscsit_add_reject_from_cmd(
+-                                      ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                                      1, 1, buf, cmd);
++                      return iscsit_add_reject_cmd(cmd,
++                                      ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
+               iscsit_attach_datain_req(cmd, dr);
+       }
+@@ -1015,18 +1001,16 @@ done:
+       cmd->sense_reason = target_setup_cmd_from_cdb(&cmd->se_cmd, hdr->cdb);
+       if (cmd->sense_reason) {
+               if (cmd->sense_reason == TCM_OUT_OF_RESOURCES) {
+-                      return iscsit_add_reject_from_cmd(
+-                                      ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                                      1, 1, buf, cmd);
++                      return iscsit_add_reject_cmd(cmd,
++                                      ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
+               }
+               goto attach_cmd;
+       }
+       if (iscsit_build_pdu_and_seq_lists(cmd, payload_length) < 0) {
+-              return iscsit_add_reject_from_cmd(
+-                      ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                      1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                              ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
+       }
+ attach_cmd:
+@@ -1075,10 +1059,6 @@ int iscsit_process_scsi_cmd(struct iscsi
+                       target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
+                       return 0;
+-              } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) {
+-                      return iscsit_add_reject_from_cmd(
+-                              ISCSI_REASON_PROTOCOL_ERROR,
+-                              1, 0, (unsigned char *)hdr, cmd);
+               }
+       }
+@@ -1149,11 +1129,6 @@ after_immediate_data:
+               } else if (cmd->unsolicited_data)
+                       iscsit_set_unsoliticed_dataout(cmd);
+-              if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+-                      return iscsit_add_reject_from_cmd(
+-                              ISCSI_REASON_PROTOCOL_ERROR,
+-                              1, 0, (unsigned char *)hdr, cmd);
+-
+       } else if (immed_ret == IMMEDIATE_DATA_ERL1_CRC_FAILURE) {
+               /*
+                * Immediate Data failed DataCRC and ERL>=1,
+@@ -1190,9 +1165,8 @@ iscsit_handle_scsi_cmd(struct iscsi_conn
+        * traditional iSCSI block I/O.
+        */
+       if (iscsit_allocate_iovecs(cmd) < 0) {
+-              return iscsit_add_reject_from_cmd(
+-                              ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                              1, 0, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                              ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
+       }
+       immed_data = cmd->immediate_data;
+@@ -1283,8 +1257,8 @@ iscsit_check_dataout_hdr(struct iscsi_co
+       if (!payload_length) {
+               pr_err("DataOUT payload is ZERO, protocol error.\n");
+-              return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
+-                                      buf, conn);
++              return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
++                                       buf);
+       }
+       /* iSCSI write */
+@@ -1301,8 +1275,8 @@ iscsit_check_dataout_hdr(struct iscsi_co
+               pr_err("DataSegmentLength: %u is greater than"
+                       " MaxXmitDataSegmentLength: %u\n", payload_length,
+                       conn->conn_ops->MaxXmitDataSegmentLength);
+-              return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
+-                                      buf, conn);
++              return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
++                                       buf);
+       }
+       cmd = iscsit_find_cmd_from_itt_or_dump(conn, hdr->itt,
+@@ -1325,8 +1299,7 @@ iscsit_check_dataout_hdr(struct iscsi_co
+       if (cmd->data_direction != DMA_TO_DEVICE) {
+               pr_err("Command ITT: 0x%08x received DataOUT for a"
+                       " NON-WRITE command.\n", cmd->init_task_tag);
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
+-                              1, 0, buf, cmd);
++              return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
+       }
+       se_cmd = &cmd->se_cmd;
+       iscsit_mod_dataout_timer(cmd);
+@@ -1335,8 +1308,7 @@ iscsit_check_dataout_hdr(struct iscsi_co
+               pr_err("DataOut Offset: %u, Length %u greater than"
+                       " iSCSI Command EDTL %u, protocol error.\n",
+                       hdr->offset, payload_length, cmd->se_cmd.data_length);
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+-                              1, 0, buf, cmd);
++              return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID, buf);
+       }
+       if (cmd->unsolicited_data) {
+@@ -1557,8 +1529,8 @@ int iscsit_handle_nop_out(struct iscsi_c
+       if (hdr->itt == RESERVED_ITT && !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
+               pr_err("NOPOUT ITT is reserved, but Immediate Bit is"
+                       " not set, protocol error.\n");
+-              return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
+-                                      buf, conn);
++              return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
++                                       (unsigned char *)hdr);
+       }
+       if (payload_length > conn->conn_ops->MaxXmitDataSegmentLength) {
+@@ -1566,8 +1538,8 @@ int iscsit_handle_nop_out(struct iscsi_c
+                       " greater than MaxXmitDataSegmentLength: %u, protocol"
+                       " error.\n", payload_length,
+                       conn->conn_ops->MaxXmitDataSegmentLength);
+-              return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
+-                                      buf, conn);
++              return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR,
++                                       (unsigned char *)hdr);
+       }
+       pr_debug("Got NOPOUT Ping %s ITT: 0x%08x, TTT: 0x%08x,"
+@@ -1584,9 +1556,9 @@ int iscsit_handle_nop_out(struct iscsi_c
+        */
+       if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
+               if (!cmd)
+-                      return iscsit_add_reject(
++                      return iscsit_reject_cmd(cmd,
+                                       ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                                      1, buf, conn);
++                                      (unsigned char *)hdr);
+               cmd->iscsi_opcode       = ISCSI_OP_NOOP_OUT;
+               cmd->i_state            = ISTATE_SEND_NOPIN;
+@@ -1706,9 +1678,7 @@ int iscsit_handle_nop_out(struct iscsi_c
+                       goto ping_out;
+               }
+               if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+-                      return iscsit_add_reject_from_cmd(
+-                                      ISCSI_REASON_PROTOCOL_ERROR,
+-                                      1, 0, buf, cmd);
++                      return -1;
+               return 0;
+       }
+@@ -1782,8 +1752,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_
+               pr_err("Task Management Request TASK_REASSIGN not"
+                       " issued as immediate command, bad iSCSI Initiator"
+                               "implementation\n");
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
+-                                      1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_PROTOCOL_ERROR, buf);
+       }
+       if ((function != ISCSI_TM_FUNC_ABORT_TASK) &&
+           be32_to_cpu(hdr->refcmdsn) != ISCSI_RESERVED_TAG)
+@@ -1795,9 +1765,9 @@ iscsit_handle_task_mgt_cmd(struct iscsi_
+       if (!cmd->tmr_req) {
+               pr_err("Unable to allocate memory for"
+                       " Task Management command!\n");
+-              return iscsit_add_reject_from_cmd(
+-                      ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                      1, 1, buf, cmd);
++              return iscsit_add_reject_cmd(cmd,
++                                           ISCSI_REASON_BOOKMARK_NO_RESOURCES,
++                                           buf);
+       }
+       /*
+@@ -1842,17 +1812,15 @@ iscsit_handle_task_mgt_cmd(struct iscsi_
+               default:
+                       pr_err("Unknown iSCSI TMR Function:"
+                              " 0x%02x\n", function);
+-                      return iscsit_add_reject_from_cmd(
+-                              ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                              1, 1, buf, cmd);
++                      return iscsit_add_reject_cmd(cmd,
++                              ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
+               }
+               ret = core_tmr_alloc_req(&cmd->se_cmd, cmd->tmr_req,
+                                        tcm_function, GFP_KERNEL);
+               if (ret < 0)
+-                      return iscsit_add_reject_from_cmd(
+-                              ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                              1, 1, buf, cmd);
++                      return iscsit_add_reject_cmd(cmd,
++                              ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
+               cmd->tmr_req->se_tmr_req = cmd->se_cmd.se_tmr_req;
+       }
+@@ -1911,9 +1879,8 @@ iscsit_handle_task_mgt_cmd(struct iscsi_
+                       break;
+               if (iscsit_check_task_reassign_expdatasn(tmr_req, conn) < 0)
+-                      return iscsit_add_reject_from_cmd(
+-                                      ISCSI_REASON_BOOKMARK_INVALID, 1, 1,
+-                                      buf, cmd);
++                      return iscsit_add_reject_cmd(cmd,
++                                      ISCSI_REASON_BOOKMARK_INVALID, buf);
+               break;
+       default:
+               pr_err("Unknown TMR function: 0x%02x, protocol"
+@@ -1937,9 +1904,7 @@ attach:
+               else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
+                       return 0;
+               else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+-                      return iscsit_add_reject_from_cmd(
+-                                      ISCSI_REASON_PROTOCOL_ERROR,
+-                                      1, 0, buf, cmd);
++                      return -1;
+       }
+       iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
+@@ -1989,8 +1954,7 @@ static int iscsit_handle_text_cmd(
+               pr_err("Unable to accept text parameter length: %u"
+                       "greater than MaxXmitDataSegmentLength %u.\n",
+                      payload_length, conn->conn_ops->MaxXmitDataSegmentLength);
+-              return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
+-                                      buf, conn);
++              return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR, buf);
+       }
+       pr_debug("Got Text Request: ITT: 0x%08x, CmdSN: 0x%08x,"
+@@ -2092,8 +2056,8 @@ static int iscsit_handle_text_cmd(
+       cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
+       if (!cmd)
+-              return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                                      1, buf, conn);
++              return iscsit_add_reject(conn,
++                                       ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
+       cmd->iscsi_opcode       = ISCSI_OP_TEXT;
+       cmd->i_state            = ISTATE_SEND_TEXTRSP;
+@@ -2113,9 +2077,7 @@ static int iscsit_handle_text_cmd(
+       if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
+               cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
+               if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+-                      return iscsit_add_reject_from_cmd(
+-                                      ISCSI_REASON_PROTOCOL_ERROR,
+-                                      1, 0, buf, cmd);
++                      return -1;
+               return 0;
+       }
+@@ -2301,13 +2263,10 @@ iscsit_handle_logout_cmd(struct iscsi_co
+                       return ret;
+       } else {
+               cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
+-              if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
++              if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
+                       logout_remove = 0;
+-              } else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) {
+-                      return iscsit_add_reject_from_cmd(
+-                              ISCSI_REASON_PROTOCOL_ERROR,
+-                              1, 0, buf, cmd);
+-              }
++              else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
++                      return -1;
+       }
+       return logout_remove;
+@@ -2331,8 +2290,8 @@ static int iscsit_handle_snack(
+       if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
+               pr_err("Initiator sent SNACK request while in"
+                       " ErrorRecoveryLevel=0.\n");
+-              return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
+-                                      buf, conn);
++              return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
++                                       buf);
+       }
+       /*
+        * SNACK_DATA and SNACK_R2T are both 0,  so check which function to
+@@ -2356,13 +2315,13 @@ static int iscsit_handle_snack(
+       case ISCSI_FLAG_SNACK_TYPE_RDATA:
+               /* FIXME: Support R-Data SNACK */
+               pr_err("R-Data SNACK Not Supported.\n");
+-              return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
+-                                      buf, conn);
++              return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
++                                       buf);
+       default:
+               pr_err("Unknown SNACK type 0x%02x, protocol"
+                       " error.\n", hdr->flags & 0x0f);
+-              return iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
+-                                      buf, conn);
++              return iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
++                                       buf);
+       }
+       return 0;
+@@ -2434,14 +2393,14 @@ static int iscsit_handle_immediate_data(
+                               pr_err("Unable to recover from"
+                                       " Immediate Data digest failure while"
+                                       " in ERL=0.\n");
+-                              iscsit_add_reject_from_cmd(
++                              iscsit_reject_cmd(cmd,
+                                               ISCSI_REASON_DATA_DIGEST_ERROR,
+-                                              1, 0, (unsigned char *)hdr, cmd);
++                                              (unsigned char *)hdr);
+                               return IMMEDIATE_DATA_CANNOT_RECOVER;
+                       } else {
+-                              iscsit_add_reject_from_cmd(
++                              iscsit_reject_cmd(cmd,
+                                               ISCSI_REASON_DATA_DIGEST_ERROR,
+-                                              0, 0, (unsigned char *)hdr, cmd);
++                                              (unsigned char *)hdr);
+                               return IMMEDIATE_DATA_ERL1_CRC_FAILURE;
+                       }
+               } else {
+@@ -3541,6 +3500,7 @@ iscsit_build_reject(struct iscsi_cmd *cm
+                   struct iscsi_reject *hdr)
+ {
+       hdr->opcode             = ISCSI_OP_REJECT;
++      hdr->reason             = cmd->reject_reason;
+       hdr->flags              |= ISCSI_FLAG_CMD_FINAL;
+       hton24(hdr->dlength, ISCSI_HDR_LEN);
+       hdr->ffffffff           = cpu_to_be32(0xffffffff);
+@@ -3814,18 +3774,11 @@ check_rsp_state:
+       case ISTATE_SEND_STATUS_RECOVERY:
+       case ISTATE_SEND_TEXTRSP:
+       case ISTATE_SEND_TASKMGTRSP:
++      case ISTATE_SEND_REJECT:
+               spin_lock_bh(&cmd->istate_lock);
+               cmd->i_state = ISTATE_SENT_STATUS;
+               spin_unlock_bh(&cmd->istate_lock);
+               break;
+-      case ISTATE_SEND_REJECT:
+-              if (cmd->cmd_flags & ICF_REJECT_FAIL_CONN) {
+-                      cmd->cmd_flags &= ~ICF_REJECT_FAIL_CONN;
+-                      complete(&cmd->reject_comp);
+-                      goto err;
+-              }
+-              complete(&cmd->reject_comp);
+-              break;
+       default:
+               pr_err("Unknown Opcode: 0x%02x ITT:"
+                      " 0x%08x, i_state: %d on CID: %hu\n",
+@@ -3930,8 +3883,7 @@ static int iscsi_target_rx_opcode(struct
+       case ISCSI_OP_SCSI_CMD:
+               cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
+               if (!cmd)
+-                      return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                                              1, buf, conn);
++                      goto reject;
+               ret = iscsit_handle_scsi_cmd(conn, cmd, buf);
+               break;
+@@ -3943,16 +3895,14 @@ static int iscsi_target_rx_opcode(struct
+               if (hdr->ttt == cpu_to_be32(0xFFFFFFFF)) {
+                       cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
+                       if (!cmd)
+-                              return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                                              1, buf, conn);
++                              goto reject;
+               }
+               ret = iscsit_handle_nop_out(conn, cmd, buf);
+               break;
+       case ISCSI_OP_SCSI_TMFUNC:
+               cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
+               if (!cmd)
+-                      return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                                              1, buf, conn);
++                      goto reject;
+               ret = iscsit_handle_task_mgt_cmd(conn, cmd, buf);
+               break;
+@@ -3962,8 +3912,7 @@ static int iscsi_target_rx_opcode(struct
+       case ISCSI_OP_LOGOUT:
+               cmd = iscsit_allocate_cmd(conn, GFP_KERNEL);
+               if (!cmd)
+-                      return iscsit_add_reject(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                                              1, buf, conn);
++                      goto reject;
+               ret = iscsit_handle_logout_cmd(conn, cmd, buf);
+               if (ret > 0)
+@@ -3995,6 +3944,8 @@ static int iscsi_target_rx_opcode(struct
+       }
+       return ret;
++reject:
++      return iscsit_add_reject(conn, ISCSI_REASON_BOOKMARK_NO_RESOURCES, buf);
+ }
+ int iscsi_target_rx_thread(void *arg)
+@@ -4094,8 +4045,8 @@ restart:
+                   (!(opcode & ISCSI_OP_LOGOUT)))) {
+                       pr_err("Received illegal iSCSI Opcode: 0x%02x"
+                       " while in Discovery Session, rejecting.\n", opcode);
+-                      iscsit_add_reject(ISCSI_REASON_PROTOCOL_ERROR, 1,
+-                                      buffer, conn);
++                      iscsit_add_reject(conn, ISCSI_REASON_PROTOCOL_ERROR,
++                                        buffer);
+                       goto transport_err;
+               }
+--- a/drivers/target/iscsi/iscsi_target.h
++++ b/drivers/target/iscsi/iscsi_target.h
+@@ -15,7 +15,7 @@ extern struct iscsi_np *iscsit_add_np(st
+ extern int iscsit_reset_np_thread(struct iscsi_np *, struct iscsi_tpg_np *,
+                               struct iscsi_portal_group *);
+ extern int iscsit_del_np(struct iscsi_np *);
+-extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *, struct iscsi_cmd *);
++extern int iscsit_reject_cmd(struct iscsi_cmd *cmd, u8, unsigned char *);
+ extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *);
+ extern int iscsit_logout_closesession(struct iscsi_cmd *, struct iscsi_conn *);
+ extern int iscsit_logout_closeconnection(struct iscsi_cmd *, struct iscsi_conn *);
+--- a/drivers/target/iscsi/iscsi_target_core.h
++++ b/drivers/target/iscsi/iscsi_target_core.h
+@@ -132,7 +132,6 @@ enum cmd_flags_table {
+       ICF_CONTIG_MEMORY                       = 0x00000020,
+       ICF_ATTACHED_TO_RQUEUE                  = 0x00000040,
+       ICF_OOO_CMDSN                           = 0x00000080,
+-      ICF_REJECT_FAIL_CONN                    = 0x00000100,
+ };
+ /* struct iscsi_cmd->i_state */
+@@ -366,6 +365,8 @@ struct iscsi_cmd {
+       u8                      maxcmdsn_inc;
+       /* Immediate Unsolicited Dataout */
+       u8                      unsolicited_data;
++      /* Reject reason code */
++      u8                      reject_reason;
+       /* CID contained in logout PDU when opcode == ISCSI_INIT_LOGOUT_CMND */
+       u16                     logout_cid;
+       /* Command flags */
+@@ -446,7 +447,6 @@ struct iscsi_cmd {
+       struct list_head        datain_list;
+       /* R2T List */
+       struct list_head        cmd_r2t_list;
+-      struct completion       reject_comp;
+       /* Timer for DataOUT */
+       struct timer_list       dataout_timer;
+       /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */
+--- a/drivers/target/iscsi/iscsi_target_erl0.c
++++ b/drivers/target/iscsi/iscsi_target_erl0.c
+@@ -746,13 +746,12 @@ int iscsit_check_post_dataout(
+               if (!conn->sess->sess_ops->ErrorRecoveryLevel) {
+                       pr_err("Unable to recover from DataOUT CRC"
+                               " failure while ERL=0, closing session.\n");
+-                      iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR,
+-                                      1, 0, buf, cmd);
++                      iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR,
++                                        buf);
+                       return DATAOUT_CANNOT_RECOVER;
+               }
+-              iscsit_add_reject_from_cmd(ISCSI_REASON_DATA_DIGEST_ERROR,
+-                              0, 0, buf, cmd);
++              iscsit_reject_cmd(cmd, ISCSI_REASON_DATA_DIGEST_ERROR, buf);
+               return iscsit_dataout_post_crc_failed(cmd, buf);
+       }
+ }
+--- a/drivers/target/iscsi/iscsi_target_erl1.c
++++ b/drivers/target/iscsi/iscsi_target_erl1.c
+@@ -162,9 +162,8 @@ static int iscsit_handle_r2t_snack(
+                       " protocol error.\n", cmd->init_task_tag, begrun,
+                       (begrun + runlength), cmd->acked_data_sn);
+-                      return iscsit_add_reject_from_cmd(
+-                                      ISCSI_REASON_PROTOCOL_ERROR,
+-                                      1, 0, buf, cmd);
++                      return iscsit_reject_cmd(cmd,
++                                      ISCSI_REASON_PROTOCOL_ERROR, buf);
+       }
+       if (runlength) {
+@@ -173,8 +172,8 @@ static int iscsit_handle_r2t_snack(
+                       " with BegRun: 0x%08x, RunLength: 0x%08x, exceeds"
+                       " current R2TSN: 0x%08x, protocol error.\n",
+                       cmd->init_task_tag, begrun, runlength, cmd->r2t_sn);
+-                      return iscsit_add_reject_from_cmd(
+-                              ISCSI_REASON_BOOKMARK_INVALID, 1, 0, buf, cmd);
++                      return iscsit_reject_cmd(cmd,
++                                      ISCSI_REASON_BOOKMARK_INVALID, buf);
+               }
+               last_r2tsn = (begrun + runlength);
+       } else
+@@ -433,8 +432,7 @@ static int iscsit_handle_recovery_datain
+                       " protocol error.\n", cmd->init_task_tag, begrun,
+                       (begrun + runlength), cmd->acked_data_sn);
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_PROTOCOL_ERROR,
+-                              1, 0, buf, cmd);
++              return iscsit_reject_cmd(cmd, ISCSI_REASON_PROTOCOL_ERROR, buf);
+       }
+       /*
+@@ -445,14 +443,14 @@ static int iscsit_handle_recovery_datain
+               pr_err("Initiator requesting BegRun: 0x%08x, RunLength"
+                       ": 0x%08x greater than maximum DataSN: 0x%08x.\n",
+                               begrun, runlength, (cmd->data_sn - 1));
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_INVALID,
+-                              1, 0, buf, cmd);
++              return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_INVALID,
++                                       buf);
+       }
+       dr = iscsit_allocate_datain_req();
+       if (!dr)
+-              return iscsit_add_reject_from_cmd(ISCSI_REASON_BOOKMARK_NO_RESOURCES,
+-                              1, 0, buf, cmd);
++              return iscsit_reject_cmd(cmd, ISCSI_REASON_BOOKMARK_NO_RESOURCES,
++                                       buf);
+       dr->data_sn = dr->begrun = begrun;
+       dr->runlength = runlength;
+--- a/drivers/target/iscsi/iscsi_target_util.c
++++ b/drivers/target/iscsi/iscsi_target_util.c
+@@ -178,7 +178,6 @@ struct iscsi_cmd *iscsit_allocate_cmd(st
+       INIT_LIST_HEAD(&cmd->i_conn_node);
+       INIT_LIST_HEAD(&cmd->datain_list);
+       INIT_LIST_HEAD(&cmd->cmd_r2t_list);
+-      init_completion(&cmd->reject_comp);
+       spin_lock_init(&cmd->datain_lock);
+       spin_lock_init(&cmd->dataout_timeout_lock);
+       spin_lock_init(&cmd->istate_lock);
+--- a/include/target/iscsi/iscsi_transport.h
++++ b/include/target/iscsi/iscsi_transport.h
+@@ -34,8 +34,6 @@ extern void iscsit_put_transport(struct
+ /*
+  * From iscsi_target.c
+  */
+-extern int iscsit_add_reject_from_cmd(u8, int, int, unsigned char *,
+-                              struct iscsi_cmd *);
+ extern int iscsit_setup_scsi_cmd(struct iscsi_conn *, struct iscsi_cmd *,
+                               unsigned char *);
+ extern void iscsit_set_unsoliticed_dataout(struct iscsi_cmd *);
diff --git a/queue-3.10/iscsi-target-fix-iscsit_sequence_cmd-reject-handling-for-iser.patch b/queue-3.10/iscsi-target-fix-iscsit_sequence_cmd-reject-handling-for-iser.patch
new file mode 100644 (file)
index 0000000..349ffac
--- /dev/null
@@ -0,0 +1,283 @@
+From nab@linux-iscsi.org  Fri Aug  2 06:54:36 2013
+From: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
+Date: Tue, 30 Jul 2013 04:04:02 +0000
+Subject: iscsi-target: Fix iscsit_sequence_cmd reject handling for iser
+To: target-devel <target-devel@vger.kernel.org>
+Cc: Greg-KH <gregkh@linuxfoundation.org>, Stable <stable@vger.kernel.org>, Nicholas Bellinger <nab@linux-iscsi.org>, Or Gerlitz <ogerlitz@mellanox.com>, Mike Christie <michaelc@cs.wisc.edu>
+Message-ID: <1375157042-25935-3-git-send-email-nab@linux-iscsi.org>
+
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 561bf15892375597ee59d473a704a3e634c4f311 upstream
+
+This patch moves ISCSI_OP_REJECT failures into iscsit_sequence_cmd()
+in order to avoid external iscsit_reject_cmd() reject usage for all
+PDU types.
+
+It also updates PDU specific handlers for traditional iscsi-target
+code to not reset the session after posting a ISCSI_OP_REJECT during
+setup.
+
+(v2: Fix CMDSN_LOWER_THAN_EXP for ISCSI_OP_SCSI to call
+     target_put_sess_cmd() after iscsit_sequence_cmd() failure)
+
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Cc: Or Gerlitz <ogerlitz@mellanox.com>
+Cc: Mike Christie <michaelc@cs.wisc.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/ulp/isert/ib_isert.c  |    2 -
+ drivers/target/iscsi/iscsi_target.c      |   50 +++++++++++++++++++------------
+ drivers/target/iscsi/iscsi_target_erl1.c |    6 +--
+ drivers/target/iscsi/iscsi_target_util.c |   26 ++++++++++++----
+ drivers/target/iscsi/iscsi_target_util.h |    3 +
+ include/target/iscsi/iscsi_transport.h   |    3 +
+ 6 files changed, 60 insertions(+), 30 deletions(-)
+
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -952,7 +952,7 @@ isert_handle_scsi_cmd(struct isert_conn
+       }
+ sequence_cmd:
+-      rc = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
++      rc = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
+       if (!rc && dump_payload == false && unsol_data)
+               iscsit_set_unsoliticed_dataout(cmd);
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -1052,11 +1052,11 @@ int iscsit_process_scsi_cmd(struct iscsi
+        * be acknowledged. (See below)
+        */
+       if (!cmd->immediate_data) {
+-              cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
+-              if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
+-                      if (!cmd->sense_reason)
+-                              return 0;
+-
++              cmdsn_ret = iscsit_sequence_cmd(conn, cmd,
++                                      (unsigned char *)hdr, hdr->cmdsn);
++              if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
++                      return -1;
++              else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
+                       target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
+                       return 0;
+               }
+@@ -1083,6 +1083,9 @@ int iscsit_process_scsi_cmd(struct iscsi
+        * iscsit_check_received_cmdsn() in iscsit_get_immediate_data() below.
+        */
+       if (cmd->sense_reason) {
++              if (cmd->reject_reason)
++                      return 0;
++
+               target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
+               return 1;
+       }
+@@ -1091,10 +1094,8 @@ int iscsit_process_scsi_cmd(struct iscsi
+        * the backend memory allocation.
+        */
+       cmd->sense_reason = transport_generic_new_cmd(&cmd->se_cmd);
+-      if (cmd->sense_reason) {
+-              target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
++      if (cmd->sense_reason)
+               return 1;
+-      }
+       return 0;
+ }
+@@ -1104,6 +1105,7 @@ static int
+ iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
+                         bool dump_payload)
+ {
++      struct iscsi_conn *conn = cmd->conn;
+       int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
+       /*
+        * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes.
+@@ -1120,12 +1122,22 @@ after_immediate_data:
+                * DataCRC, check against ExpCmdSN/MaxCmdSN if
+                * Immediate Bit is not set.
+                */
+-              cmdsn_ret = iscsit_sequence_cmd(cmd->conn, cmd, hdr->cmdsn);
++              cmdsn_ret = iscsit_sequence_cmd(cmd->conn, cmd,
++                                      (unsigned char *)hdr, hdr->cmdsn);
++              if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER) {
++                      return -1;
++              } else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
++                      target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
++                      return 0;
++              }
+               if (cmd->sense_reason) {
+-                      if (iscsit_dump_data_payload(cmd->conn,
+-                                      cmd->first_burst_len, 1) < 0)
+-                              return -1;
++                      int rc;
++
++                      rc = iscsit_dump_data_payload(cmd->conn,
++                                                    cmd->first_burst_len, 1);
++                      target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
++                      return rc;
+               } else if (cmd->unsolicited_data)
+                       iscsit_set_unsoliticed_dataout(cmd);
+@@ -1159,7 +1171,7 @@ iscsit_handle_scsi_cmd(struct iscsi_conn
+       rc = iscsit_setup_scsi_cmd(conn, cmd, buf);
+       if (rc < 0)
+-              return rc;
++              return 0;
+       /*
+        * Allocation iovecs needed for struct socket operations for
+        * traditional iSCSI block I/O.
+@@ -1500,7 +1512,7 @@ static int iscsit_handle_data_out(struct
+       rc = iscsit_check_dataout_hdr(conn, buf, &cmd);
+       if (rc < 0)
+-              return rc;
++              return 0;
+       else if (!cmd)
+               return 0;
+@@ -1672,7 +1684,8 @@ int iscsit_handle_nop_out(struct iscsi_c
+                       return 0;
+               }
+-              cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
++              cmdsn_ret = iscsit_sequence_cmd(conn, cmd,
++                              (unsigned char *)hdr, hdr->cmdsn);
+               if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
+                       ret = 0;
+                       goto ping_out;
+@@ -1898,7 +1911,7 @@ attach:
+       spin_unlock_bh(&conn->cmd_lock);
+       if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
+-              int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
++              int cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
+               if (cmdsn_ret == CMDSN_HIGHER_THAN_EXP)
+                       out_of_order_cmdsn = 1;
+               else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
+@@ -2075,7 +2088,8 @@ static int iscsit_handle_text_cmd(
+       iscsit_ack_from_expstatsn(conn, be32_to_cpu(hdr->exp_statsn));
+       if (!(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
+-              cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
++              cmdsn_ret = iscsit_sequence_cmd(conn, cmd,
++                              (unsigned char *)hdr, hdr->cmdsn);
+               if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+                       return -1;
+@@ -2262,7 +2276,7 @@ iscsit_handle_logout_cmd(struct iscsi_co
+               if (ret < 0)
+                       return ret;
+       } else {
+-              cmdsn_ret = iscsit_sequence_cmd(conn, cmd, hdr->cmdsn);
++              cmdsn_ret = iscsit_sequence_cmd(conn, cmd, buf, hdr->cmdsn);
+               if (cmdsn_ret == CMDSN_LOWER_THAN_EXP)
+                       logout_remove = 0;
+               else if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+--- a/drivers/target/iscsi/iscsi_target_erl1.c
++++ b/drivers/target/iscsi/iscsi_target_erl1.c
+@@ -1088,7 +1088,7 @@ int iscsit_handle_ooo_cmdsn(
+       ooo_cmdsn = iscsit_allocate_ooo_cmdsn();
+       if (!ooo_cmdsn)
+-              return CMDSN_ERROR_CANNOT_RECOVER;
++              return -ENOMEM;
+       ooo_cmdsn->cmd                  = cmd;
+       ooo_cmdsn->batch_count          = (batch) ?
+@@ -1099,10 +1099,10 @@ int iscsit_handle_ooo_cmdsn(
+       if (iscsit_attach_ooo_cmdsn(sess, ooo_cmdsn) < 0) {
+               kmem_cache_free(lio_ooo_cache, ooo_cmdsn);
+-              return CMDSN_ERROR_CANNOT_RECOVER;
++              return -ENOMEM;
+       }
+-      return CMDSN_HIGHER_THAN_EXP;
++      return 0;
+ }
+ static int iscsit_set_dataout_timeout_values(
+--- a/drivers/target/iscsi/iscsi_target_util.c
++++ b/drivers/target/iscsi/iscsi_target_util.c
+@@ -283,13 +283,12 @@ static inline int iscsit_check_received_
+  * Commands may be received out of order if MC/S is in use.
+  * Ensure they are executed in CmdSN order.
+  */
+-int iscsit_sequence_cmd(
+-      struct iscsi_conn *conn,
+-      struct iscsi_cmd *cmd,
+-      __be32 cmdsn)
++int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
++                      unsigned char *buf, __be32 cmdsn)
+ {
+-      int ret;
+-      int cmdsn_ret;
++      int ret, cmdsn_ret;
++      bool reject = false;
++      u8 reason = ISCSI_REASON_BOOKMARK_NO_RESOURCES;
+       mutex_lock(&conn->sess->cmdsn_mutex);
+@@ -299,9 +298,19 @@ int iscsit_sequence_cmd(
+               ret = iscsit_execute_cmd(cmd, 0);
+               if ((ret >= 0) && !list_empty(&conn->sess->sess_ooo_cmdsn_list))
+                       iscsit_execute_ooo_cmdsns(conn->sess);
++              else if (ret < 0) {
++                      reject = true;
++                      ret = CMDSN_ERROR_CANNOT_RECOVER;
++              }
+               break;
+       case CMDSN_HIGHER_THAN_EXP:
+               ret = iscsit_handle_ooo_cmdsn(conn->sess, cmd, be32_to_cpu(cmdsn));
++              if (ret < 0) {
++                      reject = true;
++                      ret = CMDSN_ERROR_CANNOT_RECOVER;
++                      break;
++              }
++              ret = CMDSN_HIGHER_THAN_EXP;
+               break;
+       case CMDSN_LOWER_THAN_EXP:
+               cmd->i_state = ISTATE_REMOVE;
+@@ -309,11 +318,16 @@ int iscsit_sequence_cmd(
+               ret = cmdsn_ret;
+               break;
+       default:
++              reason = ISCSI_REASON_PROTOCOL_ERROR;
++              reject = true;
+               ret = cmdsn_ret;
+               break;
+       }
+       mutex_unlock(&conn->sess->cmdsn_mutex);
++      if (reject)
++              iscsit_reject_cmd(cmd, reason, buf);
++
+       return ret;
+ }
+ EXPORT_SYMBOL(iscsit_sequence_cmd);
+--- a/drivers/target/iscsi/iscsi_target_util.h
++++ b/drivers/target/iscsi/iscsi_target_util.h
+@@ -13,7 +13,8 @@ extern struct iscsi_cmd *iscsit_allocate
+ extern struct iscsi_seq *iscsit_get_seq_holder_for_datain(struct iscsi_cmd *, u32);
+ extern struct iscsi_seq *iscsit_get_seq_holder_for_r2t(struct iscsi_cmd *);
+ extern struct iscsi_r2t *iscsit_get_holder_for_r2tsn(struct iscsi_cmd *, u32);
+-int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd, __be32 cmdsn);
++extern int iscsit_sequence_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
++                             unsigned char * ,__be32 cmdsn);
+ extern int iscsit_check_unsolicited_dataout(struct iscsi_cmd *, unsigned char *);
+ extern struct iscsi_cmd *iscsit_find_cmd_from_itt(struct iscsi_conn *, itt_t);
+ extern struct iscsi_cmd *iscsit_find_cmd_from_itt_or_dump(struct iscsi_conn *,
+--- a/include/target/iscsi/iscsi_transport.h
++++ b/include/target/iscsi/iscsi_transport.h
+@@ -82,4 +82,5 @@ extern int iscsit_tmr_post_handler(struc
+  * From iscsi_target_util.c
+  */
+ extern struct iscsi_cmd *iscsit_allocate_cmd(struct iscsi_conn *, gfp_t);
+-extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *, __be32);
++extern int iscsit_sequence_cmd(struct iscsi_conn *, struct iscsi_cmd *,
++                             unsigned char *, __be32);
diff --git a/queue-3.10/perf-tools-revert-regression-in-configuration-of-python-support.patch b/queue-3.10/perf-tools-revert-regression-in-configuration-of-python-support.patch
new file mode 100644 (file)
index 0000000..d3f13a7
--- /dev/null
@@ -0,0 +1,71 @@
+From a363a9da65d253fa7354ce5fd630f4f94df934cc Mon Sep 17 00:00:00 2001
+From: Michael Witten <mfwitten@gmail.com>
+Date: Wed, 17 Apr 2013 02:23:16 +0000
+Subject: perf tools: Revert regression in configuration of Python support
+
+From: Michael Witten <mfwitten@gmail.com>
+
+commit a363a9da65d253fa7354ce5fd630f4f94df934cc upstream.
+
+Among other things, the following:
+
+  commit 31160d7feab786c991780d7f0ce2755a469e0e5e
+  Date:   Tue Jan 8 16:22:36 2013 -0500
+  perf tools: Fix GNU make v3.80 compatibility issue
+
+attempts to aid the user by tapping into an existing error message,
+as described in the commit message:
+
+  ... Also fix an issue where _get_attempt was called with only
+  one argument. This prevented the error message from printing
+  the name of the variable that can be used to fix the problem.
+
+or more precisely:
+
+  -$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
+  +$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2),$(1)))
+
+However, The "missing" argument was in fact missing on purpose; it's
+absence is a signal that the error message should be skipped, because
+the failure would be due to the default value, not any user-supplied
+value.  This can be seen in how `_ge_attempt' uses `gea_err' (in the
+config/utilities.mak file):
+
+  _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2)))
+  _gea_warn = $(warning The path '$(1)' is not executable.)
+  _gea_err  = $(if $(1),$(error Please set '$(1)' appropriately))
+
+That is, because the argument is no longer missing, the value `$(1)'
+(associated with `_gea_err') always evaluates to true, thus always
+triggering the error condition that is meant to be reserved for
+only the case when a user explicitly supplies an invalid value.
+
+Concretely, the result is a regression in the Makefile's configuration
+of python support; rather than gracefully disable support when the
+relevant executables cannot be found according to default values, the
+build process halts in error as though the user explicitly supplied
+the values.
+
+This new commit simply reverts the offending one-line change.
+
+Reported-by: Pekka Enberg <penberg@kernel.org>
+Link: http://lkml.kernel.org/r/CAOJsxLHv17Ys3M7P5q25imkUxQW6LE_vABxh1N3Tt7Mv6Ho4iw@mail.gmail.com
+Signed-off-by: Michael Witten <mfwitten@gmail.com>
+Cc: Mark Brown <broonie@sirena.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/config/utilities.mak |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/tools/perf/config/utilities.mak
++++ b/tools/perf/config/utilities.mak
+@@ -173,7 +173,7 @@ _ge-abspath = $(if $(is-executable),$(1)
+ # Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
+ #
+ define get-executable-or-default
+-$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2),$(1)))
++$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
+ endef
+ _ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2)))
+ _gea_warn = $(warning The path '$(1)' is not executable.)
diff --git a/queue-3.10/radeon-kms-do-not-flush-uninitialized-hotplug-work.patch b/queue-3.10/radeon-kms-do-not-flush-uninitialized-hotplug-work.patch
new file mode 100644 (file)
index 0000000..e88e9bf
--- /dev/null
@@ -0,0 +1,112 @@
+From a01c34f72e7cd2624570818f579b5ab464f93de2 Mon Sep 17 00:00:00 2001
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Date: Sun, 14 Jul 2013 14:03:27 +0300
+Subject: radeon kms: do not flush uninitialized hotplug work
+
+From: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+
+commit a01c34f72e7cd2624570818f579b5ab464f93de2 upstream.
+
+Fix a warning from lockdep caused by calling flush_work() for
+uninitialized hotplug work. Initialize hotplug_work, audio_work
+and reset_work upon successful radeon_irq_kms_init() completion
+and thus perform hotplug flush_work only when rdev->irq.installed
+is true.
+
+[    4.790019] [drm] Loading CEDAR Microcode
+[    4.790943] r600_cp: Failed to load firmware "radeon/CEDAR_smc.bin"
+[    4.791152] [drm:evergreen_startup] *ERROR* Failed to load firmware!
+[    4.791330] radeon 0000:01:00.0: disabling GPU acceleration
+
+[    4.792633] INFO: trying to register non-static key.
+[    4.792792] the code is fine but needs lockdep annotation.
+[    4.792953] turning off the locking correctness validator.
+
+[    4.793114] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 3.11.0-rc0-dbg-10676-gfe56456-dirty #1816
+[    4.793314] Hardware name: Acer             Aspire 5741G    /Aspire 5741G    , BIOS V1.20 02/08/2011
+[    4.793507]  ffffffff821fd810 ffff8801530b9a18 ffffffff8160434e 0000000000000002
+[    4.794155]  ffff8801530b9ad8 ffffffff810b8404 ffff8801530b0798 ffff8801530b0000
+[    4.794789]  ffff8801530b9b00 0000000000000046 00000000000004c0 ffffffff00000000
+[    4.795418] Call Trace:
+[    4.795573]  [<ffffffff8160434e>] dump_stack+0x4e/0x82
+[    4.795731]  [<ffffffff810b8404>] __lock_acquire+0x1a64/0x1d30
+[    4.795893]  [<ffffffff814a87f0>] ? dev_vprintk_emit+0x50/0x60
+[    4.796034]  [<ffffffff810b8fb4>] lock_acquire+0xa4/0x200
+[    4.796216]  [<ffffffff8106cd75>] ? flush_work+0x5/0x280
+[    4.796375]  [<ffffffff8106cdad>] flush_work+0x3d/0x280
+[    4.796520]  [<ffffffff8106cd75>] ? flush_work+0x5/0x280
+[    4.796682]  [<ffffffff810b659d>] ? trace_hardirqs_on_caller+0xfd/0x1c0
+[    4.796862]  [<ffffffff8131d775>] ? delay_tsc+0x95/0xf0
+[    4.797024]  [<ffffffff8141bb8b>] radeon_irq_kms_fini+0x2b/0x70
+[    4.797186]  [<ffffffff814557c9>] evergreen_init+0x2a9/0x2e0
+[    4.797347]  [<ffffffff813ebb1f>] radeon_device_init+0x5ef/0x700
+[    4.797511]  [<ffffffff81335bc7>] ? pci_find_capability+0x47/0x50
+[    4.797672]  [<ffffffff813edaed>] radeon_driver_load_kms+0x8d/0x150
+[    4.797843]  [<ffffffff813ce426>] drm_get_pci_dev+0x166/0x280
+[    4.798007]  [<ffffffff8116cff5>] ? kfree+0xf5/0x2e0
+[    4.798168]  [<ffffffff813ea298>] ? radeon_pci_probe+0x98/0xd0
+[    4.798329]  [<ffffffff813ea2aa>] radeon_pci_probe+0xaa/0xd0
+[    4.798489]  [<ffffffff81339404>] pci_device_probe+0x84/0xe0
+[    4.798644]  [<ffffffff814ac7d6>] driver_probe_device+0x76/0x240
+[    4.798805]  [<ffffffff814aca73>] __driver_attach+0x93/0xa0
+[    4.798948]  [<ffffffff814ac9e0>] ? __device_attach+0x40/0x40
+[    4.799126]  [<ffffffff814aa82b>] bus_for_each_dev+0x6b/0xb0
+[    4.799272]  [<ffffffff814ac2be>] driver_attach+0x1e/0x20
+[    4.799434]  [<ffffffff814abec0>] bus_add_driver+0x1f0/0x280
+[    4.799596]  [<ffffffff814ad0e4>] driver_register+0x74/0x150
+[    4.799758]  [<ffffffff8133923d>] __pci_register_driver+0x5d/0x60
+[    4.799936]  [<ffffffff81d16efc>] ? ttm_init+0x67/0x67
+[    4.800081]  [<ffffffff813ce655>] drm_pci_init+0x115/0x130
+[    4.800243]  [<ffffffff81d16efc>] ? ttm_init+0x67/0x67
+[    4.800405]  [<ffffffff81d16f98>] radeon_init+0x9c/0xba
+[    4.800586]  [<ffffffff810002ca>] do_one_initcall+0xfa/0x150
+[    4.800746]  [<ffffffff81073f60>] ? parse_args+0x120/0x330
+[    4.800909]  [<ffffffff81cdafae>] kernel_init_freeable+0x111/0x191
+[    4.801052]  [<ffffffff81cda87a>] ? do_early_param+0x88/0x88
+[    4.801233]  [<ffffffff815fb670>] ? rest_init+0x140/0x140
+[    4.801393]  [<ffffffff815fb67e>] kernel_init+0xe/0x180
+[    4.801556]  [<ffffffff8160dcac>] ret_from_fork+0x7c/0xb0
+[    4.801718]  [<ffffffff815fb670>] ? rest_init+0x140/0x140
+
+Signed-off-by: Sergey Senozhatsky <sergey.senozhatsky@gmail.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+
+ drivers/gpu/drm/radeon/radeon_irq_kms.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/radeon/radeon_irq_kms.c
++++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c
+@@ -241,9 +241,6 @@ int radeon_irq_kms_init(struct radeon_de
+ {
+       int r = 0;
+-      INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
+-      INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
+-
+       spin_lock_init(&rdev->irq.lock);
+       r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
+       if (r) {
+@@ -265,6 +262,10 @@ int radeon_irq_kms_init(struct radeon_de
+               rdev->irq.installed = false;
+               return r;
+       }
++
++      INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
++      INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
++
+       DRM_INFO("radeon: irq initialized.\n");
+       return 0;
+ }
+@@ -284,8 +285,8 @@ void radeon_irq_kms_fini(struct radeon_d
+               rdev->irq.installed = false;
+               if (rdev->msi_enabled)
+                       pci_disable_msi(rdev->pdev);
++              flush_work(&rdev->hotplug_work);
+       }
+-      flush_work(&rdev->hotplug_work);
+ }
+ /**
index 9a63ce5b4141576481169f4f560771522f1a444c..a06d2178762ccaf750f6dfe9e5e02b26cacec01b 100644 (file)
@@ -90,3 +90,8 @@ usb-gadget-udc-core-fix-the-typo-of-udc-state-attribute.patch
 mm-mempolicy-fix-mbind_range-vma_adjust-interaction.patch
 tty_port-fix-refcounting-leak-in-tty_port_tty_hangup.patch
 livelock-avoidance-in-sget.patch
+xen-evtchn-avoid-a-deadlock-when-unbinding-an-event-channel.patch
+radeon-kms-do-not-flush-uninitialized-hotplug-work.patch
+iscsi-target-fix-iscsit_add_reject-usage-for-iser.patch
+iscsi-target-fix-iscsit_sequence_cmd-reject-handling-for-iser.patch
+perf-tools-revert-regression-in-configuration-of-python-support.patch
diff --git a/queue-3.10/xen-evtchn-avoid-a-deadlock-when-unbinding-an-event-channel.patch b/queue-3.10/xen-evtchn-avoid-a-deadlock-when-unbinding-an-event-channel.patch
new file mode 100644 (file)
index 0000000..effc3cd
--- /dev/null
@@ -0,0 +1,103 @@
+From 179fbd5a45f0d4034cc6fd37b8d367a3b79663c4 Mon Sep 17 00:00:00 2001
+From: David Vrabel <david.vrabel@citrix.com>
+Date: Fri, 19 Jul 2013 15:51:58 +0100
+Subject: xen/evtchn: avoid a deadlock when unbinding an event channel
+
+From: David Vrabel <david.vrabel@citrix.com>
+
+commit 179fbd5a45f0d4034cc6fd37b8d367a3b79663c4 upstream.
+
+Unbinding an event channel (either with the ioctl or when the evtchn
+device is closed) may deadlock because disable_irq() is called with
+port_user_lock held which is also locked by the interrupt handler.
+
+Think of the IOCTL_EVTCHN_UNBIND is being serviced, the routine has
+just taken the lock, and an interrupt happens. The evtchn_interrupt
+is invoked, tries to take the lock and spins forever.
+
+A quick glance at the code shows that the spinlock is a local IRQ
+variant. Unfortunately that does not help as "disable_irq() waits for
+the interrupt handler on all CPUs to stop running.  If the irq occurs
+on another VCPU, it tries to take port_user_lock and can't because
+the unbind ioctl is holding it." (from David). Hence we cannot
+depend on the said spinlock to protect us. We could make it a system
+wide IRQ disable spinlock but there is a better way.
+
+We can piggyback on the fact that the existence of the spinlock is
+to make get_port_user() checks be up-to-date. And we can alter those
+checks to not depend on the spin lock (as it's protected by u->bind_mutex
+in the ioctl) and can remove the unnecessary locking (this is
+IOCTL_EVTCHN_UNBIND) path.
+
+In the interrupt handler we cannot use the mutex, but we do not
+need it.
+
+"The unbind disables the irq before making the port user stale, so when
+you clear it you are guaranteed that the interrupt handler that might
+use that port cannot be running." (from David).
+
+Hence this patch removes the spinlock usage on the teardown path
+and piggybacks on disable_irq happening before we muck with the
+get_port_user() data. This ensures that the interrupt handler will
+never run on stale data.
+
+Signed-off-by: David Vrabel <david.vrabel@citrix.com>
+Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+[v1: Expanded the commit description a bit]
+Signed-off-by: Jonghwan Choi <jhbird.choi@samsung.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/xen/evtchn.c |   21 ++-------------------
+ 1 file changed, 2 insertions(+), 19 deletions(-)
+
+--- a/drivers/xen/evtchn.c
++++ b/drivers/xen/evtchn.c
+@@ -377,18 +377,12 @@ static long evtchn_ioctl(struct file *fi
+               if (unbind.port >= NR_EVENT_CHANNELS)
+                       break;
+-              spin_lock_irq(&port_user_lock);
+-
+               rc = -ENOTCONN;
+-              if (get_port_user(unbind.port) != u) {
+-                      spin_unlock_irq(&port_user_lock);
++              if (get_port_user(unbind.port) != u)
+                       break;
+-              }
+               disable_irq(irq_from_evtchn(unbind.port));
+-              spin_unlock_irq(&port_user_lock);
+-
+               evtchn_unbind_from_user(u, unbind.port);
+               rc = 0;
+@@ -488,26 +482,15 @@ static int evtchn_release(struct inode *
+       int i;
+       struct per_user_data *u = filp->private_data;
+-      spin_lock_irq(&port_user_lock);
+-
+-      free_page((unsigned long)u->ring);
+-
+       for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+               if (get_port_user(i) != u)
+                       continue;
+               disable_irq(irq_from_evtchn(i));
+-      }
+-
+-      spin_unlock_irq(&port_user_lock);
+-
+-      for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+-              if (get_port_user(i) != u)
+-                      continue;
+-
+               evtchn_unbind_from_user(get_port_user(i), i);
+       }
++      free_page((unsigned long)u->ring);
+       kfree(u->name);
+       kfree(u);