All of lore.kernel.org
 help / color / mirror / Atom feed
From: Douglas Gilbert <dgilbert@interlog.com>
To: linux-scsi@vger.kernel.org
Cc: martin.petersen@oracle.com, jejb@linux.vnet.ibm.com,
	hare@suse.de, Damien.LeMoal@wdc.com
Subject: [PATCH v4 05/14] scsi_debug: improve command duration calculation
Date: Tue, 25 Feb 2020 01:23:42 -0500	[thread overview]
Message-ID: <20200225062351.21267-6-dgilbert@interlog.com> (raw)
In-Reply-To: <20200225062351.21267-1-dgilbert@interlog.com>

Previously the code did the work implied by the given SCSI
command and after that it waited for a timer based on the user
specified command duration to be exhausted before informing
the mid-level that the command was complete. For short command
durations the time to complete the work implied by the SCSI
command could be significant compared to the user specified
command duration.

For example a WRITE of 128 blocks (say 512 bytes each) on a
machine that can copy from main memory to main memory at a rate
of 10 GB/sec will take around 6.4 microseconds to do that copy.
If the user specified a command duration of 5 microseconds
(ndelay=5000) should the driver do a further delay of 5
microseconds after the copy or return immediately because
6.4 > 5 ?

The action prior to this patch was to always do the timer based
delay. After this patch, for ndelay values less than 1
millisecond, this driver will complete the command immediately.
And in the case where the user specified delay was 7
microseconds, a timer delay of 600 nanoseconds will be set
((7 - 6.4) * 1000).

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

diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index c6b0a7d021cd..6193a88f9e24 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -4366,6 +4366,8 @@ static void setup_inject(struct sdebug_queue *sqp,
 	sqcp->inj_cmd_abort = !!(SDEBUG_OPT_CMD_ABORT & sdebug_opts);
 }
 
+#define INCLUSIVE_TIMING_MAX_NS 1000000		/* 1 millisecond */
+
 /* Complete the processing of the thread that queued a SCSI command to this
  * driver. It either completes the command by calling cmnd_done() or
  * schedules a hr timer or work queue then returns 0. Returns
@@ -4377,8 +4379,10 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 				    struct sdebug_dev_info *),
 			 int delta_jiff, int ndelay)
 {
-	unsigned long iflags;
+	bool new_sd_dp;
 	int k, num_in_q, qdepth, inject;
+	unsigned long iflags;
+	u64 ns_from_boot = 0;
 	struct sdebug_queue *sqp;
 	struct sdebug_queued_cmd *sqcp;
 	struct scsi_device *sdp;
@@ -4394,7 +4398,6 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 	if (delta_jiff == 0)
 		goto respond_in_thread;
 
-	/* schedule the response at a later time if resources permit */
 	sqp = get_queue(cmnd);
 	spin_lock_irqsave(&sqp->qc_lock, iflags);
 	if (unlikely(atomic_read(&sqp->blocked))) {
@@ -4453,8 +4456,15 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 		sd_dp = kzalloc(sizeof(*sd_dp), GFP_ATOMIC);
 		if (sd_dp == NULL)
 			return SCSI_MLQUEUE_HOST_BUSY;
+		new_sd_dp = true;
+	} else {
+		new_sd_dp = false;
 	}
 
