linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Lee Duncan <lduncan@suse.com>,
	Mike Christie <michael.christie@oracle.com>,
	"Martin K . Petersen" <martin.petersen@oracle.com>,
	Sasha Levin <sashal@kernel.org>,
	open-iscsi@googlegroups.com, linux-scsi@vger.kernel.org
Subject: [PATCH AUTOSEL 5.9 26/33] scsi: libiscsi: Fix NOP race condition
Date: Wed, 25 Nov 2020 10:35:43 -0500	[thread overview]
Message-ID: <20201125153550.810101-26-sashal@kernel.org> (raw)
In-Reply-To: <20201125153550.810101-1-sashal@kernel.org>

From: Lee Duncan <lduncan@suse.com>

[ Upstream commit fe0a8a95e7134d0b44cd407bc0085b9ba8d8fe31 ]

iSCSI NOPs are sometimes "lost", mistakenly sent to the user-land iscsid
daemon instead of handled in the kernel, as they should be, resulting in a
message from the daemon like:

  iscsid: Got nop in, but kernel supports nop handling.

This can occur because of the new forward- and back-locks, and the fact
that an iSCSI NOP response can occur before processing of the NOP send is
complete. This can result in "conn->ping_task" being NULL in
iscsi_nop_out_rsp(), when the pointer is actually in the process of being
set.

To work around this, we add a new state to the "ping_task" pointer. In
addition to NULL (not assigned) and a pointer (assigned), we add the state
"being set", which is signaled with an INVALID pointer (using "-1").

Link: https://lore.kernel.org/r/20201106193317.16993-1-leeman.duncan@gmail.com
Reviewed-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Lee Duncan <lduncan@suse.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/scsi/libiscsi.c | 23 +++++++++++++++--------
 include/scsi/libiscsi.h |  3 +++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 1e9c3171fa9f4..f9314f1393fbd 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -533,8 +533,8 @@ static void iscsi_complete_task(struct iscsi_task *task, int state)
 	if (conn->task == task)
 		conn->task = NULL;
 
-	if (conn->ping_task == task)
-		conn->ping_task = NULL;
+	if (READ_ONCE(conn->ping_task) == task)
+		WRITE_ONCE(conn->ping_task, NULL);
 
 	/* release get from queueing */
 	__iscsi_put_task(task);
@@ -738,6 +738,9 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
 						   task->conn->session->age);
 	}
 
