diff mbox series

[V2] scsi: fix race on creating sense cache

Message ID 20190712020819.31935-1-ming.lei@redhat.com (mailing list archive)
State Mainlined
Commit f9b0530fa02e0c73f31a49ef743e8f44eb8e32cc
Headers show
Series [V2] scsi: fix race on creating sense cache | expand

Commit Message

Ming Lei July 12, 2019, 2:08 a.m. UTC
When scsi_init_sense_cache(host) is called concurrently from different
hosts, each code path may see that the cache isn't created, then try
to create a new one, then the created sense cache may be overrided and
leaked.

Fixes the issue by moving 'mutex_lock(&scsi_sense_cache_mutex)' before
scsi_select_sense_cache().

Fixes: 0a6ac4ee7c21 ("scsi: respect unchecked_isa_dma for blk-mq")
Cc: Stable <stable@vger.kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Ewan D. Milne <emilne@redhat.com>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
---
 drivers/scsi/scsi_lib.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Martin K. Petersen July 17, 2019, 2:43 a.m. UTC | #1
Ming,

> When scsi_init_sense_cache(host) is called concurrently from different
> hosts, each code path may see that the cache isn't created, then try
> to create a new one, then the created sense cache may be overrided and
> leaked.
>
> Fixes the issue by moving 'mutex_lock(&scsi_sense_cache_mutex)' before
> scsi_select_sense_cache().

Applied to 5.3/scsi-fixes, thanks!
diff mbox series

Patch

diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index e07a376a8c38..7493680ec104 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -72,11 +72,11 @@  int scsi_init_sense_cache(struct Scsi_Host *shost)
 	struct kmem_cache *cache;
 	int ret = 0;
 
+	mutex_lock(&scsi_sense_cache_mutex);
 	cache = scsi_select_sense_cache(shost->unchecked_isa_dma);
 	if (cache)
-		return 0;
+		goto exit;
 
-	mutex_lock(&scsi_sense_cache_mutex);
 	if (shost->unchecked_isa_dma) {
 		scsi_sense_isadma_cache =
 			kmem_cache_create("scsi_sense_cache(DMA)",
@@ -92,7 +92,7 @@  int scsi_init_sense_cache(struct Scsi_Host *shost)
 		if (!scsi_sense_cache)
 			ret = -ENOMEM;
 	}
-
+ exit:
 	mutex_unlock(&scsi_sense_cache_mutex);
 	return ret;
 }