+	if (ndelay > 0 && ndelay < INCLUSIVE_TIMING_MAX_NS)
+		ns_from_boot = ktime_get_boottime_ns();
+
+	/* one of the resp_*() response functions is called here */
 	cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0;
 	if (cmnd->result & SDEG_RES_IMMED_MASK) {
 		cmnd->result &= ~SDEG_RES_IMMED_MASK;
@@ -4485,6 +4495,22 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 		} else {	/* ndelay has a 4.2 second max */
 			kt = sdebug_random ? prandom_u32_max((u32)ndelay) :
 					     (u32)ndelay;
+			if (ndelay < INCLUSIVE_TIMING_MAX_NS) {
+				u64 d = ktime_get_boottime_ns() - ns_from_boot;
+
+				if (kt <= d) {	/* elapsed duration >= kt */
+					sqcp->a_cmnd = NULL;
+					atomic_dec(&devip->num_in_q);
+					clear_bit(k, sqp->in_use_bm);
+					if (new_sd_dp)
+						kfree(sd_dp);
+					/* call scsi_done() from this thread */
+					cmnd->scsi_done(cmnd);
+					return 0;
+				}
+				/* otherwise reduce kt by elapsed time */
+				kt -= d;
+			}
 		}
 		if (!sd_dp->init_hrt) {
 			sd_dp->init_hrt = true;
@@ -4498,6 +4524,7 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip,
 		if (sdebug_statistics)
 			sd_dp->issuing_cpu = raw_smp_processor_id();
 		sd_dp->defer_t = SDEB_DEFER_HRT;
+		/* schedule the invocation of scsi_done() for a later time */
 		hrtimer_start(&sd_dp->hrt, kt, HRTIMER_MODE_REL_PINNED);
 	} else {	/* jdelay < 0, use work queue */
 		if (!sd_dp->init_wq) {
-- 
2.25.1


  parent reply	other threads:[~2020-02-25  6:24 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-25  6:23 [PATCH v4 00/14] scsi_debug: host managed ZBC + doublestore Douglas Gilbert
2020-02-25  6:23 ` [PATCH v4 01/14] scsi_debug: randomize command completion time Douglas Gilbert
2020-04-13 22:24   ` Martin K. Petersen
2020-02-25  6:23 ` [PATCH v4 02/14] scsi_debug: add doublestore option Douglas Gilbert
2020-04-13 22:36   ` Martin K. Petersen
2020-02-25  6:23 ` [PATCH v4 03/14] scsi_debug: implement verify(10), add verify(16) Douglas Gilbert
2020-04-13 22:48   ` Martin K. Petersen
2020-02-25  6:23 ` [PATCH v4 04/14] scsi_debug: weaken rwlock around ramdisk access Douglas Gilbert
2020-02-25  6:23 ` Douglas Gilbert [this message]
2020-04-13 22:50   ` [PATCH v4 05/14] scsi_debug: improve command duration calculation Martin K. Petersen
2020-02-25  6:23 ` [PATCH v4 06/14] scsi_debug: implement pre-fetch commands Douglas Gilbert
2020-04-13 22:57   ` Martin K. Petersen
2020-04-19 18:01     ` Douglas Gilbert
2020-04-19 18:22       ` Julian Wiedmann
2020-04-19 21:53         ` Douglas Gilbert
2020-02-25  6:23 ` [PATCH v4 07/14] scsi_debug: expand zbc support Douglas Gilbert
2020-04-13 23:00   ` Martin K. Petersen
2020-04-13 23:05     ` Damien Le Moal
2020-04-13 23:06       ` Damien Le Moal
2020-04-14  1:55         ` Martin K. Petersen
2020-04-14  5:38           ` Damien Le Moal
2020-02-25  6:23 ` [PATCH v4 08/14] scsi_debug: add zone commands Douglas Gilbert
2020-02-25  6:23 ` [PATCH v4 09/14] scsi_debug: add zbc parameter Douglas Gilbert
2020-04-15  2:10   ` Martin K. Petersen
2020-02-25  6:23 ` [PATCH v4 10/14] scsi_debug: re-arrange parameters alphabetically Douglas Gilbert
2020-02-25  6:23 ` [PATCH v4 11/14] scsi_debug: zone_max_open module parameter Douglas Gilbert
2020-02-25  6:23 ` [PATCH v4 12/14] scsi_debug: zone_nr_conv " Douglas Gilbert
2020-02-25  6:23 ` [PATCH v4 13/14] scsi_debug: zone_size_mb " Douglas Gilbert
2020-02-25  6:23 ` [PATCH v4 14/14] scsi_debug: bump to version 1.89 Douglas Gilbert
2020-04-13 23:19 ` [PATCH v4 00/14] scsi_debug: host managed ZBC + doublestore Martin K. Petersen
2020-04-14  2:49   ` Douglas Gilbert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200225062351.21267-6-dgilbert@interlog.com \
    --to=dgilbert@interlog.com \
    --cc=Damien.LeMoal@wdc.com \
    --cc=hare@suse.de \
    --cc=jejb@linux.vnet.ibm.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.