nvme-auth: use workqueue dedicated to authentication
NVMe In-Band authentication uses two kinds of works: chap->auth_work and
ctrl->dhchap_auth_work. The latter work flushes or cancels the former
work. However, the both works are queued to the same workqueue nvme-wq.
It results in the lockdep WARNING as follows:
WARNING: possible recursive locking detected
6.2.0-rc4+ #1 Not tainted
--------------------------------------------
kworker/u16:7/69 is trying to acquire lock:
ffff902d52e65548 ((wq_completion)nvme-wq){+.+.}-{0:0}, at: start_flush_work+0x2c5/0x380
but task is already holding lock:
ffff902d52e65548 ((wq_completion)nvme-wq){+.+.}-{0:0}, at: process_one_work+0x210/0x410
To avoid the WARNING, introduce a new workqueue nvme-auth-wq dedicated
to chap->auth_work.
Reported-by: Daniel Wagner <dwagner@suse.de>
Link: https://lore.kernel.org/linux-nvme/20230130110802.paafkiipmitwtnwr@carbon.lan/
Fixes: f50fff73d6
("nvme: implement In-Band authentication")
Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
Tested-by: Daniel Wagner <dwagner@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
Родитель
6fbf13c0e2
Коммит
bd97a59da6
|
@ -45,6 +45,8 @@ struct nvme_dhchap_queue_context {
|
|||
int sess_key_len;
|
||||
};
|
||||
|
||||
struct workqueue_struct *nvme_auth_wq;
|
||||
|
||||
#define nvme_auth_flags_from_qid(qid) \
|
||||
(qid == 0) ? 0 : BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED
|
||||
#define nvme_auth_queue_from_qid(ctrl, qid) \
|
||||
|
@ -866,7 +868,7 @@ int nvme_auth_negotiate(struct nvme_ctrl *ctrl, int qid)
|
|||
|
||||
chap = &ctrl->dhchap_ctxs[qid];
|
||||
cancel_work_sync(&chap->auth_work);
|
||||
queue_work(nvme_wq, &chap->auth_work);
|
||||
queue_work(nvme_auth_wq, &chap->auth_work);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvme_auth_negotiate);
|
||||
|
@ -1008,10 +1010,15 @@ EXPORT_SYMBOL_GPL(nvme_auth_free);
|
|||
|
||||
int __init nvme_init_auth(void)
|
||||
{
|
||||
nvme_auth_wq = alloc_workqueue("nvme-auth-wq",
|
||||
WQ_UNBOUND | WQ_MEM_RECLAIM | WQ_SYSFS, 0);
|
||||
if (!nvme_auth_wq)
|
||||
return -ENOMEM;
|
||||
|
||||
nvme_chap_buf_cache = kmem_cache_create("nvme-chap-buf-cache",
|
||||
CHAP_BUF_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL);
|
||||
if (!nvme_chap_buf_cache)
|
||||
return -ENOMEM;
|
||||
goto err_destroy_workqueue;
|
||||
|
||||
nvme_chap_buf_pool = mempool_create(16, mempool_alloc_slab,
|
||||
mempool_free_slab, nvme_chap_buf_cache);
|
||||
|
@ -1021,6 +1028,8 @@ int __init nvme_init_auth(void)
|
|||
return 0;
|
||||
err_destroy_chap_buf_cache:
|
||||
kmem_cache_destroy(nvme_chap_buf_cache);
|
||||
err_destroy_workqueue:
|
||||
destroy_workqueue(nvme_auth_wq);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
@ -1028,4 +1037,5 @@ void __exit nvme_exit_auth(void)
|
|||
{
|
||||
mempool_destroy(nvme_chap_buf_pool);
|
||||
kmem_cache_destroy(nvme_chap_buf_cache);
|
||||
destroy_workqueue(nvme_auth_wq);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче