Message ID | 20220712221936.1199196-5-bvanassche@acm.org |
---|---|
State | New |
Headers | show |
Series | Call blk_mq_free_tag_set() earlier | expand |
On 7/14/22 05:25, John Garry wrote: > On 13/07/2022 21:04, Bart Van Assche wrote: >>>> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c >>>> index 2aca0a838ca5..295c48fdb650 100644 >>>> --- a/drivers/scsi/scsi_lib.c >>>> +++ b/drivers/scsi/scsi_lib.c >>>> @@ -1990,7 +1990,10 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost) >>>> void scsi_mq_destroy_tags(struct Scsi_Host *shost) >>>> { >>>> + if (!shost->tag_set.tags) >>>> + return; >>>> blk_mq_free_tag_set(&shost->tag_set); >>>> + WARN_ON_ONCE(shost->tag_set.tags); >>> >>> blk_mq_free_tag_set() clears the tagset tags pointer, so I don't know >>> why you don't trust the semantics of that API - this seems like >>> paranoia. >> >> Semantics of the API? Shouldn't this rather be called an undocumented >> aspect of blk_mq_free_tag_set()? >> >> My concern is that the "set->tags = NULL" statement might be removed >> in the future from blk_mq_free_tag_set() and also that it is possible >> that scsi_mq_destroy_tags() is not updated after that change. > > Sure, so how it is possible that set->tags == NULL ever when calling > scsi_mq_setup_tags()? I'm just wondering why you even care. How about applying the patch below on top of patch 4/4? diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 295c48fdb650..2aca0a838ca5 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1990,10 +1990,7 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost) void scsi_mq_destroy_tags(struct Scsi_Host *shost) { - if (!shost->tag_set.tags) - return; blk_mq_free_tag_set(&shost->tag_set); - WARN_ON_ONCE(shost->tag_set.tags); } Thanks, Bart.
On 14/07/2022 19:49, Bart Van Assche wrote: >>> Semantics of the API? Shouldn't this rather be called an undocumented >>> aspect of blk_mq_free_tag_set()? >>> >>> My concern is that the "set->tags = NULL" statement might be removed >>> in the future from blk_mq_free_tag_set() and also that it is possible >>> that scsi_mq_destroy_tags() is not updated after that change. >> >> Sure, so how it is possible that set->tags == NULL ever when calling >> scsi_mq_setup_tags()? I'm just wondering why you even care. > > How about applying the patch below on top of patch 4/4? > > diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c > index 295c48fdb650..2aca0a838ca5 100644 > --- a/drivers/scsi/scsi_lib.c > +++ b/drivers/scsi/scsi_lib.c > @@ -1990,10 +1990,7 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost) > > void scsi_mq_destroy_tags(struct Scsi_Host *shost) > { > - if (!shost->tag_set.tags) > - return; > blk_mq_free_tag_set(&shost->tag_set); > - WARN_ON_ONCE(shost->tag_set.tags); > } That looks better. Thanks, John
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 8fa98c8d0ee0..6c63672971f1 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -197,6 +197,8 @@ 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); @@ -302,8 +304,8 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, return error; /* - * Any host allocation in this function will be freed in - * scsi_host_dev_release(). + * Any resources associated with the SCSI host in this function except + * the tag set will be freed by scsi_host_dev_release(). */ out_del_dev: device_del(&shost->shost_dev); @@ -319,6 +321,7 @@ 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; } @@ -352,9 +355,6 @@ 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); diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 2aca0a838ca5..295c48fdb650 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1990,7 +1990,10 @@ int scsi_mq_setup_tags(struct Scsi_Host *shost) void scsi_mq_destroy_tags(struct Scsi_Host *shost) { + if (!shost->tag_set.tags) + return; blk_mq_free_tag_set(&shost->tag_set); + WARN_ON_ONCE(shost->tag_set.tags); } /**