All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] scsi_debug: randomize command duration option + %p
@ 2019-09-27  1:48 Douglas Gilbert
  2019-09-27  5:31 ` kbuild test robot
  2019-09-27  6:10 ` kbuild test robot
  0 siblings, 2 replies; 3+ messages in thread
From: Douglas Gilbert @ 2019-09-27  1:48 UTC (permalink / raw)
  To: linux-scsi; +Cc: martin.petersen, hare, bvanassche

Add an option to use the given command delay (in nanoseconds)
as the upper limit for command durations. A pseudo random
number generator chooses a duration in the range:
      [0..delay_in_ns)

Main benefit: allows testing with out-of-order responses.

Change the only %p (print a kernel pointer) in the driver
to %pK as the former seems to have no usefulness in recent
kernels.

---

The new %p would be more useful if it didn't randomize NULL
pointers and gave an indicative output for ERR_PTR(-ENOENT)
type pointers. Hard to imagine how that will help the black
hats. Probably all printk()s in the SCSI subsystem should be
changed to %pK or some variant of that.

Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
---
 drivers/scsi/scsi_debug.c | 43 +++++++++++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index d323523f5f9d..6e48ff80def9 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -38,6 +38,7 @@
 #include <linux/hrtimer.h>
 #include <linux/uuid.h>
 #include <linux/t10-pi.h>
+#include <linux/random.h>
 
 #include <net/checksum.h>
 
@@ -125,6 +126,7 @@ static const char *sdebug_version_date = "20190125";
 #define DEF_PHYSBLK_EXP 0
 #define DEF_OPT_XFERLEN_EXP 0
 #define DEF_PTYPE   TYPE_DISK
+#define DEF_RANDOM false
 #define DEF_REMOVABLE false
 #define DEF_SCSI_LEVEL   7    /* INQUIRY, byte2 [6->SPC-4; 7->SPC-5] */
 #define DEF_SECTOR_SIZE 512
@@ -655,6 +657,7 @@ static unsigned int sdebug_unmap_max_blocks = DEF_UNMAP_MAX_BLOCKS;
 static unsigned int sdebug_unmap_max_desc = DEF_UNMAP_MAX_DESC;
 static unsigned int sdebug_write_same_length = DEF_WRITESAME_LENGTH;
 static int sdebug_uuid_ctl = DEF_UUID_CTL;
+static bool sdebug_random = DEF_RANDOM;
 static bool sdebug_removable = DEF_REMOVABLE;
 static bool sdebug_clustering;
 static bool sdebug_host_lock = DEF_HOST_LOCK;
