diff options
author | Mike Christie <michael.christie@oracle.com> | 2022-06-16 17:45:55 -0500 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2022-06-21 21:19:23 -0400 |
commit | e1c6a7ec14290a0e371b09300685638f9009f2ab (patch) | |
tree | 7e931b60b90e714a2b630a816b1fa720f2724024 /drivers/scsi/libiscsi_tcp.c | |
parent | 533ac412fdb4cbc8ce282b1ee1991e03b2717625 (diff) | |
download | linux-stable-e1c6a7ec14290a0e371b09300685638f9009f2ab.tar.gz linux-stable-e1c6a7ec14290a0e371b09300685638f9009f2ab.tar.bz2 linux-stable-e1c6a7ec14290a0e371b09300685638f9009f2ab.zip |
scsi: iscsi: Remove iscsi_get_task back_lock requirement
We currently require that the back_lock is held when calling the functions
that manipulate the iscsi_task refcount. The only reason for this is to
handle races where we are handling SCSI-ml EH callbacks and the cmd is
completing at the same time the normal completion path is running, and we
can't return from the EH callback until the driver has stopped accessing
the cmd. Holding the back_lock while also accessing the task->state made it
simple to check that a cmd is completing and also get/put a refcount at the
same time, and at the time we were not as concerned about performance.
The problem is that we don't want to take the back_lock from the xmit path
for normal I/O since it causes contention with the completion path if the
user has chosen to try and split those paths on different CPUs (in this
case abusing the CPUs and ignoring caching improves perf for some uses).
Begins to remove the back_lock requirement for iscsi_get/put_task by
removing the requirement for the get path. Instead of always holding the
back_lock we detect if something has done the last put and is about to call
iscsi_free_task(). A subsequent commit will then allow iSCSI code to do the
last put on a task and only grab the back_lock if the refcount is now zero
and it's going to call iscsi_free_task().
Link: https://lore.kernel.org/r/20220616224557.115234-8-michael.christie@oracle.com
Reviewed-by: Lee Duncan <lduncan@suse.com>
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/libiscsi_tcp.c')
-rw-r--r-- | drivers/scsi/libiscsi_tcp.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index 883005757ddb..c182aa83f2c9 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -558,7 +558,11 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) return 0; } task->last_xfer = jiffies; - __iscsi_get_task(task); + if (!iscsi_get_task(task)) { + spin_unlock(&session->back_lock); + /* Let the path that got the early rsp complete it */ + return 0; + } tcp_conn = conn->dd_data; rhdr = (struct iscsi_r2t_rsp *)tcp_conn->in.hdr; |