* [PATCH 3/3] scsi_debug: iouring iopoll support
@ 2020-10-14 12:27 Kashyap Desai
2020-10-14 16:39 ` kernel test robot
2020-10-14 18:16 ` kernel test robot
0 siblings, 2 replies; 3+ messages in thread
From: Kashyap Desai @ 2020-10-14 12:27 UTC (permalink / raw)
To: linux-scsi; +Cc: Kashyap Desai, dgilbert, linux-block
[-- Attachment #1: Type: text/plain, Size: 6348 bytes --]
Add support of iouring iopoll interface in scsi_debug.
This feature requires shared hosttag support in kernel and driver.
Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Cc: dgilbert@interlog.com
Cc: linux-block@vger.kernel.org
---
drivers/scsi/scsi_debug.c | 123 ++++++++++++++++++++++++++++++++++++++
1 file changed, 123 insertions(+)
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index a87e40aec11f..4e441aaa60db 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -826,6 +826,7 @@ static int sdeb_zbc_max_open = DEF_ZBC_MAX_OPEN_ZONES;
static int sdeb_zbc_nr_conv = DEF_ZBC_NR_CONV_ZONES;
static int submit_queues = DEF_SUBMIT_QUEUES; /* > 1 for multi-queue (mq) */
+static int poll_queues; /* iouring iopoll interface.*/
static struct sdebug_queue *sdebug_q_arr; /* ptr to array of submit queues */
static DEFINE_RWLOCK(atomic_rw);
@@ -5422,6 +5423,14 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
cmnd->host_scribble = (unsigned char *)sqcp;
sd_dp = sqcp->sd_dp;
spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+
+ /* Do not complete IO from default completion path.
+ * Let it to be on queue.
+ * Completion should happen from mq_poll interface.
+ */
+ if ((sqp - sdebug_q_arr) >= (submit_queues - poll_queues))
+ return;
+
if (!sd_dp) {
sd_dp = kzalloc(sizeof(*sd_dp), GFP_ATOMIC);
if (!sd_dp) {
@@ -5604,6 +5613,7 @@ module_param_named(sector_size, sdebug_sector_size, int, S_IRUGO);
module_param_named(statistics, sdebug_statistics, bool, S_IRUGO | S_IWUSR);
module_param_named(strict, sdebug_strict, bool, S_IRUGO | S_IWUSR);
module_param_named(submit_queues, submit_queues, int, S_IRUGO);
+module_param_named(poll_queues, poll_queues, int, S_IRUGO);
module_param_named(tur_ms_to_ready, sdeb_tur_ms_to_ready, int, S_IRUGO);
module_param_named(unmap_alignment, sdebug_unmap_alignment, int, S_IRUGO);
module_param_named(unmap_granularity, sdebug_unmap_granularity, int, S_IRUGO);
@@ -5673,6 +5683,7 @@ MODULE_PARM_DESC(sector_size, "logical block size in bytes (def=512)");
MODULE_PARM_DESC(statistics, "collect statistics on commands, queues (def=0)");
MODULE_PARM_DESC(strict, "stricter checks: reserved field in cdb (def=0)");
MODULE_PARM_DESC(submit_queues, "support for block multi-queue (def=1)");
+MODULE_PARM_DESC(poll_queues, "support for iouring iopoll queues");
MODULE_PARM_DESC(tur_ms_to_ready, "TEST UNIT READY millisecs before initial good status (def=0)");
MODULE_PARM_DESC(unmap_alignment, "lowest aligned thin provisioning lba (def=0)");
MODULE_PARM_DESC(unmap_granularity, "thin provisioning granularity in blocks (def=1)");
@@ -7140,6 +7151,104 @@ static int resp_not_ready(struct scsi_cmnd *scp, struct sdebug_dev_info *devip)
return check_condition_result;
}
+static int sdebug_map_queues(struct Scsi_Host *shost)
+{
+ int i, qoff;
+
+ if (shost->nr_hw_queues == 1)
+ return 0;
+
+ for (i = 0, qoff = 0; i < HCTX_MAX_TYPES; i++) {
+ struct blk_mq_queue_map *map = &shost->tag_set.map[i];
+
+ map->nr_queues = 0;
+
+ if (i == HCTX_TYPE_DEFAULT)
+ map->nr_queues = submit_queues - poll_queues;
+ else if (i == HCTX_TYPE_POLL)
+ map->nr_queues = poll_queues;
+
+ if (!map->nr_queues) {
+ BUG_ON(i == HCTX_TYPE_DEFAULT);
+ continue;
+ }
+
+ map->queue_offset = qoff;
+ blk_mq_map_queues(map);
+
+ qoff += map->nr_queues;
+ }
+
+ return 0;
+
+}
+
+int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num)
+{
+ int qc_idx;
+ int retiring = 0;
+ unsigned long iflags;
+ struct sdebug_queue *sqp;
+ struct sdebug_queued_cmd *sqcp;
+ struct scsi_cmnd *scp;
+ struct sdebug_dev_info *devip;
+ int num_entries = 0;
+
+ sqp = sdebug_q_arr + queue_num;
+
+ do {
+ spin_lock_irqsave(&sqp->qc_lock, iflags);
+ qc_idx = find_first_bit(sqp->in_use_bm, sdebug_max_queue);
+ if (unlikely((qc_idx < 0) || (qc_idx >= SDEBUG_CANQUEUE)))
+ goto out;
+
+ sqcp = &sqp->qc_arr[qc_idx];
+ scp = sqcp->a_cmnd;
+ if (unlikely(scp == NULL)) {
+ pr_err("scp is NULL, queue_num=%d, qc_idx=%d from %s\n",
+ queue_num, qc_idx, __func__);
+ goto out;
+ }
+ devip = (struct sdebug_dev_info *)scp->device->hostdata;
+ if (likely(devip))
+ atomic_dec(&devip->num_in_q);
+ else
+ pr_err("devip=NULL from %s\n", __func__);
+ if (unlikely(atomic_read(&retired_max_queue) > 0))
+ retiring = 1;
+
+ sqcp->a_cmnd = NULL;
+ if (unlikely(!test_and_clear_bit(qc_idx, sqp->in_use_bm))) {
+ pr_err("Unexpected completion sqp %p queue_num=%d qc_idx=%d from %s\n",
+ sqp, queue_num, qc_idx, __func__);
+ goto out;
+ }
+
+ if (unlikely(retiring)) { /* user has reduced max_queue */
+ int k, retval;
+
+ retval = atomic_read(&retired_max_queue);
+ if (qc_idx >= retval) {
+ pr_err("index %d too large\n", retval);
+ goto out;
+ }
+ k = find_last_bit(sqp->in_use_bm, retval);
+ if ((k < sdebug_max_queue) || (k == retval))
+ atomic_set(&retired_max_queue, 0);
+ else
+ atomic_set(&retired_max_queue, k + 1);
+ }
+ spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+ scp->scsi_done(scp); /* callback to mid level */
+ num_entries++;
+ } while (1);
+
+out:
+ spin_unlock_irqrestore(&sqp->qc_lock, iflags);
+ return num_entries;
+}
+
+
static int scsi_debug_queuecommand(struct Scsi_Host *shost,
struct scsi_cmnd *scp)
{
@@ -7318,6 +7427,8 @@ static struct scsi_host_template sdebug_driver_template = {
.ioctl = scsi_debug_ioctl,
.queuecommand = scsi_debug_queuecommand,
.change_queue_depth = sdebug_change_qdepth,
+ .map_queues = sdebug_map_queues,
+ .mq_poll = sdebug_blk_mq_poll,
.eh_abort_handler = scsi_debug_abort,
.eh_device_reset_handler = scsi_debug_device_reset,
.eh_target_reset_handler = scsi_debug_target_reset,
@@ -7365,6 +7476,18 @@ static int sdebug_driver_probe(struct device *dev)
if (sdebug_host_max_queue)
hpnt->host_tagset = 1;
+ /* poll queues are possible for nr_hw_queues > 1 */
+ if (hpnt->nr_hw_queues == 1)
+ poll_queues = 0;
+
+ /* poll queues */
+ if (poll_queues >= submit_queues) {
+ pr_warn("%s: trim poll_queues to 1\n", my_name);
+ poll_queues = 1;
+ }
+ if (poll_queues)
+ hpnt->nr_maps = 3;
+
sdbg_host->shost = hpnt;
*((struct sdebug_host_info **)hpnt->hostdata) = sdbg_host;
if ((hpnt->this_id >= 0) && (sdebug_num_tgts > hpnt->this_id))
--
2.18.1
[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4169 bytes --]
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 3/3] scsi_debug: iouring iopoll support
2020-10-14 12:27 [PATCH 3/3] scsi_debug: iouring iopoll support Kashyap Desai
@ 2020-10-14 16:39 ` kernel test robot
2020-10-14 18:16 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2020-10-14 16:39 UTC (permalink / raw)
To: Kashyap Desai, linux-scsi
Cc: kbuild-all, clang-built-linux, Kashyap Desai, dgilbert, linux-block
[-- Attachment #1: Type: text/plain, Size: 10387 bytes --]
Hi Kashyap,
I love your patch! Perhaps something to improve:
[auto build test WARNING on next-20201013]
[cannot apply to scsi/for-next mkp-scsi/for-next v5.9 v5.9-rc8 v5.9-rc7 v5.9]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Kashyap-Desai/add-io_uring-with-IOPOLL-support-in-scsi-layer/20201014-202916
base: f2fb1afc57304f9dd68c20a08270e287470af2eb
config: powerpc64-randconfig-r006-20201014 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project e7fe3c6dfede8d5781bd000741c3dea7088307a4)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install powerpc64 cross compiling tool for clang build
# apt-get install binutils-powerpc64-linux-gnu
# https://github.com/0day-ci/linux/commit/a3173d0d1c2ca8a45007fa994f2641aa7262719c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Kashyap-Desai/add-io_uring-with-IOPOLL-support-in-scsi-layer/20201014-202916
git checkout a3173d0d1c2ca8a45007fa994f2641aa7262719c
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
In file included from drivers/scsi/scsi_debug.c:32:
In file included from include/linux/scatterlist.h:9:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:43:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(insb, (unsigned long p, void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:29:1: note: expanded from here
__do_insb
^
arch/powerpc/include/asm/io.h:541:56: note: expanded from macro '__do_insb'
#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from drivers/scsi/scsi_debug.c:32:
In file included from include/linux/scatterlist.h:9:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:45:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(insw, (unsigned long p, void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:31:1: note: expanded from here
__do_insw
^
arch/powerpc/include/asm/io.h:542:56: note: expanded from macro '__do_insw'
#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from drivers/scsi/scsi_debug.c:32:
In file included from include/linux/scatterlist.h:9:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:47:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:33:1: note: expanded from here
__do_insl
^
arch/powerpc/include/asm/io.h:543:56: note: expanded from macro '__do_insl'
#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from drivers/scsi/scsi_debug.c:32:
In file included from include/linux/scatterlist.h:9:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:49:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:35:1: note: expanded from here
__do_outsb
^
arch/powerpc/include/asm/io.h:544:58: note: expanded from macro '__do_outsb'
#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from drivers/scsi/scsi_debug.c:32:
In file included from include/linux/scatterlist.h:9:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:51:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:37:1: note: expanded from here
__do_outsw
^
arch/powerpc/include/asm/io.h:545:58: note: expanded from macro '__do_outsw'
#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
~~~~~~~~~~~~~~~~~~~~~^
In file included from drivers/scsi/scsi_debug.c:32:
In file included from include/linux/scatterlist.h:9:
In file included from arch/powerpc/include/asm/io.h:604:
arch/powerpc/include/asm/io-defs.h:53:1: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c),
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/io.h:601:3: note: expanded from macro 'DEF_PCI_AC_NORET'
__do_##name al; \
^~~~~~~~~~~~~~
<scratch space>:39:1: note: expanded from here
__do_outsl
^
arch/powerpc/include/asm/io.h:546:58: note: expanded from macro '__do_outsl'
#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
~~~~~~~~~~~~~~~~~~~~~^
drivers/scsi/scsi_debug.c:5442:3: error: non-void function 'schedule_resp' should return a value [-Wreturn-type]
return;
^
>> drivers/scsi/scsi_debug.c:7246:5: warning: no previous prototype for function 'sdebug_blk_mq_poll' [-Wmissing-prototypes]
int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num)
^
drivers/scsi/scsi_debug.c:7246:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num)
^
static
7 warnings and 1 error generated.
vim +/sdebug_blk_mq_poll +7246 drivers/scsi/scsi_debug.c
7245
> 7246 int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num)
7247 {
7248 int qc_idx;
7249 int retiring = 0;
7250 unsigned long iflags;
7251 struct sdebug_queue *sqp;
7252 struct sdebug_queued_cmd *sqcp;
7253 struct scsi_cmnd *scp;
7254 struct sdebug_dev_info *devip;
7255 int num_entries = 0;
7256
7257 sqp = sdebug_q_arr + queue_num;
7258
7259 do {
7260 spin_lock_irqsave(&sqp->qc_lock, iflags);
7261 qc_idx = find_first_bit(sqp->in_use_bm, sdebug_max_queue);
7262 if (unlikely((qc_idx < 0) || (qc_idx >= SDEBUG_CANQUEUE)))
7263 goto out;
7264
7265 sqcp = &sqp->qc_arr[qc_idx];
7266 scp = sqcp->a_cmnd;
7267 if (unlikely(scp == NULL)) {
7268 pr_err("scp is NULL, queue_num=%d, qc_idx=%d from %s\n",
7269 queue_num, qc_idx, __func__);
7270 goto out;
7271 }
7272 devip = (struct sdebug_dev_info *)scp->device->hostdata;
7273 if (likely(devip))
7274 atomic_dec(&devip->num_in_q);
7275 else
7276 pr_err("devip=NULL from %s\n", __func__);
7277 if (unlikely(atomic_read(&retired_max_queue) > 0))
7278 retiring = 1;
7279
7280 sqcp->a_cmnd = NULL;
7281 if (unlikely(!test_and_clear_bit(qc_idx, sqp->in_use_bm))) {
7282 pr_err("Unexpected completion sqp %p queue_num=%d qc_idx=%d from %s\n",
7283 sqp, queue_num, qc_idx, __func__);
7284 goto out;
7285 }
7286
7287 if (unlikely(retiring)) { /* user has reduced max_queue */
7288 int k, retval;
7289
7290 retval = atomic_read(&retired_max_queue);
7291 if (qc_idx >= retval) {
7292 pr_err("index %d too large\n", retval);
7293 goto out;
7294 }
7295 k = find_last_bit(sqp->in_use_bm, retval);
7296 if ((k < sdebug_max_queue) || (k == retval))
7297 atomic_set(&retired_max_queue, 0);
7298 else
7299 atomic_set(&retired_max_queue, k + 1);
7300 }
7301 spin_unlock_irqrestore(&sqp->qc_lock, iflags);
7302 scp->scsi_done(scp); /* callback to mid level */
7303 num_entries++;
7304 } while (1);
7305
7306 out:
7307 spin_unlock_irqrestore(&sqp->qc_lock, iflags);
7308 return num_entries;
7309 }
7310
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 28887 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH 3/3] scsi_debug: iouring iopoll support
2020-10-14 12:27 [PATCH 3/3] scsi_debug: iouring iopoll support Kashyap Desai
2020-10-14 16:39 ` kernel test robot
@ 2020-10-14 18:16 ` kernel test robot
1 sibling, 0 replies; 3+ messages in thread
From: kernel test robot @ 2020-10-14 18:16 UTC (permalink / raw)
To: Kashyap Desai, linux-scsi
Cc: kbuild-all, Kashyap Desai, dgilbert, linux-block
[-- Attachment #1: Type: text/plain, Size: 10194 bytes --]
Hi Kashyap,
I love your patch! Perhaps something to improve:
[auto build test WARNING on next-20201013]
[cannot apply to scsi/for-next mkp-scsi/for-next v5.9 v5.9-rc8 v5.9-rc7 v5.9]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Kashyap-Desai/add-io_uring-with-IOPOLL-support-in-scsi-layer/20201014-202916
base: f2fb1afc57304f9dd68c20a08270e287470af2eb
config: xtensa-allyesconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/a3173d0d1c2ca8a45007fa994f2641aa7262719c
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Kashyap-Desai/add-io_uring-with-IOPOLL-support-in-scsi-layer/20201014-202916
git checkout a3173d0d1c2ca8a45007fa994f2641aa7262719c
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=xtensa
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/scsi/scsi_debug.c: In function 'schedule_resp':
>> drivers/scsi/scsi_debug.c:5442:3: warning: 'return' with no value, in function returning non-void [-Wreturn-type]
5442 | return;
| ^~~~~~
drivers/scsi/scsi_debug.c:5359:12: note: declared here
5359 | static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
| ^~~~~~~~~~~~~
drivers/scsi/scsi_debug.c: At top level:
>> drivers/scsi/scsi_debug.c:7246:5: warning: no previous prototype for 'sdebug_blk_mq_poll' [-Wmissing-prototypes]
7246 | int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num)
| ^~~~~~~~~~~~~~~~~~
vim +/return +5442 drivers/scsi/scsi_debug.c
5353
5354 /* Complete the processing of the thread that queued a SCSI command to this
5355 * driver. It either completes the command by calling cmnd_done() or
5356 * schedules a hr timer or work queue then returns 0. Returns
5357 * SCSI_MLQUEUE_HOST_BUSY if temporarily out of resources.
5358 */
5359 static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
5360 int scsi_result,
5361 int (*pfp)(struct scsi_cmnd *,
5362 struct sdebug_dev_info *),
5363 int delta_jiff, int ndelay)
5364 {
5365 bool new_sd_dp;
5366 bool inject = false;
5367 int k, num_in_q, qdepth;
5368 unsigned long iflags;
5369 u64 ns_from_boot = 0;
5370 struct sdebug_queue *sqp;
5371 struct sdebug_queued_cmd *sqcp;
5372 struct scsi_device *sdp;
5373 struct sdebug_defer *sd_dp;
5374
5375 if (unlikely(devip == NULL)) {
5376 if (scsi_result == 0)
5377 scsi_result = DID_NO_CONNECT << 16;
5378 goto respond_in_thread;
5379 }
5380 sdp = cmnd->device;
5381
5382 if (delta_jiff == 0)
5383 goto respond_in_thread;
5384
5385 sqp = get_queue(cmnd);
5386 spin_lock_irqsave(&sqp->qc_lock, iflags);
5387 if (unlikely(atomic_read(&sqp->blocked))) {
5388 spin_unlock_irqrestore(&sqp->qc_lock, iflags);
5389 return SCSI_MLQUEUE_HOST_BUSY;
5390 }
5391 num_in_q = atomic_read(&devip->num_in_q);
5392 qdepth = cmnd->device->queue_depth;
5393 if (unlikely((qdepth > 0) && (num_in_q >= qdepth))) {
5394 if (scsi_result) {
5395 spin_unlock_irqrestore(&sqp->qc_lock, iflags);
5396 goto respond_in_thread;
5397 } else
5398 scsi_result = device_qfull_result;
5399 } else if (unlikely(sdebug_every_nth &&
5400 (SDEBUG_OPT_RARE_TSF & sdebug_opts) &&
5401 (scsi_result == 0))) {
5402 if ((num_in_q == (qdepth - 1)) &&
5403 (atomic_inc_return(&sdebug_a_tsf) >=
5404 abs(sdebug_every_nth))) {
5405 atomic_set(&sdebug_a_tsf, 0);
5406 inject = true;
5407 scsi_result = device_qfull_result;
5408 }
5409 }
5410
5411 k = find_first_zero_bit(sqp->in_use_bm, sdebug_max_queue);
5412 if (unlikely(k >= sdebug_max_queue)) {
5413 spin_unlock_irqrestore(&sqp->qc_lock, iflags);
5414 if (scsi_result)
5415 goto respond_in_thread;
5416 else if (SDEBUG_OPT_ALL_TSF & sdebug_opts)
5417 scsi_result = device_qfull_result;
5418 if (SDEBUG_OPT_Q_NOISE & sdebug_opts)
5419 sdev_printk(KERN_INFO, sdp,
5420 "%s: max_queue=%d exceeded, %s\n",
5421 __func__, sdebug_max_queue,
5422 (scsi_result ? "status: TASK SET FULL" :
5423 "report: host busy"));
5424 if (scsi_result)
5425 goto respond_in_thread;
5426 else
5427 return SCSI_MLQUEUE_HOST_BUSY;
5428 }
5429 set_bit(k, sqp->in_use_bm);
5430 atomic_inc(&devip->num_in_q);
5431 sqcp = &sqp->qc_arr[k];
5432 sqcp->a_cmnd = cmnd;
5433 cmnd->host_scribble = (unsigned char *)sqcp;
5434 sd_dp = sqcp->sd_dp;
5435 spin_unlock_irqrestore(&sqp->qc_lock, iflags);
5436
5437 /* Do not complete IO from default completion path.
5438 * Let it to be on queue.
5439 * Completion should happen from mq_poll interface.
5440 */
5441 if ((sqp - sdebug_q_arr) >= (submit_queues - poll_queues))
> 5442 return;
5443
5444 if (!sd_dp) {
5445 sd_dp = kzalloc(sizeof(*sd_dp), GFP_ATOMIC);
5446 if (!sd_dp) {
5447 atomic_dec(&devip->num_in_q);
5448 clear_bit(k, sqp->in_use_bm);
5449 return SCSI_MLQUEUE_HOST_BUSY;
5450 }
5451 new_sd_dp = true;
5452 } else {
5453 new_sd_dp = false;
5454 }
5455
5456 /* Set the hostwide tag */
5457 if (sdebug_host_max_queue)
5458 sd_dp->hc_idx = get_tag(cmnd);
5459
5460 if (ndelay > 0 && ndelay < INCLUSIVE_TIMING_MAX_NS)
5461 ns_from_boot = ktime_get_boottime_ns();
5462
5463 /* one of the resp_*() response functions is called here */
5464 cmnd->result = pfp ? pfp(cmnd, devip) : 0;
5465 if (cmnd->result & SDEG_RES_IMMED_MASK) {
5466 cmnd->result &= ~SDEG_RES_IMMED_MASK;
5467 delta_jiff = ndelay = 0;
5468 }
5469 if (cmnd->result == 0 && scsi_result != 0)
5470 cmnd->result = scsi_result;
5471 if (cmnd->result == 0 && unlikely(sdebug_opts & SDEBUG_OPT_TRANSPORT_ERR)) {
5472 if (atomic_read(&sdeb_inject_pending)) {
5473 mk_sense_buffer(cmnd, ABORTED_COMMAND, TRANSPORT_PROBLEM, ACK_NAK_TO);
5474 atomic_set(&sdeb_inject_pending, 0);
5475 cmnd->result = check_condition_result;
5476 }
5477 }
5478
5479 if (unlikely(sdebug_verbose && cmnd->result))
5480 sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
5481 __func__, cmnd->result);
5482
5483 if (delta_jiff > 0 || ndelay > 0) {
5484 ktime_t kt;
5485
5486 if (delta_jiff > 0) {
5487 u64 ns = jiffies_to_nsecs(delta_jiff);
5488
5489 if (sdebug_random && ns < U32_MAX) {
5490 ns = prandom_u32_max((u32)ns);
5491 } else if (sdebug_random) {
5492 ns >>= 12; /* scale to 4 usec precision */
5493 if (ns < U32_MAX) /* over 4 hours max */
5494 ns = prandom_u32_max((u32)ns);
5495 ns <<= 12;
5496 }
5497 kt = ns_to_ktime(ns);
5498 } else { /* ndelay has a 4.2 second max */
5499 kt = sdebug_random ? prandom_u32_max((u32)ndelay) :
5500 (u32)ndelay;
5501 if (ndelay < INCLUSIVE_TIMING_MAX_NS) {
5502 u64 d = ktime_get_boottime_ns() - ns_from_boot;
5503
5504 if (kt <= d) { /* elapsed duration >= kt */
5505 spin_lock_irqsave(&sqp->qc_lock, iflags);
5506 sqcp->a_cmnd = NULL;
5507 atomic_dec(&devip->num_in_q);
5508 clear_bit(k, sqp->in_use_bm);
5509 spin_unlock_irqrestore(&sqp->qc_lock, iflags);
5510 if (new_sd_dp)
5511 kfree(sd_dp);
5512 /* call scsi_done() from this thread */
5513 cmnd->scsi_done(cmnd);
5514 return 0;
5515 }
5516 /* otherwise reduce kt by elapsed time */
5517 kt -= d;
5518 }
5519 }
5520 if (!sd_dp->init_hrt) {
5521 sd_dp->init_hrt = true;
5522 sqcp->sd_dp = sd_dp;
5523 hrtimer_init(&sd_dp->hrt, CLOCK_MONOTONIC,
5524 HRTIMER_MODE_REL_PINNED);
5525 sd_dp->hrt.function = sdebug_q_cmd_hrt_complete;
5526 sd_dp->sqa_idx = sqp - sdebug_q_arr;
5527 sd_dp->qc_idx = k;
5528 }
5529 if (sdebug_statistics)
5530 sd_dp->issuing_cpu = raw_smp_processor_id();
5531 sd_dp->defer_t = SDEB_DEFER_HRT;
5532 /* schedule the invocation of scsi_done() for a later time */
5533 hrtimer_start(&sd_dp->hrt, kt, HRTIMER_MODE_REL_PINNED);
5534 } else { /* jdelay < 0, use work queue */
5535 if (!sd_dp->init_wq) {
5536 sd_dp->init_wq = true;
5537 sqcp->sd_dp = sd_dp;
5538 sd_dp->sqa_idx = sqp - sdebug_q_arr;
5539 sd_dp->qc_idx = k;
5540 INIT_WORK(&sd_dp->ew.work, sdebug_q_cmd_wq_complete);
5541 }
5542 if (sdebug_statistics)
5543 sd_dp->issuing_cpu = raw_smp_processor_id();
5544 sd_dp->defer_t = SDEB_DEFER_WQ;
5545 if (unlikely((sdebug_opts & SDEBUG_OPT_CMD_ABORT) &&
5546 atomic_read(&sdeb_inject_pending)))
5547 sd_dp->aborted = true;
5548 schedule_work(&sd_dp->ew.work);
5549 if (unlikely((sdebug_opts & SDEBUG_OPT_CMD_ABORT) &&
5550 atomic_read(&sdeb_inject_pending))) {
5551 sdev_printk(KERN_INFO, sdp, "abort request tag %d\n", cmnd->request->tag);
5552 blk_abort_request(cmnd->request);
5553 atomic_set(&sdeb_inject_pending, 0);
5554 }
5555 }
5556 if (unlikely((SDEBUG_OPT_Q_NOISE & sdebug_opts) && scsi_result == device_qfull_result))
5557 sdev_printk(KERN_INFO, sdp, "%s: num_in_q=%d +1, %s%s\n", __func__,
5558 num_in_q, (inject ? "<inject> " : ""), "status: TASK SET FULL");
5559 return 0;
5560
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 66137 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-10-14 18:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-14 12:27 [PATCH 3/3] scsi_debug: iouring iopoll support Kashyap Desai
2020-10-14 16:39 ` kernel test robot
2020-10-14 18:16 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).