From: Mike Christie <michael.christie@oracle.com>
To: lduncan@suse.com, cleech@redhat.com, njavali@marvell.com,
mrangankar@marvell.com, GR-QLogic-Storage-Upstream@marvell.com,
varun@chelsio.com, martin.petersen@oracle.com,
linux-scsi@vger.kernel.org, jejb@linux.ibm.com
Subject: [PATCH 22/22] libiscsi: fix conn_send_pdu API
Date: Thu, 17 Dec 2020 00:42:12 -0600 [thread overview]
Message-ID: <1608187332-4434-23-git-send-email-michael.christie@oracle.com> (raw)
In-Reply-To: <1608187332-4434-1-git-send-email-michael.christie@oracle.com>
The conn_send_pdu API is evil in that it returns a pointer to a
iscsi_task, but that task might have been freed already so you can't
touch it. This patch splits the task allocation and transmission, so
functions like iscsi_send_nopout can access the task before its sent.
We then can remove that INVALID_SCSI_TASK dance.
Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
drivers/scsi/libiscsi.c | 68 ++++++++++++++++++++++++++++++++++---------------
include/scsi/libiscsi.h | 3 ---
2 files changed, 48 insertions(+), 23 deletions(-)
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 6516900..b902043 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -696,11 +696,10 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
}
static struct iscsi_task *
-__iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+iscsi_alloc_mgmt_task(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
char *data, uint32_t data_size)
{
struct iscsi_session *session = conn->session;
- struct iscsi_host *ihost = shost_priv(session->host);
uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK;
struct iscsi_task *task;
itt_t itt;
@@ -784,25 +783,50 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
task->conn->session->age);
}
- if (unlikely(READ_ONCE(conn->ping_task) == INVALID_SCSI_TASK))
- WRITE_ONCE(conn->ping_task, task);
+ return task;
+
+free_task:
+ iscsi_put_task(task);
+ return NULL;
+}
+
+static int iscsi_send_mgmt_task(struct iscsi_task *task)
+{
+ struct iscsi_conn *conn = task->conn;
+ struct iscsi_session *session = conn->session;
+ struct iscsi_host *ihost = shost_priv(conn->session->host);
+ int rc = 0;
if (!ihost->workq) {
- if (iscsi_prep_mgmt_task(conn, task))
- goto free_task;
+ rc = iscsi_prep_mgmt_task(conn, task);
+ if (rc)
+ return rc;
- if (session->tt->xmit_task(task))
- goto free_task;
+ rc = session->tt->xmit_task(task);
+ if (rc)
+ return rc;
} else {
list_add_tail(&task->running, &conn->mgmtqueue);
iscsi_conn_queue_work(conn);
}
- return task;
+ return 0;
+}
-free_task:
- iscsi_put_task(task);
- return NULL;
+static int __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
+ char *data, uint32_t data_size)
+{
+ struct iscsi_task *task;
+ int rc;
+
+ task = iscsi_alloc_mgmt_task(conn, hdr, data, data_size);
+ if (!task)
+ return -ENOMEM;
+
+ rc = iscsi_send_mgmt_task(task);
+ if (rc)
+ iscsi_put_task(task);
+ return rc;
}
int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
@@ -813,7 +837,7 @@ int iscsi_conn_send_pdu(struct iscsi_cls_conn *cls_conn, struct iscsi_hdr *hdr,
int err = 0;
spin_lock_bh(&session->frwd_lock);
- if (!__iscsi_conn_send_pdu(conn, hdr, data, data_size))
+ if (__iscsi_conn_send_pdu(conn, hdr, data, data_size))
err = -EPERM;
spin_unlock_bh(&session->frwd_lock);
return err;
@@ -988,7 +1012,6 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
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));
@@ -1002,10 +1025,18 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr)
} else
hdr.ttt = RESERVED_ITT;
- task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
- if (!task) {
+ task = iscsi_alloc_mgmt_task(conn, (struct iscsi_hdr *)&hdr, NULL, 0);
+ if (!task)
+ return -ENOMEM;
+
+ if (!rhdr)
+ WRITE_ONCE(conn->ping_task, task);
+
+ if (iscsi_send_mgmt_task(task)) {
if (!rhdr)
WRITE_ONCE(conn->ping_task, NULL);
+ iscsi_put_task(task);
+
iscsi_conn_printk(KERN_ERR, conn, "Could not send nopout\n");
return -EIO;
} else if (!rhdr) {
@@ -1840,11 +1871,8 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn,
__must_hold(&session->frwd_lock)
{
struct iscsi_session *session = conn->session;
- struct iscsi_task *task;
- task = __iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr,
- NULL, 0);
- if (!task) {
+ if (__iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0)) {
spin_unlock_bh(&session->frwd_lock);
iscsi_conn_printk(KERN_ERR, conn, "Could not send TMF.\n");
iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED);
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 3fa7d90..2bc9bf5 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -142,9 +142,6 @@ 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;
--
1.8.3.1
prev parent reply other threads:[~2020-12-17 6:45 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-17 6:41 [RFC PATCH 00/22 V3] iscsi: lock clean ups Mike Christie
2020-12-17 6:41 ` [PATCH 01/22] libiscsi: fix iscsi_prep_scsi_cmd_pdu error handling Mike Christie
2020-12-17 6:41 ` [PATCH 02/22] libiscsi: drop taskqueuelock Mike Christie
2020-12-17 6:41 ` [PATCH 03/22] libiscsi: fix iscsi_task use after free Mike Christie
2020-12-17 6:41 ` [PATCH 04/22] qla4xxx: use iscsi_is_session_online Mike Christie
2020-12-17 6:41 ` [PATCH 05/22] iscsi class: drop session lock in iscsi_session_chkready Mike Christie
2020-12-17 6:41 ` [PATCH 06/22] libiscsi: remove queued_cmdsn Mike Christie
2020-12-17 6:41 ` [PATCH 07/22] libiscsi: drop frwd lock for session state Mike Christie
2020-12-17 6:41 ` [PATCH 08/22] libiscsi: add task prealloc/free callouts Mike Christie
2020-12-17 6:41 ` [PATCH 09/22] qedi: implement alloc_task_priv/free_task_priv Mike Christie
2020-12-17 6:42 ` [PATCH 10/22] bnx2i: " Mike Christie
2020-12-17 6:42 ` [PATCH 11/22] iser, be2iscsi, qla4xxx: set scsi_host_template cmd_size Mike Christie
2020-12-17 6:42 ` [PATCH 12/22] bnx2i: " Mike Christie
2020-12-17 6:42 ` [PATCH 13/22] qedi: " Mike Christie
2020-12-17 6:42 ` [PATCH 14/22] iscsi_tcp, libcxgbi: " Mike Christie
2020-12-17 6:42 ` [PATCH 15/22] libiscsi: use scsi_host_busy_iter Mike Christie
2020-12-17 6:42 ` [PATCH 16/22] be2iscsi: " Mike Christie
2020-12-17 6:42 ` [PATCH 17/22] bnx2i: prep driver for switch to blk tags Mike Christie
2020-12-17 6:42 ` [PATCH 18/22] qedi: " Mike Christie
2020-12-17 6:42 ` [PATCH 19/22] libiscsi: use blk/scsi-ml mq cmd pre-allocator Mike Christie
2020-12-17 6:42 ` [PATCH 20/22] libiscsi: rm iscsi_put_task back_lock requirement Mike Christie
2020-12-17 6:42 ` [PATCH 21/22] libiscsi: drop back_lock from xmit path Mike Christie
2020-12-17 6:42 ` Mike Christie [this message]
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=1608187332-4434-23-git-send-email-michael.christie@oracle.com \
--to=michael.christie@oracle.com \
--cc=GR-QLogic-Storage-Upstream@marvell.com \
--cc=cleech@redhat.com \
--cc=jejb@linux.ibm.com \
--cc=lduncan@suse.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=mrangankar@marvell.com \
--cc=njavali@marvell.com \
--cc=varun@chelsio.com \
/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).