+	if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK))
+		WRITE_ONCE(conn->ping_task, task);
+
 	if (!ihost->workq) {
 		if (iscsi_prep_mgmt_task(conn, task))
 			goto free_task;
@@ -941,8 +944,11 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
         struct iscsi_nopout hdr;
 	struct iscsi_task *task;
 
-	if (!rhdr && conn->ping_task)
-		return -EINVAL;
+	if (!rhdr) {
+		if (READ_ONCE(conn->ping_task))
+			return -EINVAL;
+		WRITE_ONCE(conn->ping_task, INVALID_SCSI_TASK);
+	}
 
 	memset(&hdr, 0, sizeof(struct iscsi_nopout));
 	hdr.opcode = ISCSI_OP_NOOP_OUT | ISCSI_OP_IMMEDIATE;
@@ -957,11 +963,12 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
 
 	task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
 	if (!task) {
+		if (!rhdr)
+			WRITE_ONCE(conn->ping_task, NULL);
 		iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
 		return -EIO;
 	} else if (!rhdr) {
 		/* only track our nops */
-		conn->ping_task = task;
 		conn->last_ping = jiffies;
 	}
 
@@ -984,7 +991,7 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task,
 	struct iscsi_conn *conn = task->conn;
 	int rc = 0;
 
-	if (conn->ping_task != task) {
+	if (READ_ONCE(conn->ping_task) != task) {
 		/*
 		 * If this is not in response to one of our
 		 * nops then it must be from userspace.
@@ -1923,7 +1930,7 @@ static void iscsi_start_tx(struct iscsi_conn *conn)
  */
 static int iscsi_has_ping_timed_out(struct iscsi_conn *conn)
 {
-	if (conn->ping_task &&
+	if (READ_ONCE(conn->ping_task) &&
 	    time_before_eq(conn->last_recv + (conn->recv_timeout * HZ) +
 			   (conn->ping_timeout * HZ), jiffies))
 		return 1;
@@ -2058,7 +2065,7 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
 	 * Checking the transport already or nop from a cmd timeout still
 	 * running
 	 */
-	if (conn->ping_task) {
+	if (READ_ONCE(conn->ping_task)) {
 		task->have_checked_conn = true;
 		rc = BLK_EH_RESET_TIMER;
 		goto done;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index c25fb86ffae95..b3bbd10eb3f07 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -132,6 +132,9 @@ struct iscsi_task {
 	void			*dd_data;	/* driver/transport data */
 };
 
+/* invalid scsi_task pointer */
+#define	INVALID_SCSI_TASK	(struct iscsi_task *)-1l
+
 static inline int iscsi_task_has_unsol_data(struct iscsi_task *task)
 {
 	return task->unsol_r2t.data_length > task->unsol_r2t.sent;
-- 
2.27.0


  parent reply	other threads:[~2020-11-25 15:36 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-25 15:35 [PATCH AUTOSEL 5.9 01/33] HID: uclogic: Add ID for Trust Flex Design Tablet Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 02/33] HID: ite: Replace ABS_MISC 120/121 events with touchpad on/off keypresses Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 03/33] HID: cypress: Support Varmilo Keyboards' media hotkeys Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 04/33] HID: add support for Sega Saturn Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 05/33] Input: i8042 - allow insmod to succeed on devices without an i8042 controller Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 06/33] HID: hid-sensor-hub: Fix issue with devices with no report ID Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 07/33] staging: ralink-gdma: fix kconfig dependency bug for DMA_RALINK Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 08/33] HID: add HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE for Gamevice devices Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 09/33] dmaengine: xilinx_dma: use readl_poll_timeout_atomic variant Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 10/33] x86/xen: don't unbind uninitialized lock_kicker_irq Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 11/33] kunit: fix display of failed expectations for strings Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 12/33] HID: logitech-hidpp: Add HIDPP_CONSUMER_VENDOR_KEYS quirk for the Dinovo Edge Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 13/33] HID: Add Logitech Dinovo Edge battery quirk Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 14/33] proc: don't allow async path resolution of /proc/self components Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 15/33] nvme: free sq/cq dbbuf pointers when dbbuf set fails Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 16/33] io_uring: handle -EOPNOTSUPP on path resolution Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 17/33] net: stmmac: dwmac_lib: enlarge dma reset timeout Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 18/33] vdpasim: fix "mac_pton" undefined error Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 19/33] vhost: add helper to check if a vq has been setup Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 20/33] vhost scsi: alloc cmds per vq instead of session Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 21/33] vhost scsi: fix cmd completion race Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 22/33] vhost scsi: add lun parser helper Sasha Levin
2020-11-25 17:48   ` Paolo Bonzini
2020-11-25 18:01     ` Sasha Levin
2020-11-25 18:08       ` Paolo Bonzini
2020-11-29  4:13         ` Sasha Levin
2020-11-29 17:34           ` Paolo Bonzini
2020-11-29 21:06             ` Sasha Levin
2020-11-30  8:33               ` Paolo Bonzini
2020-11-30 13:28                 ` Greg KH
2020-11-30 13:52                   ` Paolo Bonzini
2020-11-30 13:57                     ` Greg KH
2020-11-30 14:00                       ` Paolo Bonzini
2020-11-30 17:34                         ` Sasha Levin
2020-11-30 17:38                 ` Sasha Levin
2020-11-30 17:52                   ` Paolo Bonzini
2020-11-30 19:44                     ` Mike Christie
2020-11-30 20:29                       ` Paolo Bonzini
2020-11-30 23:59                         ` Sasha Levin
2020-12-04  8:27                           ` Paolo Bonzini
2020-12-04 15:49                             ` Sasha Levin
2020-12-04 16:12                               ` Joe Perches
2020-12-04 17:08                               ` Paolo Bonzini
2020-12-05 20:59                                 ` Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 23/33] vhost scsi: Add support for LUN resets Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 24/33] cpuidle: tegra: Annotate tegra_pm_set_cpu_in_lp2() with RCU_NONIDLE Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 25/33] dmaengine: pl330: _prep_dma_memcpy: Fix wrong burst size Sasha Levin
2020-11-25 15:35 ` Sasha Levin [this message]
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 27/33] scsi: target: iscsi: Fix cmd abort fabric stop race Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 28/33] lockdep: Put graph lock/unlock under lock_recursion protection Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 29/33] perf/x86: fix sysfs type mismatches Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 30/33] xtensa: uaccess: Add missing __user to strncpy_from_user() prototype Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 31/33] x86/dumpstack: Do not try to access user space code of other tasks Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 32/33] net: dsa: mv88e6xxx: Wait for EEPROM done after HW reset Sasha Levin
2020-11-25 15:35 ` [PATCH AUTOSEL 5.9 33/33] xfs: don't allow NOWAIT DIO across extent boundaries Sasha Levin
2020-11-25 21:52   ` Dave Chinner
2020-11-25 23:46     ` Sasha Levin
2020-11-26  7:13       ` Dave Chinner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201125153550.810101-26-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=lduncan@suse.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=michael.christie@oracle.com \
    --cc=open-iscsi@googlegroups.com \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).