Message ID | 20201014122734.201426-1-kashyap.desai@broadcom.com |
---|---|
State | New |
Headers | show |
Series | [1/3] add io_uring with IOPOLL support in scsi layer | expand |
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
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
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))
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(+)