@@ -4354,9 +4357,21 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 		ktime_t kt;
 
 		if (delta_jiff > 0) {
-			kt = ns_to_ktime((u64)delta_jiff * (NSEC_PER_SEC / HZ));
-		} else
-			kt = ndelay;
+			u64 ns = (u64)delta_jiff * (NSEC_PER_SEC / HZ);
+
+			if (sdebug_random && ns < U32_MAX) {
+				ns = prandom_u32_max((u32)ns);
+			} else if (sdebug_random) {
+				ns /= 1000;
+				if (ns < U32_MAX)  /* an hour and a bit */
+					ns = prandom_u32_max((u32)ns);
+				ns *= 1000;
+			}
+			kt = ns_to_ktime(ns);
+		} else {
+			kt = sdebug_random ? prandom_u32_max((u32)ndelay) :
+					     (u32)ndelay;
+		}
 		if (!sd_dp->init_hrt) {
 			sd_dp->init_hrt = true;
 			sqcp->sd_dp = sd_dp;
@@ -4451,6 +4466,7 @@ module_param_named(opts, sdebug_opts, int, S_IRUGO | S_IWUSR);
 module_param_named(physblk_exp, sdebug_physblk_exp, int, S_IRUGO);
 module_param_named(opt_xferlen_exp, sdebug_opt_xferlen_exp, int, S_IRUGO);
 module_param_named(ptype, sdebug_ptype, int, S_IRUGO | S_IWUSR);
+module_param_named(random, sdebug_random, bool, S_IRUGO | S_IWUSR);
 module_param_named(removable, sdebug_removable, bool, S_IRUGO | S_IWUSR);
 module_param_named(scsi_level, sdebug_scsi_level, int, S_IRUGO);
 module_param_named(sector_size, sdebug_sector_size, int, S_IRUGO);
@@ -4511,6 +4527,7 @@ MODULE_PARM_DESC(opts, "1->noise, 2->medium_err, 4->timeout, 8->recovered_err...
 MODULE_PARM_DESC(physblk_exp, "physical block exponent (def=0)");
 MODULE_PARM_DESC(opt_xferlen_exp, "optimal transfer length granularity exponent (def=physblk_exp)");
 MODULE_PARM_DESC(ptype, "SCSI peripheral type(def=0[disk])");
+MODULE_PARM_DESC(random, "1-> command duration chosen from [0..delay_in_ns) (def=0)");
 MODULE_PARM_DESC(removable, "claim to have removable media (def=0)");
 MODULE_PARM_DESC(scsi_level, "SCSI level to simulate(def=7[SPC-5])");
 MODULE_PARM_DESC(sector_size, "logical block size in bytes (def=512)");
@@ -5101,6 +5118,23 @@ static ssize_t map_show(struct device_driver *ddp, char *buf)
 }
 static DRIVER_ATTR_RO(map);
 
+static ssize_t random_show(struct device_driver *ddp, char *buf)
+{
+	return scnprintf(buf, PAGE_SIZE, "%d\n", sdebug_random ? 1 : 0);
+}
+static ssize_t random_store(struct device_driver *ddp, const char *buf,
+			    size_t count)
+{
+	int n;
+
+	if (count > 0 && 1 == sscanf(buf, "%d", &n) && n >= 0) {
+		sdebug_random = (n > 0);
+		return count;
+	}
+	return -EINVAL;
+}
+static DRIVER_ATTR_RW(random);
+
 static ssize_t removable_show(struct device_driver *ddp, char *buf)
 {
 	return scnprintf(buf, PAGE_SIZE, "%d\n", sdebug_removable ? 1 : 0);
@@ -5211,6 +5245,7 @@ static struct attribute *sdebug_drv_attrs[] = {
 	&driver_attr_guard.attr,
 	&driver_attr_ato.attr,
 	&driver_attr_map.attr,
+	&driver_attr_random.attr,
 	&driver_attr_removable.attr,
 	&driver_attr_host_lock.attr,
 	&driver_attr_ndelay.attr,
@@ -5338,7 +5373,7 @@ static int __init scsi_debug_init(void)
 		dif_size = sdebug_store_sectors * sizeof(struct t10_pi_tuple);
 		dif_storep = vmalloc(dif_size);
 
-		pr_err("dif_storep %u bytes @ %p\n", dif_size, dif_storep);
+		pr_err("dif_storep %u bytes @ %pK\n", dif_size, dif_storep);
 
 		if (dif_storep == NULL) {
 			pr_err("out of mem. (DIX)\n");
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/1] scsi_debug: randomize command duration option + %p
  2019-09-27  1:48 [PATCH 1/1] scsi_debug: randomize command duration option + %p Douglas Gilbert
@ 2019-09-27  5:31 ` kbuild test robot
  2019-09-27  6:10 ` kbuild test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kbuild test robot @ 2019-09-27  5:31 UTC (permalink / raw)
  To: Douglas Gilbert; +Cc: kbuild-all, linux-scsi, martin.petersen, hare, bvanassche

[-- Attachment #1: Type: text/plain, Size: 1197 bytes --]

Hi Douglas,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on scsi/for-next]
[cannot apply to v5.3 next-20190925]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Douglas-Gilbert/scsi_debug-randomize-command-duration-option-p/20190927-094954
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
config: i386-randconfig-e003-201938 (attached as .config)
compiler: gcc-7 (Debian 7.4.0-13) 7.4.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

>> ERROR: "__divdi3" [drivers/scsi/scsi_debug.ko] undefined!
>> ERROR: "__udivdi3" [drivers/scsi/scsi_debug.ko] undefined!

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 29755 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH 1/1] scsi_debug: randomize command duration option + %p
  2019-09-27  1:48 [PATCH 1/1] scsi_debug: randomize command duration option + %p Douglas Gilbert
  2019-09-27  5:31 ` kbuild test robot
@ 2019-09-27  6:10 ` kbuild test robot
  1 sibling, 0 replies; 3+ messages in thread
From: kbuild test robot @ 2019-09-27  6:10 UTC (permalink / raw)
  To: Douglas Gilbert; +Cc: kbuild-all, linux-scsi, martin.petersen, hare, bvanassche

[-- Attachment #1: Type: text/plain, Size: 7397 bytes --]

Hi Douglas,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on scsi/for-next]
[cannot apply to v5.3 next-20190925]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Douglas-Gilbert/scsi_debug-randomize-command-duration-option-p/20190927-094954
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
config: i386-randconfig-f004-201938 (attached as .config)
compiler: gcc-7 (Debian 7.4.0-13) 7.4.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   ld: drivers/scsi/scsi_debug.o: in function `schedule_resp':
>> drivers/scsi/scsi_debug.c:4365: undefined reference to `__udivdi3'

vim +4365 drivers/scsi/scsi_debug.c

  4251	
  4252	/* Complete the processing of the thread that queued a SCSI command to this
  4253	 * driver. It either completes the command by calling cmnd_done() or
  4254	 * schedules a hr timer or work queue then returns 0. Returns
  4255	 * SCSI_MLQUEUE_HOST_BUSY if temporarily out of resources.
  4256	 */
  4257	static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
  4258				 int scsi_result,
  4259				 int (*pfp)(struct scsi_cmnd *,
  4260					    struct sdebug_dev_info *),
  4261				 int delta_jiff, int ndelay)
  4262	{
  4263		unsigned long iflags;
  4264		int k, num_in_q, qdepth, inject;
  4265		struct sdebug_queue *sqp;
  4266		struct sdebug_queued_cmd *sqcp;
  4267		struct scsi_device *sdp;
  4268		struct sdebug_defer *sd_dp;
  4269	
  4270		if (unlikely(devip == NULL)) {
  4271			if (scsi_result == 0)
  4272				scsi_result = DID_NO_CONNECT << 16;
  4273			goto respond_in_thread;
  4274		}
  4275		sdp = cmnd->device;
  4276	
  4277		if (delta_jiff == 0)
  4278			goto respond_in_thread;
  4279	
  4280		/* schedule the response at a later time if resources permit */
  4281		sqp = get_queue(cmnd);
  4282		spin_lock_irqsave(&sqp->qc_lock, iflags);
  4283		if (unlikely(atomic_read(&sqp->blocked))) {
  4284			spin_unlock_irqrestore(&sqp->qc_lock, iflags);
  4285			return SCSI_MLQUEUE_HOST_BUSY;
  4286		}
  4287		num_in_q = atomic_read(&devip->num_in_q);
  4288		qdepth = cmnd->device->queue_depth;
  4289		inject = 0;
  4290		if (unlikely((qdepth > 0) && (num_in_q >= qdepth))) {
  4291			if (scsi_result) {
  4292				spin_unlock_irqrestore(&sqp->qc_lock, iflags);
  4293				goto respond_in_thread;
  4294			} else
  4295				scsi_result = device_qfull_result;
  4296		} else if (unlikely(sdebug_every_nth &&
  4297				    (SDEBUG_OPT_RARE_TSF & sdebug_opts) &&
  4298				    (scsi_result == 0))) {
  4299			if ((num_in_q == (qdepth - 1)) &&
  4300			    (atomic_inc_return(&sdebug_a_tsf) >=
  4301			     abs(sdebug_every_nth))) {
  4302				atomic_set(&sdebug_a_tsf, 0);
  4303				inject = 1;
  4304				scsi_result = device_qfull_result;
  4305			}
  4306		}
  4307	
  4308		k = find_first_zero_bit(sqp->in_use_bm, sdebug_max_queue);
  4309		if (unlikely(k >= sdebug_max_queue)) {
  4310			spin_unlock_irqrestore(&sqp->qc_lock, iflags);
  4311			if (scsi_result)
  4312				goto respond_in_thread;
  4313			else if (SDEBUG_OPT_ALL_TSF & sdebug_opts)
  4314				scsi_result = device_qfull_result;
  4315			if (SDEBUG_OPT_Q_NOISE & sdebug_opts)
  4316				sdev_printk(KERN_INFO, sdp,
  4317					    "%s: max_queue=%d exceeded, %s\n",
  4318					    __func__, sdebug_max_queue,
  4319					    (scsi_result ?  "status: TASK SET FULL" :
  4320							    "report: host busy"));
  4321			if (scsi_result)
  4322				goto respond_in_thread;
  4323			else
  4324				return SCSI_MLQUEUE_HOST_BUSY;
  4325		}
  4326		__set_bit(k, sqp->in_use_bm);
  4327		atomic_inc(&devip->num_in_q);
  4328		sqcp = &sqp->qc_arr[k];
  4329		sqcp->a_cmnd = cmnd;
  4330		cmnd->host_scribble = (unsigned char *)sqcp;
  4331		sd_dp = sqcp->sd_dp;
  4332		spin_unlock_irqrestore(&sqp->qc_lock, iflags);
  4333		if (unlikely(sdebug_every_nth && sdebug_any_injecting_opt))
  4334			setup_inject(sqp, sqcp);
  4335		if (sd_dp == NULL) {
  4336			sd_dp = kzalloc(sizeof(*sd_dp), GFP_ATOMIC);
  4337			if (sd_dp == NULL)
  4338				return SCSI_MLQUEUE_HOST_BUSY;
  4339		}
  4340	
  4341		cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0;
  4342		if (cmnd->result & SDEG_RES_IMMED_MASK) {
  4343			/*
  4344			 * This is the F_DELAY_OVERR case. No delay.
  4345			 */
  4346			cmnd->result &= ~SDEG_RES_IMMED_MASK;
  4347			delta_jiff = ndelay = 0;
  4348		}
  4349		if (cmnd->result == 0 && scsi_result != 0)
  4350			cmnd->result = scsi_result;
  4351	
  4352		if (unlikely(sdebug_verbose && cmnd->result))
  4353			sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n",
  4354				    __func__, cmnd->result);
  4355	
  4356		if (delta_jiff > 0 || ndelay > 0) {
  4357			ktime_t kt;
  4358	
  4359			if (delta_jiff > 0) {
  4360				u64 ns = (u64)delta_jiff * (NSEC_PER_SEC / HZ);
  4361	
  4362				if (sdebug_random && ns < U32_MAX) {
  4363					ns = prandom_u32_max((u32)ns);
  4364				} else if (sdebug_random) {
> 4365					ns /= 1000;
  4366					if (ns < U32_MAX)  /* an hour and a bit */
  4367						ns = prandom_u32_max((u32)ns);
  4368					ns *= 1000;
  4369				}
  4370				kt = ns_to_ktime(ns);
  4371			} else {
  4372				kt = sdebug_random ? prandom_u32_max((u32)ndelay) :
  4373						     (u32)ndelay;
  4374			}
  4375			if (!sd_dp->init_hrt) {
  4376				sd_dp->init_hrt = true;
  4377				sqcp->sd_dp = sd_dp;
  4378				hrtimer_init(&sd_dp->hrt, CLOCK_MONOTONIC,
  4379					     HRTIMER_MODE_REL_PINNED);
  4380				sd_dp->hrt.function = sdebug_q_cmd_hrt_complete;
  4381				sd_dp->sqa_idx = sqp - sdebug_q_arr;
  4382				sd_dp->qc_idx = k;
  4383			}
  4384			if (sdebug_statistics)
  4385				sd_dp->issuing_cpu = raw_smp_processor_id();
  4386			sd_dp->defer_t = SDEB_DEFER_HRT;
  4387			hrtimer_start(&sd_dp->hrt, kt, HRTIMER_MODE_REL_PINNED);
  4388		} else {	/* jdelay < 0, use work queue */
  4389			if (!sd_dp->init_wq) {
  4390				sd_dp->init_wq = true;
  4391				sqcp->sd_dp = sd_dp;
  4392				sd_dp->sqa_idx = sqp - sdebug_q_arr;
  4393				sd_dp->qc_idx = k;
  4394				INIT_WORK(&sd_dp->ew.work, sdebug_q_cmd_wq_complete);
  4395			}
  4396			if (sdebug_statistics)
  4397				sd_dp->issuing_cpu = raw_smp_processor_id();
  4398			sd_dp->defer_t = SDEB_DEFER_WQ;
  4399			if (unlikely(sqcp->inj_cmd_abort))
  4400				sd_dp->aborted = true;
  4401			schedule_work(&sd_dp->ew.work);
  4402			if (unlikely(sqcp->inj_cmd_abort)) {
  4403				sdev_printk(KERN_INFO, sdp, "abort request tag %d\n",
  4404					    cmnd->request->tag);
  4405				blk_abort_request(cmnd->request);
  4406			}
  4407		}
  4408		if (unlikely((SDEBUG_OPT_Q_NOISE & sdebug_opts) &&
  4409			     (scsi_result == device_qfull_result)))
  4410			sdev_printk(KERN_INFO, sdp,
  4411				    "%s: num_in_q=%d +1, %s%s\n", __func__,
  4412				    num_in_q, (inject ? "<inject> " : ""),
  4413				    "status: TASK SET FULL");
  4414		return 0;
  4415	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 30878 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-09-27  6:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-09-27  1:48 [PATCH 1/1] scsi_debug: randomize command duration option + %p Douglas Gilbert
2019-09-27  5:31 ` kbuild test robot
2019-09-27  6:10 ` kbuild test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.