diff options
author | Bart Van Assche <bvanassche@acm.org> | 2022-08-22 01:04:59 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2022-09-01 08:02:10 +0300 |
commit | 2b36209ca8182c5e0221dd416106d434de433d34 (patch) | |
tree | 420ef02e7bbf3b775784ae3dd32bfe572ca376a4 /drivers/scsi | |
parent | da6d507f5ff328f346b3c50e19e19993027b8ffd (diff) | |
download | linux-2b36209ca8182c5e0221dd416106d434de433d34.tar.xz |
scsi: core: Revert "Call blk_mq_free_tag_set() earlier"
Revert the patch series "Call blk_mq_free_tag_set() earlier" because it
introduces a deadlock if the scsi_remove_host() caller holds a reference on
a device, target or host.
Link: https://lore.kernel.org/r/20220821220502.13685-2-bvanassche@acm.org
Fixes: f323896fe6fa ("scsi: core: Call blk_mq_free_tag_set() earlier")
Reported-by: syzbot+bafeb834708b1bb750bc@syzkaller.appspotmail.com
Tested-by: Kenneth R. Crudup <kenny@panix.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/hosts.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 0738238ed6cc..20c1f5420ba6 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -197,8 +197,6 @@ void scsi_remove_host(struct Scsi_Host *shost) * the dependent SCSI targets and devices are gone before returning. */ wait_event(shost->targets_wq, atomic_read(&shost->target_count) == 0); - - scsi_mq_destroy_tags(shost); } EXPORT_SYMBOL(scsi_remove_host); @@ -309,8 +307,8 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, return error; /* - * Any resources associated with the SCSI host in this function except - * the tag set will be freed by scsi_host_dev_release(). + * Any host allocation in this function will be freed in + * scsi_host_dev_release(). */ out_del_dev: device_del(&shost->shost_dev); @@ -326,7 +324,6 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, pm_runtime_disable(&shost->shost_gendev); pm_runtime_set_suspended(&shost->shost_gendev); pm_runtime_put_noidle(&shost->shost_gendev); - scsi_mq_destroy_tags(shost); fail: return error; } @@ -360,6 +357,9 @@ static void scsi_host_dev_release(struct device *dev) kfree(dev_name(&shost->shost_dev)); } + if (shost->tag_set.tags) + scsi_mq_destroy_tags(shost); + kfree(shost->shost_data); ida_free(&host_index_ida, shost->host_no); |