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/sg_mrq_dd.cpp | |
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/sg_mrq_dd.cpp')
-rw-r--r-- | testing/sg_mrq_dd.cpp | 67 |
1 files changed, 61 insertions, 6 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")) |