From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org,
Mike Christie <michael.christie@oracle.com>,
Lee Duncan <lduncan@suse.com>,
"Martin K. Petersen" <martin.petersen@oracle.com>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 4.4 10/24] scsi: libiscsi: Fix NOP race condition
Date: Tue, 1 Dec 2020 09:53:16 +0100 [thread overview]
Message-ID: <20201201084638.260744766@linuxfoundation.org> (raw)
In-Reply-To: <20201201084637.754785180@linuxfoundation.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 b4fbcf4cade8f..36e415487fe53 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -570,8 +570,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);
@@ -780,6 +780,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;
@@ -987,8 +990,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;
@@ -1003,11 +1009,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;
}
@@ -1020,7 +1027,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.
@@ -1960,7 +1967,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;
@@ -2095,7 +2102,7 @@ static 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 c7b1dc713cdd7..9c7f4aad6db66 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -144,6 +144,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
next prev parent reply other threads:[~2020-12-01 8:54 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-01 8:53 [PATCH 4.4 00/24] 4.4.247-rc1 review Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 01/24] btrfs: tree-checker: Enhance chunk checker to validate chunk profile Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 02/24] btrfs: inode: Verify inode mode to avoid NULL pointer dereference Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 03/24] KVM: x86: Fix split-irqchip vs interrupt injection window request Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 04/24] HID: cypress: Support Varmilo Keyboards media hotkeys Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 05/24] Input: i8042 - allow insmod to succeed on devices without an i8042 controller Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 06/24] HID: hid-sensor-hub: Fix issue with devices with no report ID Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 07/24] x86/xen: dont unbind uninitialized lock_kicker_irq Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 08/24] proc: dont allow async path resolution of /proc/self components Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 09/24] dmaengine: pl330: _prep_dma_memcpy: Fix wrong burst size Greg Kroah-Hartman
2020-12-01 8:53 ` Greg Kroah-Hartman [this message]
2020-12-01 8:53 ` [PATCH 4.4 11/24] scsi: target: iscsi: Fix cmd abort fabric stop race Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 12/24] scsi: ufs: Fix race between shutdown and runtime resume flow Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 13/24] bnxt_en: fix error return code in bnxt_init_board() Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 14/24] video: hyperv_fb: Fix the cache type when mapping the VRAM Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 15/24] bnxt_en: Release PCI regions when DMA mask setup fails during probe Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 16/24] IB/mthca: fix return value of error branch in mthca_init_cq() Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 17/24] nfc: s3fwrn5: use signed integer for parsing GPIO numbers Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 18/24] efivarfs: revert "fix memory leak in efivarfs_create()" Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 19/24] perf probe: Fix to die_entrypc() returns error correctly Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 20/24] USB: core: Change %pK for __user pointers to %px Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 21/24] x86/speculation: Fix prctl() when spectre_v2_user={seccomp,prctl},ibpb Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 22/24] USB: core: add endpoint-blacklist quirk Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 23/24] USB: core: Fix regression in Hercules audio card Greg Kroah-Hartman
2020-12-01 8:53 ` [PATCH 4.4 24/24] btrfs: fix lockdep splat when reading qgroup config on mount Greg Kroah-Hartman
2020-12-01 13:41 ` [PATCH 4.4 00/24] 4.4.247-rc1 review Jon Hunter
2020-12-01 15:59 ` Pavel Machek
2020-12-01 21:38 ` Guenter Roeck
2020-12-02 6:17 ` Naresh Kamboju
2020-12-02 17:04 ` Shuah Khan
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=20201201084638.260744766@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=lduncan@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=michael.christie@oracle.com \
--cc=sashal@kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.