[PATCH v3 02/11] scsi: scsi_debug: Don't iter all shosts in clear_luns_changed_on_target()

John Garry posted 11 patches 2 years, 10 months ago
[PATCH v3 02/11] scsi: scsi_debug: Don't iter all shosts in clear_luns_changed_on_target()
Posted by John Garry 2 years, 10 months ago
In clear_luns_changed_on_target(), we iter all devices for all shosts to
conditionally clear the SDEBUG_UA_LUNS_CHANGED flag in the per-device
uas_bm.

One condition to see whether we clear the flag is to test whether the host
for the device under consideration is the same as the matching device's
(devip) host. This check will only ever pass for devices for the same
shost, so only iter the devices for the matching device shost.

We can now drop the spinlock'ing of the sdebug_host_list_lock in the same
function. This will allow us to use a mutex instead of the spinlock for
the global shost lock, as clear_luns_changed_on_target() could be called
in non-blocking context, in scsi_debug_queuecommand() -> make_ua() ->
clear_luns_changed_on_target() (which is why required a spinlock).

Signed-off-by: John Garry <john.g.garry@oracle.com>
---
 drivers/scsi/scsi_debug.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 782515abca2c..eba6eca81e84 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -1063,18 +1063,15 @@ static void all_config_cdb_len(void)
 
 static void clear_luns_changed_on_target(struct sdebug_dev_info *devip)
 {
-	struct sdebug_host_info *sdhp;
+	struct sdebug_host_info *sdhp = devip->sdbg_host;
 	struct sdebug_dev_info *dp;
 
-	spin_lock(&sdebug_host_list_lock);
-	list_for_each_entry(sdhp, &sdebug_host_list, host_list) {
-		list_for_each_entry(dp, &sdhp->dev_info_list, dev_list) {
-			if ((devip->sdbg_host == dp->sdbg_host) &&
-			    (devip->target == dp->target))
-				clear_bit(SDEBUG_UA_LUNS_CHANGED, dp->uas_bm);
+	list_for_each_entry(dp, &sdhp->dev_info_list, dev_list) {
+		if ((devip->sdbg_host == dp->sdbg_host) &&
+		    (devip->target == dp->target)) {
+			clear_bit(SDEBUG_UA_LUNS_CHANGED, dp->uas_bm);
 		}
 	}
-	spin_unlock(&sdebug_host_list_lock);
 }
 
 static int make_ua(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
-- 
2.35.3
Re: [PATCH v3 02/11] scsi: scsi_debug: Don't iter all shosts in clear_luns_changed_on_target()
Posted by Douglas Gilbert 2 years, 10 months ago
On 2023-03-27 03:43, John Garry wrote:
> In clear_luns_changed_on_target(), we iter all devices for all shosts to
> conditionally clear the SDEBUG_UA_LUNS_CHANGED flag in the per-device
> uas_bm.
> 
> One condition to see whether we clear the flag is to test whether the host
> for the device under consideration is the same as the matching device's
> (devip) host. This check will only ever pass for devices for the same
> shost, so only iter the devices for the matching device shost.
> 
> We can now drop the spinlock'ing of the sdebug_host_list_lock in the same
> function. This will allow us to use a mutex instead of the spinlock for
> the global shost lock, as clear_luns_changed_on_target() could be called
> in non-blocking context, in scsi_debug_queuecommand() -> make_ua() ->
> clear_luns_changed_on_target() (which is why required a spinlock).
> 
> Signed-off-by: John Garry <john.g.garry@oracle.com>
Acked-by: Douglas Gilbert <dgilbert@interlog.com

Thanks.

> ---
>   drivers/scsi/scsi_debug.c | 13 +++++--------
>   1 file changed, 5 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index 782515abca2c..eba6eca81e84 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -1063,18 +1063,15 @@ static void all_config_cdb_len(void)
>   
>   static void clear_luns_changed_on_target(struct sdebug_dev_info *devip)
>   {
> -	struct sdebug_host_info *sdhp;
> +	struct sdebug_host_info *sdhp = devip->sdbg_host;
>   	struct sdebug_dev_info *dp;
>   
> -	spin_lock(&sdebug_host_list_lock);
> -	list_for_each_entry(sdhp, &sdebug_host_list, host_list) {
> -		list_for_each_entry(dp, &sdhp->dev_info_list, dev_list) {
> -			if ((devip->sdbg_host == dp->sdbg_host) &&
> -			    (devip->target == dp->target))
> -				clear_bit(SDEBUG_UA_LUNS_CHANGED, dp->uas_bm);
> +	list_for_each_entry(dp, &sdhp->dev_info_list, dev_list) {
> +		if ((devip->sdbg_host == dp->sdbg_host) &&
> +		    (devip->target == dp->target)) {
> +			clear_bit(SDEBUG_UA_LUNS_CHANGED, dp->uas_bm);
>   		}
>   	}
> -	spin_unlock(&sdebug_host_list_lock);
>   }
>   
>   static int make_ua(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)