From patchwork Fri Oct 19 06:24:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Douglas Gilbert X-Patchwork-Id: 10648755 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6721717D4 for ; Fri, 19 Oct 2018 06:25:17 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 58C0528ABF for ; Fri, 19 Oct 2018 06:25:17 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4D9FE28AC8; Fri, 19 Oct 2018 06:25:17 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B726E28ABF for ; Fri, 19 Oct 2018 06:25:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727033AbeJSO3y (ORCPT ); Fri, 19 Oct 2018 10:29:54 -0400 Received: from smtp.infotech.no ([82.134.31.41]:47409 "EHLO smtp.infotech.no" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727017AbeJSO3y (ORCPT ); Fri, 19 Oct 2018 10:29:54 -0400 Received: from localhost (localhost [127.0.0.1]) by smtp.infotech.no (Postfix) with ESMTP id 92483204196; Fri, 19 Oct 2018 08:25:14 +0200 (CEST) X-Virus-Scanned: by amavisd-new-2.6.6 (20110518) (Debian) at infotech.no Received: from smtp.infotech.no ([127.0.0.1]) by localhost (smtp.infotech.no [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ydmKRrCXTGhW; Fri, 19 Oct 2018 08:25:13 +0200 (CEST) Received: from xtwo70.bingwo.ca (host-45-58-195-233.dyn.295.ca [45.58.195.233]) by smtp.infotech.no (Postfix) with ESMTPA id 084F620424C; Fri, 19 Oct 2018 08:25:10 +0200 (CEST) From: Douglas Gilbert To: linux-scsi@vger.kernel.org Cc: martin.petersen@oracle.com, tonyb@cybernetics.com, hare@suse.de, bart.vanassche@wdc.com Subject: [PATCH 8/8] sg: user control for q_at_head or tail Date: Fri, 19 Oct 2018 02:24:56 -0400 Message-Id: <20181019062456.4690-9-dgilbert@interlog.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181019062456.4690-1-dgilbert@interlog.com> References: <20181019062456.4690-1-dgilbert@interlog.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a SG_SET_GET_EXTENDED ioctl control for whether commands will be queued_at_head or queued_at_tail by the block layer (together with the scsi mid-level). It has file scope. Signed-off-by: Douglas Gilbert --- The user can still override this setting on a per command basis with the SG_FLAG_Q_AT_HEAD and SG_FLAG_Q_AT_TAIL in the sg v3 and v4 structures. drivers/scsi/sg.c | 35 +++++++++++++++++++++++++++++++---- include/uapi/scsi/sg.h | 3 ++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 583846ebc5e0..258923aac50d 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -93,6 +93,10 @@ static int sg_proc_init(void); #define SG_DEF_TIME_UNIT SG_TIME_UNIT_MS #define SG_DEFAULT_TIMEOUT mult_frac(SG_DEFAULT_TIMEOUT_USER, HZ, USER_HZ) +#define SG_FD_Q_AT_TAIL true +#define SG_FD_Q_AT_HEAD false +#define SG_DEFAULT_Q_AT SG_FD_Q_AT_HEAD /* for backward compatibility */ + int sg_big_buff = SG_DEF_RESERVED_SIZE; /* N.B. This variable is readable and writeable via /proc/scsi/sg/def_reserved_size . Each time sg_open() is called a buffer @@ -185,6 +189,7 @@ struct sg_fd { /* holds the state of a file descriptor */ bool keep_orphan;/* false -> drop (def), true -> keep for read() */ bool mmap_called; /* false -> mmap() never called on this fd */ bool time_in_ns; /* report times in nanoseconds */ + bool q_at_tail; /* queue at tail if true, head when false */ u8 next_cmd_len; /* 0: automatic, >0: use on next write() */ struct sg_request *reserve_srp; /* allocate on open(), starts on fl */ struct fasync_struct *async_qp; /* used by asynchronous notification */ @@ -894,9 +899,13 @@ sg_common_write(struct sg_fd *sfp, const struct sg_io_hdr *hi_p, srp->start_ts = ktime_get_with_offset(TK_OFFS_BOOT); else hp->duration = jiffies_to_msecs(jiffies); - /* at tail if v3 or later interface and tail flag set */ - at_head = !(hp->interface_id != '\0' && - (SG_FLAG_Q_AT_TAIL & hp->flags)); + + if (hp->interface_id == '\0') /* v1 and v2 interface */ + at_head = true; /* backward compatibility */ + else if (sfp->q_at_tail) /* cmd flags can override sfd setting */ + at_head = (SG_FLAG_Q_AT_HEAD & hp->flags); + else /* this sfd is defaulting to head */ + at_head = !(SG_FLAG_Q_AT_TAIL & hp->flags); srp->rq->timeout = timeout; kref_get(&sfp->f_ref); /* sg_rq_end_io() does kref_put(). */ @@ -1186,8 +1195,10 @@ sg_set_get_extended(struct sg_fd *sfp, void __user *p) } SG_LOG(3, sdp, "%s: wr_mask=0x%x rd_mask=0x%x\n", __func__, seip->valid_wr_mask, seip->valid_rd_mask); + /* reserved_sz (u32), read-write */ if (or_masks & SG_SEIM_RESERVED_SIZE) result = sg_reserved_sz(sfp, seip); + /* rq_rem_sgat_threshold (u32), read-write [impacts re-use only] */ if (or_masks & SG_SEIM_RQ_REM_THRESH) { if (seip->valid_wr_mask & SG_SEIM_RQ_REM_THRESH) { uv = seip->rq_rem_sgat_thresh; @@ -1198,6 +1209,7 @@ sg_set_get_extended(struct sg_fd *sfp, void __user *p) if (seip->valid_rd_mask & SG_SEIM_RQ_REM_THRESH) seip->rq_rem_sgat_thresh = sfp->rem_sgat_thresh; } + /* tot_fd_thresh (u32), read-write [sum of active cmd dlen_s] */ if (or_masks & SG_SEIM_TOT_FD_THRESH) { if (seip->valid_wr_mask & SG_SEIM_TOT_FD_THRESH) { uv = seip->tot_fd_thresh; @@ -1208,8 +1220,9 @@ sg_set_get_extended(struct sg_fd *sfp, void __user *p) if (seip->valid_rd_mask & SG_SEIM_TOT_FD_THRESH) seip->tot_fd_thresh = sfp->tot_fd_thresh; } + /* check all boolean flags if either wr or rd mask set in or_mask */ if (or_masks & SG_SEIM_CTL_FLAGS) { - /* don't care whether wr or rd mask set in or_mask */ + /* TIME_IN_NS boolean, read-write */ if (seip->ctl_flags_wr_mask & SG_CTL_FLAGM_TIME_IN_NS) sfp->time_in_ns = !!(seip->ctl_flags & SG_CTL_FLAGM_TIME_IN_NS); @@ -1219,19 +1232,32 @@ sg_set_get_extended(struct sg_fd *sfp, void __user *p) else seip->ctl_flags &= ~SG_CTL_FLAGM_TIME_IN_NS; } + /* ORPHANS boolean, read-only */ if (seip->ctl_flags_rd_mask & SG_CTL_FLAGM_ORPHANS) { if (sg_any_persistent_orphans(sfp)) seip->ctl_flags |= SG_CTL_FLAGM_ORPHANS; else seip->ctl_flags &= ~SG_CTL_FLAGM_ORPHANS; } + /* OTHER_OPENS boolean, read-only */ if (seip->ctl_flags_rd_mask & SG_CTL_FLAGM_OTHER_OPENS) { if (sdp->open_cnt > 1) seip->ctl_flags |= SG_CTL_FLAGM_OTHER_OPENS; else seip->ctl_flags &= ~SG_CTL_FLAGM_OTHER_OPENS; } + /* Q_TAIL boolean, read-write */ + if (seip->ctl_flags_wr_mask & SG_CTL_FLAGM_Q_TAIL) + sfp->q_at_tail = + !!(seip->ctl_flags & SG_CTL_FLAGM_Q_TAIL); + if (seip->ctl_flags_rd_mask & SG_CTL_FLAGM_Q_TAIL) { + if (sfp->q_at_tail) + seip->ctl_flags |= SG_CTL_FLAGM_Q_TAIL; + else + seip->ctl_flags &= ~SG_CTL_FLAGM_Q_TAIL; + } } + /* minor_index u32, read-only */ if (or_masks & SG_SEIM_MINOR_INDEX) { if (seip->valid_wr_mask & SG_SEIM_MINOR_INDEX) SG_LOG(2, sdp, "%s: writing to minor_index ignored\n", @@ -2803,6 +2829,7 @@ sg_add_sfp(struct sg_device *sdp) sfp->rem_sgat_thresh = SG_RQ_DATA_THRESHOLD; sfp->tot_fd_thresh = SG_TOT_FD_THRESHOLD; sfp->time_in_ns = !!SG_DEF_TIME_UNIT; + sfp->q_at_tail = SG_DEFAULT_Q_AT; sfp->parentdp = sdp; if (atomic_read(&sdp->detaching)) { kfree(sfp); diff --git a/include/uapi/scsi/sg.h b/include/uapi/scsi/sg.h index 027323bdfedc..659119d49f86 100644 --- a/include/uapi/scsi/sg.h +++ b/include/uapi/scsi/sg.h @@ -109,7 +109,7 @@ typedef struct sg_io_hdr { #define SG_FLAG_MMAP_IO 4 /* request memory mapped IO */ /* no transfer of kernel buffers to/from user space; to debug indirect IO */ #define SG_FLAG_NO_DXFER 0x10000 -/* defaults: for sg driver: Q_AT_HEAD; for block layer: Q_AT_TAIL */ +/* defaults: for sg driver (v3): Q_AT_HEAD; for block layer: Q_AT_TAIL */ #define SG_FLAG_Q_AT_TAIL 0x10 #define SG_FLAG_Q_AT_HEAD 0x20 @@ -192,6 +192,7 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ #define SG_CTL_FLAGM_TAG_FOR_PACK_ID 0x2 #define SG_CTL_FLAGM_OTHER_OPENS 0x4 /* rd: other sg fd_s on this dev */ #define SG_CTL_FLAGM_ORPHANS 0x8 /* rd: orphaned requests on this fd */ +#define SG_CTL_FLAGM_Q_TAIL 0x10 /* used for future cmds on this fd */ /* * A pointer to the following structure is passed as the third argument to