* [PATCH AUTOSEL 5.1 019/375] blk-mq: split blk_mq_alloc_and_init_hctx into two parts
[not found] <20190522192115.22666-1-sashal@kernel.org>
@ 2019-05-22 19:15 ` Sasha Levin
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 020/375] blk-mq: grab .q_usage_counter when queuing request from plug code path Sasha Levin
` (5 subsequent siblings)
6 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2019-05-22 19:15 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Ming Lei, Dongli Zhang, James Smart, Bart Van Assche, linux-scsi,
Martin K . Petersen, Christoph Hellwig, James E . J . Bottomley,
Hannes Reinecke, Jens Axboe, Sasha Levin, linux-block
From: Ming Lei <ming.lei@redhat.com>
[ Upstream commit 7c6c5b7c9186e3fb5b10afb8e5f710ae661144c6 ]
Split blk_mq_alloc_and_init_hctx into two parts, and one is
blk_mq_alloc_hctx() for allocating all hctx resources, another
is blk_mq_init_hctx() for initializing hctx, which serves as
counter-part of blk_mq_exit_hctx().
Cc: Dongli Zhang <dongli.zhang@oracle.com>
Cc: James Smart <james.smart@broadcom.com>
Cc: Bart Van Assche <bart.vanassche@wdc.com>
Cc: linux-scsi@vger.kernel.org
Cc: Martin K . Petersen <martin.petersen@oracle.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: James E . J . Bottomley <jejb@linux.vnet.ibm.com>
Reviewed-by: Hannes Reinecke <hare@suse.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Tested-by: James Smart <james.smart@broadcom.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/blk-mq.c | 139 ++++++++++++++++++++++++++-----------------------
1 file changed, 75 insertions(+), 64 deletions(-)
diff --git a/block/blk-mq.c b/block/blk-mq.c
index fc60ed7e940ea..24e3ae3bd710e 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2289,15 +2289,65 @@ static void blk_mq_exit_hw_queues(struct request_queue *q,
}
}
+static int blk_mq_hw_ctx_size(struct blk_mq_tag_set *tag_set)
+{
+ int hw_ctx_size = sizeof(struct blk_mq_hw_ctx);
+
+ BUILD_BUG_ON(ALIGN(offsetof(struct blk_mq_hw_ctx, srcu),
+ __alignof__(struct blk_mq_hw_ctx)) !=
+ sizeof(struct blk_mq_hw_ctx));
+
+ if (tag_set->flags & BLK_MQ_F_BLOCKING)
+ hw_ctx_size += sizeof(struct srcu_struct);
+
+ return hw_ctx_size;
+}
+
static int blk_mq_init_hctx(struct request_queue *q,
struct blk_mq_tag_set *set,
struct blk_mq_hw_ctx *hctx, unsigned hctx_idx)
{
- int node;
+ hctx->queue_num = hctx_idx;
+
+ cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead);
+
+ hctx->tags = set->tags[hctx_idx];
+
+ if (set->ops->init_hctx &&
+ set->ops->init_hctx(hctx, set->driver_data, hctx_idx))
+ goto unregister_cpu_notifier;
- node = hctx->numa_node;
+ if (blk_mq_init_request(set, hctx->fq->flush_rq, hctx_idx,
+ hctx->numa_node))
+ goto exit_hctx;
+ return 0;
+
+ exit_hctx:
+ if (set->ops->exit_hctx)
+ set->ops->exit_hctx(hctx, hctx_idx);
+ unregister_cpu_notifier:
+ blk_mq_remove_cpuhp(hctx);
+ return -1;
+}
+
+static struct blk_mq_hw_ctx *
+blk_mq_alloc_hctx(struct request_queue *q, struct blk_mq_tag_set *set,
+ int node)
+{
+ struct blk_mq_hw_ctx *hctx;
+ gfp_t gfp = GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY;
+
+ hctx = kzalloc_node(blk_mq_hw_ctx_size(set), gfp, node);
+ if (!hctx)
+ goto fail_alloc_hctx;
+
+ if (!zalloc_cpumask_var_node(&hctx->cpumask, gfp, node))
+ goto free_hctx;
+
+ atomic_set(&hctx->nr_active, 0);
if (node == NUMA_NO_NODE)
- node = hctx->numa_node = set->numa_node;
+ node = set->numa_node;
+ hctx->numa_node = node;
INIT_DELAYED_WORK(&hctx->run_work, blk_mq_run_work_fn);
spin_lock_init(&hctx->lock);
@@ -2305,58 +2355,45 @@ static int blk_mq_init_hctx(struct request_queue *q,
hctx->queue = q;
hctx->flags = set->flags & ~BLK_MQ_F_TAG_SHARED;
- cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead);
-
- hctx->tags = set->tags[hctx_idx];
-
/*
* Allocate space for all possible cpus to avoid allocation at
* runtime
*/
hctx->ctxs = kmalloc_array_node(nr_cpu_ids, sizeof(void *),
- GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, node);
+ gfp, node);
if (!hctx->ctxs)
- goto unregister_cpu_notifier;
+ goto free_cpumask;
if (sbitmap_init_node(&hctx->ctx_map, nr_cpu_ids, ilog2(8),
- GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, node))
+ gfp, node))
goto free_ctxs;
-
hctx->nr_ctx = 0;
spin_lock_init(&hctx->dispatch_wait_lock);
init_waitqueue_func_entry(&hctx->dispatch_wait, blk_mq_dispatch_wake);
INIT_LIST_HEAD(&hctx->dispatch_wait.entry);
- if (set->ops->init_hctx &&
- set->ops->init_hctx(hctx, set->driver_data, hctx_idx))
- goto free_bitmap;
-
hctx->fq = blk_alloc_flush_queue(q, hctx->numa_node, set->cmd_size,
- GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY);
+ gfp);
if (!hctx->fq)
- goto exit_hctx;
-
- if (blk_mq_init_request(set, hctx->fq->flush_rq, hctx_idx, node))
- goto free_fq;
+ goto free_bitmap;
if (hctx->flags & BLK_MQ_F_BLOCKING)
init_srcu_struct(hctx->srcu);
+ blk_mq_hctx_kobj_init(hctx);
- return 0;
+ return hctx;
- free_fq:
- blk_free_flush_queue(hctx->fq);
- exit_hctx:
- if (set->ops->exit_hctx)
- set->ops->exit_hctx(hctx, hctx_idx);
free_bitmap:
sbitmap_free(&hctx->ctx_map);
free_ctxs:
kfree(hctx->ctxs);
- unregister_cpu_notifier:
- blk_mq_remove_cpuhp(hctx);
- return -1;
+ free_cpumask:
+ free_cpumask_var(hctx->cpumask);
+ free_hctx:
+ kfree(hctx);
+ fail_alloc_hctx:
+ return NULL;
}
static void blk_mq_init_cpu_queues(struct request_queue *q,
@@ -2700,51 +2737,25 @@ struct request_queue *blk_mq_init_sq_queue(struct blk_mq_tag_set *set,
}
EXPORT_SYMBOL(blk_mq_init_sq_queue);
-static int blk_mq_hw_ctx_size(struct blk_mq_tag_set *tag_set)
-{
- int hw_ctx_size = sizeof(struct blk_mq_hw_ctx);
-
- BUILD_BUG_ON(ALIGN(offsetof(struct blk_mq_hw_ctx, srcu),
- __alignof__(struct blk_mq_hw_ctx)) !=
- sizeof(struct blk_mq_hw_ctx));
-
- if (tag_set->flags & BLK_MQ_F_BLOCKING)
- hw_ctx_size += sizeof(struct srcu_struct);
-
- return hw_ctx_size;
-}
-
static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
struct blk_mq_tag_set *set, struct request_queue *q,
int hctx_idx, int node)
{
struct blk_mq_hw_ctx *hctx;
- hctx = kzalloc_node(blk_mq_hw_ctx_size(set),
- GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY,
- node);
+ hctx = blk_mq_alloc_hctx(q, set, node);
if (!hctx)
- return NULL;
-
- if (!zalloc_cpumask_var_node(&hctx->cpumask,
- GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY,
- node)) {
- kfree(hctx);
- return NULL;
- }
-
- atomic_set(&hctx->nr_active, 0);
- hctx->numa_node = node;
- hctx->queue_num = hctx_idx;
+ goto fail;
- if (blk_mq_init_hctx(q, set, hctx, hctx_idx)) {
- free_cpumask_var(hctx->cpumask);
- kfree(hctx);
- return NULL;
- }
- blk_mq_hctx_kobj_init(hctx);
+ if (blk_mq_init_hctx(q, set, hctx, hctx_idx))
+ goto free_hctx;
return hctx;
+
+ free_hctx:
+ kobject_put(&hctx->kobj);
+ fail:
+ return NULL;
}
static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH AUTOSEL 5.1 020/375] blk-mq: grab .q_usage_counter when queuing request from plug code path
[not found] <20190522192115.22666-1-sashal@kernel.org>
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 019/375] blk-mq: split blk_mq_alloc_and_init_hctx into two parts Sasha Levin
@ 2019-05-22 19:15 ` Sasha Levin
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 051/375] scsi: qla2xxx: Fix a qla24xx_enable_msix() error path Sasha Levin
` (4 subsequent siblings)
6 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2019-05-22 19:15 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Ming Lei, Dongli Zhang, James Smart, linux-scsi,
Martin K . Petersen, Christoph Hellwig, James E . J . Bottomley,
Bart Van Assche, Jens Axboe, Sasha Levin, linux-block
From: Ming Lei <ming.lei@redhat.com>
[ Upstream commit e87eb301bee183d82bb3d04bd71b6660889a2588 ]
Just like aio/io_uring, we need to grab 2 refcount for queuing one
request, one is for submission, another is for completion.
If the request isn't queued from plug code path, the refcount grabbed
in generic_make_request() serves for submission. In theroy, this
refcount should have been released after the sumission(async run queue)
is done. blk_freeze_queue() works with blk_sync_queue() together
for avoiding race between cleanup queue and IO submission, given async
run queue activities are canceled because hctx->run_work is scheduled with
the refcount held, so it is fine to not hold the refcount when
running the run queue work function for dispatch IO.
However, if request is staggered into plug list, and finally queued
from plug code path, the refcount in submission side is actually missed.
And we may start to run queue after queue is removed because the queue's
kobject refcount isn't guaranteed to be grabbed in flushing plug list
context, then kernel oops is triggered, see the following race:
blk_mq_flush_plug_list():
blk_mq_sched_insert_requests()
insert requests to sw queue or scheduler queue
blk_mq_run_hw_queue
Because of concurrent run queue, all requests inserted above may be
completed before calling the above blk_mq_run_hw_queue. Then queue can
be freed during the above blk_mq_run_hw_queue().
Fixes the issue by grab .q_usage_counter before calling
blk_mq_sched_insert_requests() in blk_mq_flush_plug_list(). This way is
safe because the queue is absolutely alive before inserting request.
Cc: Dongli Zhang <dongli.zhang@oracle.com>
Cc: James Smart <james.smart@broadcom.com>
Cc: linux-scsi@vger.kernel.org,
Cc: Martin K . Petersen <martin.petersen@oracle.com>,
Cc: Christoph Hellwig <hch@lst.de>,
Cc: James E . J . Bottomley <jejb@linux.vnet.ibm.com>,
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Tested-by: James Smart <james.smart@broadcom.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/blk-mq-sched.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c
index aa6bc5c026438..c59babca6857a 100644
--- a/block/blk-mq-sched.c
+++ b/block/blk-mq-sched.c
@@ -413,6 +413,14 @@ void blk_mq_sched_insert_requests(struct blk_mq_hw_ctx *hctx,
struct list_head *list, bool run_queue_async)
{
struct elevator_queue *e;
+ struct request_queue *q = hctx->queue;
+
+ /*
+ * blk_mq_sched_insert_requests() is called from flush plug
+ * context only, and hold one usage counter to prevent queue
+ * from being released.
+ */
+ percpu_ref_get(&q->q_usage_counter);
e = hctx->queue->elevator;
if (e && e->type->ops.insert_requests)
@@ -426,12 +434,14 @@ void blk_mq_sched_insert_requests(struct blk_mq_hw_ctx *hctx,
if (!hctx->dispatch_busy && !e && !run_queue_async) {
blk_mq_try_issue_list_directly(hctx, list);
if (list_empty(list))
- return;
+ goto out;
}
blk_mq_insert_requests(hctx, ctx, list);
}
blk_mq_run_hw_queue(hctx, run_queue_async);
+ out:
+ percpu_ref_put(&q->q_usage_counter);
}
static void blk_mq_sched_free_tags(struct blk_mq_tag_set *set,
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH AUTOSEL 5.1 051/375] scsi: qla2xxx: Fix a qla24xx_enable_msix() error path
[not found] <20190522192115.22666-1-sashal@kernel.org>
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 019/375] blk-mq: split blk_mq_alloc_and_init_hctx into two parts Sasha Levin
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 020/375] blk-mq: grab .q_usage_counter when queuing request from plug code path Sasha Levin
@ 2019-05-22 19:15 ` Sasha Levin
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 052/375] scsi: qla2xxx: Fix abort handling in tcm_qla2xxx_write_pending() Sasha Levin
` (3 subsequent siblings)
6 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2019-05-22 19:15 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Bart Van Assche, Himanshu Madhani, Giridhar Malavali,
Martin K . Petersen, Sasha Levin, linux-scsi
From: Bart Van Assche <bvanassche@acm.org>
[ Upstream commit 24afabdbd0b3553963a2bbf465895492b14d1107 ]
Make sure that the allocated interrupts are freed if allocating memory for
the msix_entries array fails.
Cc: Himanshu Madhani <hmadhani@marvell.com>
Cc: Giridhar Malavali <gmalavali@marvell.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Acked-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_isr.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index 69bbea9239cc8..add17843148dd 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -3475,7 +3475,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
ql_log(ql_log_fatal, vha, 0x00c8,
"Failed to allocate memory for ha->msix_entries.\n");
ret = -ENOMEM;
- goto msix_out;
+ goto free_irqs;
}
ha->flags.msix_enabled = 1;
@@ -3558,6 +3558,10 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
msix_out:
return ret;
+
+free_irqs:
+ pci_free_irq_vectors(ha->pdev);
+ goto msix_out;
}
int
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH AUTOSEL 5.1 052/375] scsi: qla2xxx: Fix abort handling in tcm_qla2xxx_write_pending()
[not found] <20190522192115.22666-1-sashal@kernel.org>
` (2 preceding siblings ...)
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 051/375] scsi: qla2xxx: Fix a qla24xx_enable_msix() error path Sasha Levin
@ 2019-05-22 19:15 ` Sasha Levin
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 053/375] scsi: qla2xxx: Avoid that lockdep complains about unsafe locking in tcm_qla2xxx_close_session() Sasha Levin
` (2 subsequent siblings)
6 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2019-05-22 19:15 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Bart Van Assche, Himanshu Madhani, Giridhar Malavali,
Martin K . Petersen, Sasha Levin, linux-scsi
From: Bart Van Assche <bvanassche@acm.org>
[ Upstream commit e209783d66bca04b5fce4429e59338517ffc1a0b ]
Implementations of the .write_pending() callback functions must guarantee
that an appropriate LIO core callback function will be called immediately or
at a later time. Make sure that this guarantee is met for aborted SCSI
commands.
[mkp: typo]
Cc: Himanshu Madhani <hmadhani@marvell.com>
Cc: Giridhar Malavali <gmalavali@marvell.com>
Fixes: 694833ee00c4 ("scsi: tcm_qla2xxx: Do not allow aborted cmd to advance.") # v4.13.
Fixes: a07100e00ac4 ("qla2xxx: Fix TMR ABORT interaction issue between qla2xxx and TCM") # v4.5.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Acked-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/tcm_qla2xxx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index 8a3075d17c63c..bddb573c88dd2 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -399,6 +399,8 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd)
cmd->se_cmd.transport_state,
cmd->se_cmd.t_state,
cmd->se_cmd.se_cmd_flags);
+ transport_generic_request_failure(&cmd->se_cmd,
+ TCM_CHECK_CONDITION_ABORT_CMD);
return 0;
}
cmd->trc_flags |= TRC_XFR_RDY;
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH AUTOSEL 5.1 053/375] scsi: qla2xxx: Avoid that lockdep complains about unsafe locking in tcm_qla2xxx_close_session()
[not found] <20190522192115.22666-1-sashal@kernel.org>
` (3 preceding siblings ...)
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 052/375] scsi: qla2xxx: Fix abort handling in tcm_qla2xxx_write_pending() Sasha Levin
@ 2019-05-22 19:15 ` Sasha Levin
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 054/375] scsi: qla2xxx: Fix hardirq-unsafe locking Sasha Levin
2019-05-22 19:16 ` [PATCH AUTOSEL 5.1 063/375] scsi: qedi: Abort ep termination if offload not scheduled Sasha Levin
6 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2019-05-22 19:15 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Bart Van Assche, Himanshu Madhani, Giridhar Malavali,
Martin K . Petersen, Sasha Levin, linux-scsi
From: Bart Van Assche <bvanassche@acm.org>
[ Upstream commit d4023db71108375e4194e92730ba0d32d7f07813 ]
This patch avoids that lockdep reports the following warning:
=====================================================
WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected
5.1.0-rc1-dbg+ #11 Tainted: G W
-----------------------------------------------------
rmdir/1478 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
00000000e7ac4607 (&(&k->k_lock)->rlock){+.+.}, at: klist_next+0x43/0x1d0
and this task is already holding:
00000000cf0baf5e (&(&ha->tgt.sess_lock)->rlock){-...}, at: tcm_qla2xxx_close_session+0x57/0xb0 [tcm_qla2xxx]
which would create a new lock dependency:
(&(&ha->tgt.sess_lock)->rlock){-...} -> (&(&k->k_lock)->rlock){+.+.}
but this new dependency connects a HARDIRQ-irq-safe lock:
(&(&ha->tgt.sess_lock)->rlock){-...}
... which became HARDIRQ-irq-safe at:
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
qla2x00_fcport_event_handler+0x1f3d/0x22b0 [qla2xxx]
qla2x00_async_login_sp_done+0x1dc/0x1f0 [qla2xxx]
qla24xx_process_response_queue+0xa37/0x10e0 [qla2xxx]
qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx]
__handle_irq_event_percpu+0x79/0x3c0
handle_irq_event_percpu+0x70/0xf0
handle_irq_event+0x5a/0x8b
handle_edge_irq+0x12c/0x310
handle_irq+0x192/0x20a
do_IRQ+0x73/0x160
ret_from_intr+0x0/0x1d
default_idle+0x23/0x1f0
arch_cpu_idle+0x15/0x20
default_idle_call+0x35/0x40
do_idle+0x2bb/0x2e0
cpu_startup_entry+0x1d/0x20
start_secondary+0x24d/0x2d0
secondary_startup_64+0xa4/0xb0
to a HARDIRQ-irq-unsafe lock:
(&(&k->k_lock)->rlock){+.+.}
... which became HARDIRQ-irq-unsafe at:
...
lock_acquire+0xe3/0x200
_raw_spin_lock+0x32/0x50
klist_add_tail+0x33/0xb0
device_add+0x7f4/0xb60
device_create_groups_vargs+0x11c/0x150
device_create_with_groups+0x89/0xb0
vtconsole_class_init+0xb2/0x124
do_one_initcall+0xc5/0x3ce
kernel_init_freeable+0x295/0x32e
kernel_init+0x11/0x11b
ret_from_fork+0x3a/0x50
other info that might help us debug this:
Possible interrupt unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&(&k->k_lock)->rlock);
local_irq_disable();
lock(&(&ha->tgt.sess_lock)->rlock);
lock(&(&k->k_lock)->rlock);
<Interrupt>
lock(&(&ha->tgt.sess_lock)->rlock);
*** DEADLOCK ***
4 locks held by rmdir/1478:
#0: 000000002c7f1ba4 (sb_writers#10){.+.+}, at: mnt_want_write+0x32/0x70
#1: 00000000c85eb147 (&default_group_class[depth - 1]#2/1){+.+.}, at: do_rmdir+0x217/0x2d0
#2: 000000002b164d6f (&sb->s_type->i_mutex_key#13){++++}, at: vfs_rmdir+0x7e/0x1d0
#3: 00000000cf0baf5e (&(&ha->tgt.sess_lock)->rlock){-...}, at: tcm_qla2xxx_close_session+0x57/0xb0 [tcm_qla2xxx]
the dependencies between HARDIRQ-irq-safe lock and the holding lock:
-> (&(&ha->tgt.sess_lock)->rlock){-...} ops: 127 {
IN-HARDIRQ-W at:
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
qla2x00_fcport_event_handler+0x1f3d/0x22b0 [qla2xxx]
qla2x00_async_login_sp_done+0x1dc/0x1f0 [qla2xxx]
qla24xx_process_response_queue+0xa37/0x10e0 [qla2xxx]
qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx]
__handle_irq_event_percpu+0x79/0x3c0
handle_irq_event_percpu+0x70/0xf0
handle_irq_event+0x5a/0x8b
handle_edge_irq+0x12c/0x310
handle_irq+0x192/0x20a
do_IRQ+0x73/0x160
ret_from_intr+0x0/0x1d
default_idle+0x23/0x1f0
arch_cpu_idle+0x15/0x20
default_idle_call+0x35/0x40
do_idle+0x2bb/0x2e0
cpu_startup_entry+0x1d/0x20
start_secondary+0x24d/0x2d0
secondary_startup_64+0xa4/0xb0
INITIAL USE at:
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
qla2x00_loop_resync+0xb3d/0x2690 [qla2xxx]
qla2x00_do_dpc+0xcee/0xf30 [qla2xxx]
kthread+0x1d2/0x1f0
ret_from_fork+0x3a/0x50
}
... key at: [<ffffffffa125f700>] __key.62804+0x0/0xfffffffffff7e900 [qla2xxx]
... acquired at:
__lock_acquire+0x11ed/0x1b60
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
klist_next+0x43/0x1d0
device_for_each_child+0x96/0x110
scsi_target_block+0x3c/0x40 [scsi_mod]
fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
qla2x00_mark_device_lost+0x4d3/0x500 [qla2xxx]
qlt_unreg_sess+0x104/0x2c0 [qla2xxx]
tcm_qla2xxx_close_session+0xa2/0xb0 [tcm_qla2xxx]
target_shutdown_sessions+0x17b/0x190 [target_core_mod]
core_tpg_del_initiator_node_acl+0xf3/0x1f0 [target_core_mod]
target_fabric_nacl_base_release+0x25/0x30 [target_core_mod]
config_item_release+0x9f/0x120 [configfs]
config_item_put+0x29/0x2b [configfs]
configfs_rmdir+0x3d2/0x520 [configfs]
vfs_rmdir+0xb3/0x1d0
do_rmdir+0x25c/0x2d0
__x64_sys_rmdir+0x24/0x30
do_syscall_64+0x77/0x220
entry_SYSCALL_64_after_hwframe+0x49/0xbe
the dependencies between the lock to be acquired
and HARDIRQ-irq-unsafe lock:
-> (&(&k->k_lock)->rlock){+.+.} ops: 14568 {
HARDIRQ-ON-W at:
lock_acquire+0xe3/0x200
_raw_spin_lock+0x32/0x50
klist_add_tail+0x33/0xb0
device_add+0x7f4/0xb60
device_create_groups_vargs+0x11c/0x150
device_create_with_groups+0x89/0xb0
vtconsole_class_init+0xb2/0x124
do_one_initcall+0xc5/0x3ce
kernel_init_freeable+0x295/0x32e
kernel_init+0x11/0x11b
ret_from_fork+0x3a/0x50
SOFTIRQ-ON-W at:
lock_acquire+0xe3/0x200
_raw_spin_lock+0x32/0x50
klist_add_tail+0x33/0xb0
device_add+0x7f4/0xb60
device_create_groups_vargs+0x11c/0x150
device_create_with_groups+0x89/0xb0
vtconsole_class_init+0xb2/0x124
do_one_initcall+0xc5/0x3ce
kernel_init_freeable+0x295/0x32e
kernel_init+0x11/0x11b
ret_from_fork+0x3a/0x50
INITIAL USE at:
lock_acquire+0xe3/0x200
_raw_spin_lock+0x32/0x50
klist_add_tail+0x33/0xb0
device_add+0x7f4/0xb60
device_create_groups_vargs+0x11c/0x150
device_create_with_groups+0x89/0xb0
vtconsole_class_init+0xb2/0x124
do_one_initcall+0xc5/0x3ce
kernel_init_freeable+0x295/0x32e
kernel_init+0x11/0x11b
ret_from_fork+0x3a/0x50
}
... key at: [<ffffffff83f3d900>] __key.15805+0x0/0x40
... acquired at:
__lock_acquire+0x11ed/0x1b60
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
klist_next+0x43/0x1d0
device_for_each_child+0x96/0x110
scsi_target_block+0x3c/0x40 [scsi_mod]
fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
qla2x00_mark_device_lost+0x4d3/0x500 [qla2xxx]
qlt_unreg_sess+0x104/0x2c0 [qla2xxx]
tcm_qla2xxx_close_session+0xa2/0xb0 [tcm_qla2xxx]
target_shutdown_sessions+0x17b/0x190 [target_core_mod]
core_tpg_del_initiator_node_acl+0xf3/0x1f0 [target_core_mod]
target_fabric_nacl_base_release+0x25/0x30 [target_core_mod]
config_item_release+0x9f/0x120 [configfs]
config_item_put+0x29/0x2b [configfs]
configfs_rmdir+0x3d2/0x520 [configfs]
vfs_rmdir+0xb3/0x1d0
do_rmdir+0x25c/0x2d0
__x64_sys_rmdir+0x24/0x30
do_syscall_64+0x77/0x220
entry_SYSCALL_64_after_hwframe+0x49/0xbe
stack backtrace:
CPU: 7 PID: 1478 Comm: rmdir Tainted: G W 5.1.0-rc1-dbg+ #11
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
Call Trace:
dump_stack+0x86/0xca
check_usage.cold.59+0x473/0x563
check_prev_add.constprop.43+0x1f1/0x1170
__lock_acquire+0x11ed/0x1b60
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
klist_next+0x43/0x1d0
device_for_each_child+0x96/0x110
scsi_target_block+0x3c/0x40 [scsi_mod]
fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
qla2x00_mark_device_lost+0x4d3/0x500 [qla2xxx]
qlt_unreg_sess+0x104/0x2c0 [qla2xxx]
tcm_qla2xxx_close_session+0xa2/0xb0 [tcm_qla2xxx]
target_shutdown_sessions+0x17b/0x190 [target_core_mod]
core_tpg_del_initiator_node_acl+0xf3/0x1f0 [target_core_mod]
target_fabric_nacl_base_release+0x25/0x30 [target_core_mod]
config_item_release+0x9f/0x120 [configfs]
config_item_put+0x29/0x2b [configfs]
configfs_rmdir+0x3d2/0x520 [configfs]
vfs_rmdir+0xb3/0x1d0
do_rmdir+0x25c/0x2d0
__x64_sys_rmdir+0x24/0x30
do_syscall_64+0x77/0x220
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Cc: Himanshu Madhani <hmadhani@marvell.com>
Cc: Giridhar Malavali <gmalavali@marvell.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Acked-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/tcm_qla2xxx.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index bddb573c88dd2..d6104f23f697f 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -374,8 +374,9 @@ static void tcm_qla2xxx_close_session(struct se_session *se_sess)
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
target_sess_cmd_list_set_waiting(se_sess);
- tcm_qla2xxx_put_sess(sess);
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
+
+ tcm_qla2xxx_put_sess(sess);
}
static u32 tcm_qla2xxx_sess_get_index(struct se_session *se_sess)
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH AUTOSEL 5.1 054/375] scsi: qla2xxx: Fix hardirq-unsafe locking
[not found] <20190522192115.22666-1-sashal@kernel.org>
` (4 preceding siblings ...)
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 053/375] scsi: qla2xxx: Avoid that lockdep complains about unsafe locking in tcm_qla2xxx_close_session() Sasha Levin
@ 2019-05-22 19:15 ` Sasha Levin
2019-05-22 19:16 ` [PATCH AUTOSEL 5.1 063/375] scsi: qedi: Abort ep termination if offload not scheduled Sasha Levin
6 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2019-05-22 19:15 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Bart Van Assche, Himanshu Madhani, Giridhar Malavali,
Martin K . Petersen, Sasha Levin, linux-scsi
From: Bart Van Assche <bvanassche@acm.org>
[ Upstream commit 300ec7415c1fed5c73660f50c8e14a67e236dc0a ]
Since fc_remote_port_delete() must be called with interrupts enabled, do
not disable interrupts when calling that function. Remove the lockin calls
from around the put_sess() call. This is safe because the function that is
called when the final reference is dropped, qlt_unreg_sess(), grabs the
proper locks. This patch avoids that lockdep reports the following:
WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected
kworker/2:1/62 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire:
0000000009e679b3 (&(&k->k_lock)->rlock){+.+.}, at: klist_next+0x43/0x1d0
and this task is already holding:
00000000a033b71c (&(&ha->tgt.sess_lock)->rlock){-...}, at: qla24xx_delete_sess_fn+0x55/0xf0 [qla2xxx_scst]
which would create a new lock dependency:
(&(&ha->tgt.sess_lock)->rlock){-...} -> (&(&k->k_lock)->rlock){+.+.}
but this new dependency connects a HARDIRQ-irq-safe lock:
(&(&ha->tgt.sess_lock)->rlock){-...}
... which became HARDIRQ-irq-safe at:
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
qla24xx_report_id_acquisition+0xa69/0xe30 [qla2xxx_scst]
qla24xx_process_response_queue+0x69e/0x1270 [qla2xxx_scst]
qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx_scst]
__handle_irq_event_percpu+0x79/0x3c0
handle_irq_event_percpu+0x70/0xf0
handle_irq_event+0x5a/0x8b
handle_edge_irq+0x12c/0x310
handle_irq+0x192/0x20a
do_IRQ+0x73/0x160
ret_from_intr+0x0/0x1d
default_idle+0x23/0x1f0
arch_cpu_idle+0x15/0x20
default_idle_call+0x35/0x40
do_idle+0x2bb/0x2e0
cpu_startup_entry+0x1d/0x20
start_secondary+0x2a8/0x320
secondary_startup_64+0xa4/0xb0
to a HARDIRQ-irq-unsafe lock:
(&(&k->k_lock)->rlock){+.+.}
... which became HARDIRQ-irq-unsafe at:
...
lock_acquire+0xe3/0x200
_raw_spin_lock+0x32/0x50
klist_add_tail+0x33/0xb0
device_add+0x7e1/0xb50
device_create_groups_vargs+0x11c/0x150
device_create_with_groups+0x89/0xb0
vtconsole_class_init+0xb2/0x124
do_one_initcall+0xc5/0x3ce
kernel_init_freeable+0x295/0x32e
kernel_init+0x11/0x11b
ret_from_fork+0x3a/0x50
other info that might help us debug this:
Possible interrupt unsafe locking scenario:
CPU0 CPU1
---- ----
lock(&(&k->k_lock)->rlock);
local_irq_disable();
lock(&(&ha->tgt.sess_lock)->rlock);
lock(&(&k->k_lock)->rlock);
<Interrupt>
lock(&(&ha->tgt.sess_lock)->rlock);
*** DEADLOCK ***
3 locks held by kworker/2:1/62:
#0: 00000000a4319c16 ((wq_completion)"qla2xxx_wq"){+.+.}, at: process_one_work+0x437/0xa80
#1: 00000000ffa34c42 ((work_completion)(&sess->del_work)){+.+.}, at: process_one_work+0x437/0xa80
#2: 00000000a033b71c (&(&ha->tgt.sess_lock)->rlock){-...}, at: qla24xx_delete_sess_fn+0x55/0xf0 [qla2xxx_scst]
the dependencies between HARDIRQ-irq-safe lock and the holding lock:
-> (&(&ha->tgt.sess_lock)->rlock){-...} ops: 8 {
IN-HARDIRQ-W at:
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
qla24xx_report_id_acquisition+0xa69/0xe30 [qla2xxx_scst]
qla24xx_process_response_queue+0x69e/0x1270 [qla2xxx_scst]
qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx_scst]
__handle_irq_event_percpu+0x79/0x3c0
handle_irq_event_percpu+0x70/0xf0
handle_irq_event+0x5a/0x8b
handle_edge_irq+0x12c/0x310
handle_irq+0x192/0x20a
do_IRQ+0x73/0x160
ret_from_intr+0x0/0x1d
default_idle+0x23/0x1f0
arch_cpu_idle+0x15/0x20
default_idle_call+0x35/0x40
do_idle+0x2bb/0x2e0
cpu_startup_entry+0x1d/0x20
start_secondary+0x2a8/0x320
secondary_startup_64+0xa4/0xb0
INITIAL USE at:
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
qla24xx_report_id_acquisition+0xa69/0xe30 [qla2xxx_scst]
qla24xx_process_response_queue+0x69e/0x1270 [qla2xxx_scst]
qla24xx_msix_rsp_q+0x79/0xf0 [qla2xxx_scst]
__handle_irq_event_percpu+0x79/0x3c0
handle_irq_event_percpu+0x70/0xf0
handle_irq_event+0x5a/0x8b
handle_edge_irq+0x12c/0x310
handle_irq+0x192/0x20a
do_IRQ+0x73/0x160
ret_from_intr+0x0/0x1d
default_idle+0x23/0x1f0
arch_cpu_idle+0x15/0x20
default_idle_call+0x35/0x40
do_idle+0x2bb/0x2e0
cpu_startup_entry+0x1d/0x20
start_secondary+0x2a8/0x320
secondary_startup_64+0xa4/0xb0
}
... key at: [<ffffffffa0c0d080>] __key.85462+0x0/0xfffffffffff7df80 [qla2xxx_scst]
... acquired at:
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
klist_next+0x43/0x1d0
device_for_each_child+0x96/0x110
scsi_target_block+0x3c/0x40 [scsi_mod]
fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
qla2x00_mark_device_lost+0xa0b/0xa30 [qla2xxx_scst]
qlt_unreg_sess+0x1c6/0x380 [qla2xxx_scst]
qla24xx_delete_sess_fn+0xe6/0xf0 [qla2xxx_scst]
process_one_work+0x511/0xa80
worker_thread+0x67/0x5b0
kthread+0x1d2/0x1f0
ret_from_fork+0x3a/0x50
the dependencies between the lock to be acquired
and HARDIRQ-irq-unsafe lock:
-> (&(&k->k_lock)->rlock){+.+.} ops: 13831 {
HARDIRQ-ON-W at:
lock_acquire+0xe3/0x200
_raw_spin_lock+0x32/0x50
klist_add_tail+0x33/0xb0
device_add+0x7e1/0xb50
device_create_groups_vargs+0x11c/0x150
device_create_with_groups+0x89/0xb0
vtconsole_class_init+0xb2/0x124
do_one_initcall+0xc5/0x3ce
kernel_init_freeable+0x295/0x32e
kernel_init+0x11/0x11b
ret_from_fork+0x3a/0x50
SOFTIRQ-ON-W at:
lock_acquire+0xe3/0x200
_raw_spin_lock+0x32/0x50
klist_add_tail+0x33/0xb0
device_add+0x7e1/0xb50
device_create_groups_vargs+0x11c/0x150
device_create_with_groups+0x89/0xb0
vtconsole_class_init+0xb2/0x124
do_one_initcall+0xc5/0x3ce
kernel_init_freeable+0x295/0x32e
kernel_init+0x11/0x11b
ret_from_fork+0x3a/0x50
INITIAL USE at:
lock_acquire+0xe3/0x200
_raw_spin_lock+0x32/0x50
klist_add_tail+0x33/0xb0
device_add+0x7e1/0xb50
device_create_groups_vargs+0x11c/0x150
device_create_with_groups+0x89/0xb0
vtconsole_class_init+0xb2/0x124
do_one_initcall+0xc5/0x3ce
kernel_init_freeable+0x295/0x32e
kernel_init+0x11/0x11b
ret_from_fork+0x3a/0x50
}
... key at: [<ffffffff83ed8780>] __key.15491+0x0/0x40
... acquired at:
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
klist_next+0x43/0x1d0
device_for_each_child+0x96/0x110
scsi_target_block+0x3c/0x40 [scsi_mod]
fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
qla2x00_mark_device_lost+0xa0b/0xa30 [qla2xxx_scst]
qlt_unreg_sess+0x1c6/0x380 [qla2xxx_scst]
qla24xx_delete_sess_fn+0xe6/0xf0 [qla2xxx_scst]
process_one_work+0x511/0xa80
worker_thread+0x67/0x5b0
kthread+0x1d2/0x1f0
ret_from_fork+0x3a/0x50
stack backtrace:
CPU: 2 PID: 62 Comm: kworker/2:1 Tainted: G O 5.0.7-dbg+ #8
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
Workqueue: qla2xxx_wq qla24xx_delete_sess_fn [qla2xxx_scst]
Call Trace:
dump_stack+0x86/0xca
check_usage.cold.52+0x473/0x563
__lock_acquire+0x11c0/0x23e0
lock_acquire+0xe3/0x200
_raw_spin_lock_irqsave+0x3d/0x60
klist_next+0x43/0x1d0
device_for_each_child+0x96/0x110
scsi_target_block+0x3c/0x40 [scsi_mod]
fc_remote_port_delete+0xe7/0x1c0 [scsi_transport_fc]
qla2x00_mark_device_lost+0xa0b/0xa30 [qla2xxx_scst]
qlt_unreg_sess+0x1c6/0x380 [qla2xxx_scst]
qla24xx_delete_sess_fn+0xe6/0xf0 [qla2xxx_scst]
process_one_work+0x511/0xa80
worker_thread+0x67/0x5b0
kthread+0x1d2/0x1f0
ret_from_fork+0x3a/0x50
Cc: Himanshu Madhani <hmadhani@marvell.com>
Cc: Giridhar Malavali <gmalavali@marvell.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Acked-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qla2xxx/qla_target.c | 25 ++++++++-----------------
drivers/scsi/qla2xxx/tcm_qla2xxx.c | 2 --
2 files changed, 8 insertions(+), 19 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 697eee1d88474..b210a8296c275 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -680,7 +680,6 @@ int qla24xx_async_notify_ack(scsi_qla_host_t *vha, fc_port_t *fcport,
void qla24xx_do_nack_work(struct scsi_qla_host *vha, struct qla_work_evt *e)
{
fc_port_t *t;
- unsigned long flags;
switch (e->u.nack.type) {
case SRB_NACK_PRLI:
@@ -693,10 +692,8 @@ void qla24xx_do_nack_work(struct scsi_qla_host *vha, struct qla_work_evt *e)
if (t) {
ql_log(ql_log_info, vha, 0xd034,
"%s create sess success %p", __func__, t);
- spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
/* create sess has an extra kref */
vha->hw->tgt.tgt_ops->put_sess(e->u.nack.fcport);
- spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
}
break;
}
@@ -708,9 +705,6 @@ void qla24xx_delete_sess_fn(struct work_struct *work)
{
fc_port_t *fcport = container_of(work, struct fc_port, del_work);
struct qla_hw_data *ha = fcport->vha->hw;
- unsigned long flags;
-
- spin_lock_irqsave(&ha->tgt.sess_lock, flags);
if (fcport->se_sess) {
ha->tgt.tgt_ops->shutdown_sess(fcport);
@@ -718,7 +712,6 @@ void qla24xx_delete_sess_fn(struct work_struct *work)
} else {
qlt_unreg_sess(fcport);
}
- spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
}
/*
@@ -787,8 +780,9 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
fcport->port_name, sess->loop_id);
sess->local = 0;
}
- ha->tgt.tgt_ops->put_sess(sess);
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
+ ha->tgt.tgt_ops->put_sess(sess);
}
/*
@@ -4242,9 +4236,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
/*
* Drop extra session reference from qla_tgt_handle_cmd_for_atio*(
*/
- spin_lock_irqsave(&ha->tgt.sess_lock, flags);
ha->tgt.tgt_ops->put_sess(sess);
- spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
return;
out_term:
@@ -4261,9 +4253,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
target_free_tag(sess->se_sess, &cmd->se_cmd);
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
- spin_lock_irqsave(&ha->tgt.sess_lock, flags);
ha->tgt.tgt_ops->put_sess(sess);
- spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
}
static void qlt_do_work(struct work_struct *work)
@@ -4472,9 +4462,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
if (!cmd) {
ql_dbg(ql_dbg_io, vha, 0x3062,
"qla_target(%d): Allocation of cmd failed\n", vha->vp_idx);
- spin_lock_irqsave(&ha->tgt.sess_lock, flags);
ha->tgt.tgt_ops->put_sess(sess);
- spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
return -EBUSY;
}
@@ -6318,17 +6306,19 @@ static void qlt_abort_work(struct qla_tgt *tgt,
}
rc = __qlt_24xx_handle_abts(vha, &prm->abts, sess);
- ha->tgt.tgt_ops->put_sess(sess);
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
+ ha->tgt.tgt_ops->put_sess(sess);
+
if (rc != 0)
goto out_term;
return;
out_term2:
+ spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
+
if (sess)
ha->tgt.tgt_ops->put_sess(sess);
- spin_unlock_irqrestore(&ha->tgt.sess_lock, flags2);
out_term:
spin_lock_irqsave(&ha->hardware_lock, flags);
@@ -6386,9 +6376,10 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
scsilun_to_int((struct scsi_lun *)&a->u.isp24.fcp_cmnd.lun);
rc = qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0);
- ha->tgt.tgt_ops->put_sess(sess);
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+ ha->tgt.tgt_ops->put_sess(sess);
+
if (rc != 0)
goto out_term;
return;
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index d6104f23f697f..e58becb790fa3 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -359,7 +359,6 @@ static void tcm_qla2xxx_put_sess(struct fc_port *sess)
if (!sess)
return;
- assert_spin_locked(&sess->vha->hw->tgt.sess_lock);
kref_put(&sess->sess_kref, tcm_qla2xxx_release_session);
}
@@ -832,7 +831,6 @@ static void tcm_qla2xxx_clear_nacl_from_fcport_map(struct fc_port *sess)
static void tcm_qla2xxx_shutdown_sess(struct fc_port *sess)
{
- assert_spin_locked(&sess->vha->hw->tgt.sess_lock);
target_sess_cmd_list_set_waiting(sess->se_sess);
}
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH AUTOSEL 5.1 063/375] scsi: qedi: Abort ep termination if offload not scheduled
[not found] <20190522192115.22666-1-sashal@kernel.org>
` (5 preceding siblings ...)
2019-05-22 19:15 ` [PATCH AUTOSEL 5.1 054/375] scsi: qla2xxx: Fix hardirq-unsafe locking Sasha Levin
@ 2019-05-22 19:16 ` Sasha Levin
6 siblings, 0 replies; 7+ messages in thread
From: Sasha Levin @ 2019-05-22 19:16 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Manish Rangankar, Martin K . Petersen, Sasha Levin, linux-scsi
From: Manish Rangankar <mrangankar@marvell.com>
[ Upstream commit f848bfd8e167210a29374e8a678892bed591684f ]
Sometimes during connection recovery when there is a failure to resolve
ARP, and offload connection was not issued, driver tries to flush pending
offload connection work which was not queued up.
kernel: WARNING: CPU: 19 PID: 10110 at kernel/workqueue.c:3030 __flush_work.isra.34+0x19c/0x1b0
kernel: CPU: 19 PID: 10110 Comm: iscsid Tainted: G W 5.1.0-rc4 #11
kernel: Hardware name: Dell Inc. PowerEdge R730/0599V5, BIOS 2.9.1 12/04/2018
kernel: RIP: 0010:__flush_work.isra.34+0x19c/0x1b0
kernel: Code: 8b fb 66 0f 1f 44 00 00 31 c0 eb ab 48 89 ef c6 07 00 0f 1f 40 00 fb 66 0f 1f 44 00 00 31 c0 eb 96 e8 08 16 fe ff 0f 0b eb 8d <0f> 0b 31 c0 eb 87 0f 1f 40 00 66 2e 0f 1
f 84 00 00 00 00 00 0f 1f
kernel: RSP: 0018:ffffa6b4054dba68 EFLAGS: 00010246
kernel: RAX: 0000000000000000 RBX: ffff91df21c36fc0 RCX: 0000000000000000
kernel: RDX: 0000000000000001 RSI: 0000000000000000 RDI: ffff91df21c36fc0
kernel: RBP: ffff91df21c36ef0 R08: 0000000000000000 R09: 0000000000000000
kernel: R10: 0000000000000038 R11: ffffa6b4054dbd60 R12: ffffffffc05e72c0
kernel: R13: ffff91db10280820 R14: 0000000000000048 R15: 0000000000000000
kernel: FS: 00007f5d83cc1740(0000) GS:ffff91df2f840000(0000) knlGS:0000000000000000
kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
kernel: CR2: 0000000001cc5000 CR3: 0000000465450002 CR4: 00000000001606e0
kernel: Call Trace:
kernel: ? try_to_del_timer_sync+0x4d/0x80
kernel: qedi_ep_disconnect+0x3b/0x410 [qedi]
kernel: ? 0xffffffffc083c000
kernel: ? klist_iter_exit+0x14/0x20
kernel: ? class_find_device+0x93/0xf0
kernel: iscsi_if_ep_disconnect.isra.18+0x58/0x70 [scsi_transport_iscsi]
kernel: iscsi_if_recv_msg+0x10e2/0x1510 [scsi_transport_iscsi]
kernel: ? copyout+0x22/0x30
kernel: ? _copy_to_iter+0xa0/0x430
kernel: ? _cond_resched+0x15/0x30
kernel: ? __kmalloc_node_track_caller+0x1f9/0x270
kernel: iscsi_if_rx+0xa5/0x1e0 [scsi_transport_iscsi]
kernel: netlink_unicast+0x17f/0x230
kernel: netlink_sendmsg+0x2d2/0x3d0
kernel: sock_sendmsg+0x36/0x50
kernel: ___sys_sendmsg+0x280/0x2a0
kernel: ? timerqueue_add+0x54/0x80
kernel: ? enqueue_hrtimer+0x38/0x90
kernel: ? hrtimer_start_range_ns+0x19f/0x2c0
kernel: __sys_sendmsg+0x58/0xa0
kernel: do_syscall_64+0x5b/0x180
kernel: entry_SYSCALL_64_after_hwframe+0x44/0xa9
Signed-off-by: Manish Rangankar <mrangankar@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/qedi/qedi_iscsi.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index 6d6d6013e35b8..bf371e7b957d0 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -1000,6 +1000,9 @@ static void qedi_ep_disconnect(struct iscsi_endpoint *ep)
qedi_ep = ep->dd_data;
qedi = qedi_ep->qedi;
+ if (qedi_ep->state == EP_STATE_OFLDCONN_START)
+ goto ep_exit_recover;
+
flush_work(&qedi_ep->offload_work);
if (qedi_ep->conn) {
--
2.20.1
^ permalink raw reply related [flat|nested] 7+ messages in thread