]> git.baikalelectronics.ru Git - kernel.git/commitdiff
scsi: scsi_debug: Use TASK SET FULL more
authorDouglas Gilbert <dgilbert@interlog.com>
Sun, 9 Jan 2022 01:28:47 +0000 (20:28 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 25 Jan 2022 05:25:05 +0000 (00:25 -0500)
When the internal in_use bit array in this driver is full returning
SCSI_MLQUEUE_HOST_BUSY leads to the mid-level reissuing the request which
is unhelpful. Previously TASK SET FULL status was only returned if ALL_TSF
[0x400] is placed in the opts variable (at load time or via sysfs). Now
ignore that setting and always return TASK SET FULL when in_use array is
full. Also set DID_ABORT together with TASK SET FULL so the mid-level gives
up immediately.

Aside: the situations addressed by this patch lead to lockups and
timeouts. They have only been detected when blk_poll() is used. That
mechanism is relatively new in the SCSI subsystem suggesting the mid-level
may need more work in that area.

Link: https://lore.kernel.org/r/20220109012853.301953-4-dgilbert@interlog.com
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_debug.c

index 40f698e331eef74dc4732d5b1861b8b11d918e53..8abe95a0d869ac3fba67b55998f43c1e2ea5288a 100644 (file)
@@ -174,7 +174,7 @@ static const char *sdebug_version_date = "20200710";
 #define SDEBUG_OPT_MAC_TIMEOUT         128
 #define SDEBUG_OPT_SHORT_TRANSFER      0x100
 #define SDEBUG_OPT_Q_NOISE             0x200
-#define SDEBUG_OPT_ALL_TSF             0x400
+#define SDEBUG_OPT_ALL_TSF             0x400   /* ignore */
 #define SDEBUG_OPT_RARE_TSF            0x800
 #define SDEBUG_OPT_N_WCE               0x1000
 #define SDEBUG_OPT_RESET_NOISE         0x2000
@@ -861,7 +861,7 @@ static const int illegal_condition_result =
        (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION;
 
 static const int device_qfull_result =
-       (DID_OK << 16) | SAM_STAT_TASK_SET_FULL;
+       (DID_ABORT << 16) | SAM_STAT_TASK_SET_FULL;
 
 static const int condition_met_result = SAM_STAT_CONDITION_MET;
 
@@ -5521,18 +5521,11 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
                spin_unlock_irqrestore(&sqp->qc_lock, iflags);
                if (scsi_result)
                        goto respond_in_thread;
-               else if (SDEBUG_OPT_ALL_TSF & sdebug_opts)
-                       scsi_result = device_qfull_result;
+               scsi_result = device_qfull_result;
                if (SDEBUG_OPT_Q_NOISE & sdebug_opts)
-                       sdev_printk(KERN_INFO, sdp,
-                                   "%s: max_queue=%d exceeded, %s\n",
-                                   __func__, sdebug_max_queue,
-                                   (scsi_result ?  "status: TASK SET FULL" :
-                                                   "report: host busy"));
-               if (scsi_result)
-                       goto respond_in_thread;
-               else
-                       return SCSI_MLQUEUE_HOST_BUSY;
+                       sdev_printk(KERN_INFO, sdp, "%s: max_queue=%d exceeded: TASK SET FULL\n",
+                                   __func__, sdebug_max_queue);
+               goto respond_in_thread;
        }
        set_bit(k, sqp->in_use_bm);
        atomic_inc(&devip->num_in_q);