diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2021-01-13 16:09:58 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2021-01-13 16:09:58 +0000 |
commit | 070eae9c6711b900abc1a46e09de0bbc515028a2 (patch) | |
tree | 4bc5feea6f7e300dc2282197b1ad9d3bec710b41 /testing | |
parent | 6a2fe0f14972e955e466a0d36f3a8b1d15dc3fcc (diff) | |
download | sg3_utils-070eae9c6711b900abc1a46e09de0bbc515028a2.tar.gz |
testing update for hipri; testing/uapi_sg.h update
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@873 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'testing')
-rw-r--r-- | testing/sg_mrq_dd.cpp | 67 | ||||
-rw-r--r-- | testing/sgh_dd.cpp | 30 | ||||
-rw-r--r-- | testing/uapi_sg.h | 29 |
3 files changed, 99 insertions, 27 deletions
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp index 27424a02..8496617e 100644 --- a/testing/sg_mrq_dd.cpp +++ b/testing/sg_mrq_dd.cpp @@ -2,7 +2,7 @@ * A utility program for copying files. Specialised for "files" that * represent devices that understand the SCSI command set. * - * Copyright (C) 2018-2020 D. Gilbert + * Copyright (C) 2018-2021 D. Gilbert * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) @@ -30,7 +30,7 @@ * */ -static const char * version_str = "1.16 20201105"; +static const char * version_str = "1.17 20210106"; #define _XOPEN_SOURCE 600 #ifndef _GNU_SOURCE @@ -178,6 +178,7 @@ struct flags_t { bool excl; bool ff; bool fua; + bool hipri; bool masync; /* more async sg v4 driver fd flag */ bool no_dur; bool nocreat; @@ -537,16 +538,26 @@ sg_flags_str(int flags, int b_len, char * b) if (n >= b_len) goto fini; } - if (SGV4_FLAG_EVENTFD & flags) { /* 0x40000 */ + if (SGV4_FLAG_EVENTFD & flags) { /* 0x40000 */ n += sg_scnpr(b + n, b_len - n, "EVFD|"); if (n >= b_len) goto fini; } - if (SGV4_FLAG_ORDERED_WR & flags) { /* 0x80000 */ + if (SGV4_FLAG_ORDERED_WR & flags) { /* 0x80000 */ n += sg_scnpr(b + n, b_len - n, "OWR|"); if (n >= b_len) goto fini; } + if (SGV4_FLAG_REC_ORDER & flags) { /* 0x100000 */ + n += sg_scnpr(b + n, b_len - n, "RECO|"); + if (n >= b_len) + goto fini; + } + if (SGV4_FLAG_HIPRI & flags) { /* 0x200000 */ + n += sg_scnpr(b + n, b_len - n, "HIPRI|"); + if (n >= b_len) + goto fini; + } fini: if (n < b_len) { /* trim trailing '\' */ if ('|' == b[n - 1]) @@ -929,6 +940,8 @@ page3: "iflags)\n" " fua sets the FUA (force unit access) in SCSI READs " "and WRITEs\n" + " hipri set HIPRI flag and use blk_poll() for " + "completions\n" " masync set 'more async' flag on this sg device\n" " mmap setup mmap IO on IFILE or OFILE\n" " mmap,mmap when used twice, doesn't call munmap()\n" @@ -1814,6 +1827,8 @@ sg_half_segment_mrq0(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr, rflags |= SGV4_FLAG_Q_AT_TAIL; if (clp->no_waitq) rflags |= SGV4_FLAG_NO_WAITQ; + if (flagsp->hipri) + rflags |= SGV4_FLAG_HIPRI; for (k = 0, num = 0; seg_blks > 0; ++k, seg_blks -= num) { kk = min<int>(seg_blks, clp->bpt); @@ -1930,6 +1945,8 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr, rflags |= SGV4_FLAG_Q_AT_TAIL; if (clp->no_waitq) rflags |= SGV4_FLAG_NO_WAITQ; + if (flagsp->hipri) + rflags |= SGV4_FLAG_HIPRI; for (k = 0, num = 0; seg_blks > 0; ++k, seg_blks -= num) { kk = min<int>(seg_blks, clp->bpt); @@ -1992,6 +2009,8 @@ sg_half_segment(Rq_elem * rep, scat_gath_iter & sg_it, bool is_wr, ctl_v4.flags = SGV4_FLAG_MULTIPLE_REQS; if (! flagsp->coe) ctl_v4.flags |= SGV4_FLAG_STOP_IF; + if (flagsp->hipri) + rflags |= SGV4_FLAG_HIPRI; ctl_v4.dout_xferp = (uint64_t)a_v4.data(); /* request array */ ctl_v4.dout_xfer_len = a_v4.size() * sizeof(struct sg_io_v4); ctl_v4.din_xferp = (uint64_t)a_v4.data(); /* response array */ @@ -2324,6 +2343,8 @@ do_both_sg_segment_mrq0(Rq_elem * rep, scat_gath_iter & i_sg_it, iflags |= SGV4_FLAG_Q_AT_TAIL; if (clp->no_waitq) iflags |= SGV4_FLAG_NO_WAITQ; + if (iflagsp->hipri) + iflags |= SGV4_FLAG_HIPRI; oflags = SGV4_FLAG_SHARE | SGV4_FLAG_NO_DXFER; if (oflagsp->dio) @@ -2334,6 +2355,8 @@ do_both_sg_segment_mrq0(Rq_elem * rep, scat_gath_iter & i_sg_it, oflags |= SGV4_FLAG_Q_AT_TAIL; if (clp->no_waitq) oflags |= SGV4_FLAG_NO_WAITQ; + if (oflagsp->hipri) + oflags |= SGV4_FLAG_HIPRI; for (k = 0; seg_blks > 0; ++k, seg_blks -= num) { kk = min<int>(seg_blks, clp->bpt); @@ -2501,6 +2524,8 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it, iflags |= SGV4_FLAG_Q_AT_TAIL; if (clp->no_waitq) iflags |= SGV4_FLAG_NO_WAITQ; + if (iflagsp->hipri) + iflags |= SGV4_FLAG_HIPRI; oflags = SGV4_FLAG_SHARE | SGV4_FLAG_NO_DXFER; if (oflagsp->dio) @@ -2511,6 +2536,8 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it, oflags |= SGV4_FLAG_Q_AT_TAIL; if (clp->no_waitq) oflags |= SGV4_FLAG_NO_WAITQ; + if (oflagsp->hipri) + oflags |= SGV4_FLAG_HIPRI; oflags |= SGV4_FLAG_DO_ON_OTHER; for (k = 0; seg_blks > 0; ++k, seg_blks -= num) { @@ -2603,6 +2630,8 @@ do_both_sg_segment(Rq_elem * rep, scat_gath_iter & i_sg_it, ctl_v4.flags |= SGV4_FLAG_STOP_IF; if ((! clp->verify) && clp->out_flags.order) ctl_v4.flags |= SGV4_FLAG_ORDERED_WR; + if (! (iflagsp->hipri || oflagsp->hipri)) + ctl_v4.flags |= SGV4_FLAG_HIPRI; ctl_v4.dout_xferp = (uint64_t)a_v4.data(); /* request array */ ctl_v4.dout_xfer_len = a_v4.size() * sizeof(struct sg_io_v4); ctl_v4.din_xferp = (uint64_t)a_v4.data(); /* response array */ @@ -2692,6 +2721,31 @@ fini: return res < 0 ? res : (min<int>(in_fin_blks, out_fin_blks)); } +/* Returns number found and (partially) processed. 'num' is the number of + * completions to wait for when > 0. When 'num' is zero check all inflight + * request on 'fd' and return quickly if none completed (i.e. don't wait) + * If error return negative errno and if no request inflight or waiting + * then return -9999 . */ +static int +sg_blk_poll(int fd, int num) +{ + int res; + struct sg_extended_info sei; + struct sg_extended_info * seip = &sei; + + memset(seip, 0, sizeof(*seip)); + seip->sei_rd_mask |= SG_SEIM_BLK_POLL; + seip->sei_wr_mask |= SG_SEIM_BLK_POLL; + seip->num = (num < 0) ? 0 : num; + res = ioctl(fd, SG_SET_GET_EXTENDED, seip); + if (res < 0) { + pr2serr_lk("%s: SG_SET_GET_EXTENDED(BLK_POLL) error: %s\n", + __func__, strerror(errno)); + return res; + } + return (seip->num == -1) ? -9999 : seip->num; +} + /* Returns reserved_buffer_size/mmap_size if success, else 0 for failure */ static int sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in, @@ -2705,9 +2759,8 @@ sg_prepare_resbuf(int fd, struct global_collection *clp, bool is_in, int res, t, num, err; uint8_t *mmp; struct sg_extended_info sei; - struct sg_extended_info * seip; + struct sg_extended_info * seip = &sei; - seip = &sei; res = ioctl(fd, SG_GET_VERSION_NUM, &t); if ((res < 0) || (t < 40000)) { if (ioctl(fd, SG_GET_RESERVED_SIZE, &num) < 0) { @@ -2944,6 +2997,8 @@ process_flags(const char * arg, struct flags_t * fp) fp->ff = true; else if (0 == strcmp(cp, "fua")) fp->fua = true; + else if (0 == strcmp(cp, "hipri")) + fp->hipri = true; else if (0 == strcmp(cp, "masync")) fp->masync = true; else if (0 == strcmp(cp, "mmap")) diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp index d0b8ab29..f0b145f8 100644 --- a/testing/sgh_dd.cpp +++ b/testing/sgh_dd.cpp @@ -2,7 +2,7 @@ * A utility program for copying files. Specialised for "files" that * represent devices that understand the SCSI command set. * - * Copyright (C) 2018-2020 D. Gilbert + * Copyright (C) 2018-2021 D. Gilbert * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) @@ -36,7 +36,7 @@ * renamed [20181221] */ -static const char * version_str = "1.97 20201124"; +static const char * version_str = "1.98 20210106"; #define _XOPEN_SOURCE 600 #ifndef _GNU_SOURCE @@ -173,6 +173,7 @@ struct flags_t { bool excl; bool ff; bool fua; + bool hipri; bool masync; /* more async sg v4 driver flag */ bool mrq_immed; /* mrq submit non-blocking */ bool mrq_svb; /* mrq shared_variable_block, for sg->sg copy */ @@ -589,16 +590,26 @@ sg_flags_str(int flags, int b_len, char * b) if (n >= b_len) goto fini; } - if (SGV4_FLAG_EVENTFD & flags) { /* 0x40000 */ + if (SGV4_FLAG_EVENTFD & flags) { /* 0x40000 */ n += sg_scnpr(b + n, b_len - n, "EVFD|"); if (n >= b_len) goto fini; } - if (SGV4_FLAG_ORDERED_WR & flags) { /* 0x80000 */ + if (SGV4_FLAG_ORDERED_WR & flags) { /* 0x80000 */ n += sg_scnpr(b + n, b_len - n, "OWR|"); if (n >= b_len) goto fini; } + if (SGV4_FLAG_REC_ORDER & flags) { /* 0x100000 */ + n += sg_scnpr(b + n, b_len - n, "RECO|"); + if (n >= b_len) + goto fini; + } + if (SGV4_FLAG_HIPRI & flags) { /* 0x200000 */ + n += sg_scnpr(b + n, b_len - n, "HIPRI|"); + if (n >= b_len) + goto fini; + } if (0 == n) n += sg_scnpr(b + n, b_len - n, "<none>"); fini: @@ -891,10 +902,10 @@ usage(int pg_num) goto page2; pr2serr("Usage: sgh_dd [bs=BS] [conv=CONVS] [count=COUNT] [ibs=BS] " - "[if=IFILE]\n" + "[if=IFILE]\n" " [iflag=FLAGS] [obs=BS] [of=OFILE] [oflag=FLAGS] " "[seek=SEEK]\n" - " [skip=SKIP] [--help] [--version]\n\n"); + " [skip=SKIP] [--help] [--version]\n\n"); pr2serr(" [ae=AEN[,MAEN]] [bpt=BPT] [cdbsz=6|10|12|16] " "[coe=0|1]\n" " [dio=0|1] [elemsz_kb=EKB] [fail_mask=FM] " @@ -1016,6 +1027,8 @@ page3: "iflags)\n" " fua sets the FUA (force unit access) in SCSI READs " "and WRITEs\n" + " hipri set HIPRI flag on command, uses blk_poll() to " + "complete\n" " masync set 'more async' flag on this sg device\n" " mmap setup mmap IO on IFILE or OFILE; OFILE only " "with noshare\n" @@ -3001,6 +3014,7 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id, bool v4 = wr ? clp->out_flags.v4 : clp->in_flags.v4; bool qhead = wr ? clp->out_flags.qhead : clp->in_flags.qhead; bool qtail = wr ? clp->out_flags.qtail : clp->in_flags.qtail; + bool hipri = wr ? clp->out_flags.hipri : clp->in_flags.hipri; bool prefetch = xtrp ? xtrp->prefetch : false; bool is_wr2 = xtrp ? xtrp->is_wr2 : false; int cdbsz = wr ? clp->cdbsz_out : clp->cdbsz_in; @@ -3059,6 +3073,8 @@ sg_start_io(Rq_elem * rep, mrq_arr_t & def_arr, int & pack_id, flags |= SG_FLAG_NO_DXFER; if (dio) flags |= SG_FLAG_DIRECT_IO; + if (hipri) + flags |= SGV4_FLAG_HIPRI; if (qhead) flags |= SG_FLAG_Q_AT_HEAD; if (qtail) @@ -3651,6 +3667,8 @@ process_flags(const char * arg, struct flags_t * fp) fp->ff = true; else if (0 == strcmp(cp, "fua")) fp->fua = true; + else if (0 == strcmp(cp, "hipri")) + fp->hipri = true; else if (0 == strcmp(cp, "masync")) fp->masync = true; else if (0 == strcmp(cp, "mmap")) diff --git a/testing/uapi_sg.h b/testing/uapi_sg.h index aa20c219..0cdbc249 100644 --- a/testing/uapi_sg.h +++ b/testing/uapi_sg.h @@ -14,7 +14,7 @@ * Later extensions (versions 2, 3 and 4) to driver: * Copyright (C) 1998 - 2021 Douglas Gilbert * - * Version 4.0.46 (20210101) + * Version 4.0.46 (20210111) * This version is for Linux 4 and 5 series kernels. * * Documentation @@ -119,17 +119,17 @@ typedef struct sg_io_hdr { #define SGV4_FLAG_COMPLETE_B4 0x100 /* mrq: complete this rq before next */ #define SGV4_FLAG_SIGNAL 0x200 /* v3: ignored; v4 signal on completion */ #define SGV4_FLAG_IMMED 0x400 /* issue request and return immediately ... */ -#define SGV4_FLAG_STOP_IF 0x800 /* Stops sync mrq if error or warning */ -#define SGV4_FLAG_DEV_SCOPE 0x1000 /* permit SG_IOABORT to have wider scope */ -#define SGV4_FLAG_SHARE 0x2000 /* share IO buffer; needs SG_SEIM_SHARE_FD */ -#define SGV4_FLAG_DO_ON_OTHER 0x4000 /* available on either of shared pair */ -#define SGV4_FLAG_KEEP_SHARE 0x8000 /* ... buffer for another dout command */ +#define SGV4_FLAG_HIPRI 0x800 /* request will use blk_poll to complete */ +#define SGV4_FLAG_STOP_IF 0x1000 /* Stops sync mrq if error or warning */ +#define SGV4_FLAG_DEV_SCOPE 0x2000 /* permit SG_IOABORT to have wider scope */ +#define SGV4_FLAG_SHARE 0x4000 /* share IO buffer; needs SG_SEIM_SHARE_FD */ +#define SGV4_FLAG_DO_ON_OTHER 0x8000 /* available on either of shared pair */ #define SGV4_FLAG_NO_DXFER SG_FLAG_NO_DXFER /* needed for sharing */ -#define SGV4_FLAG_MULTIPLE_REQS 0x20000 /* 1 or more sg_io_v4-s in data-in */ -#define SGV4_FLAG_EVENTFD 0x40000 /* signal completion on ... */ -#define SGV4_FLAG_ORDERED_WR 0x80000 /* svb: issue in-order writes */ -#define SGV4_FLAG_REC_ORDER 0x100000 /* receive order in v4:request_priority */ -#define SGV4_FLAG_HIPRI 0x200000 /* completion via SG_SEIM_BLK_POLL */ +#define SGV4_FLAG_KEEP_SHARE 0x20000 /* ... buffer for another dout command */ +#define SGV4_FLAG_MULTIPLE_REQS 0x40000 /* 1 or more sg_io_v4-s in data-in */ +#define SGV4_FLAG_EVENTFD 0x80000 /* signal completion on ... */ +#define SGV4_FLAG_ORDERED_WR 0x100000 /* svb: issue in-order writes */ +#define SGV4_FLAG_REC_ORDER 0x200000 /* receive order in v4:request_priority */ /* Output (potentially OR-ed together) in v3::info or v4::info field */ #define SG_INFO_OK_MASK 0x1 @@ -199,8 +199,8 @@ typedef struct sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ #define SG_SEIM_SHARE_FD 0x20 /* write-side gives fd of read-side */ #define SG_SEIM_CHG_SHARE_FD 0x40 /* read-side given new write-side fd */ #define SG_SEIM_SGAT_ELEM_SZ 0x80 /* sgat element size (>= PAGE_SIZE) */ -#define SG_SEIM_EVENTFD 0x100 /* pass eventfd to driver */ -#define SG_SEIM_BLK_POLL 0x200 /* call blk_poll, uses general field */ +#define SG_SEIM_BLK_POLL 0x100 /* call blk_poll, uses 'num' field */ +#define SG_SEIM_EVENTFD 0x200 /* pass eventfd to driver */ #define SG_SEIM_ALL_BITS 0x3ff /* should be OR of previous items */ /* flag and mask values for boolean fields follow */ @@ -262,8 +262,7 @@ struct sg_extended_info { __u32 minor_index; /* rd: kernel's sg device minor number */ __u32 share_fd; /* for SHARE_FD, CHG_SHARE_FD or EVENTFD */ __u32 sgat_elem_sz; /* sgat element size (must be power of 2) */ - __s32 num; /* blk_poll: spin for num (0: no spin); raw */ - /* read number completed */ + __s32 num; /* blk_poll: loop_count (-1 -> spin)) */ __u8 pad_to_96[48]; /* pad so struct is 96 bytes long */ }; |