aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2021-02-20 01:43:36 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2021-02-20 01:43:36 +0000
commit7d78ae6198005fcaf58a66c2db11cbfe605df439 (patch)
tree8323596b871e4dca7d35c0ad9cba07cea61d094a
parent28d27daf0d8ff9ab8ee957a3f9917e2c2a23d232 (diff)
downloadsg3_utils-7d78ae6198005fcaf58a66c2db11cbfe605df439.tar.gz
testing updates, mainly sgs_dd
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@876 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog2
-rw-r--r--debian/changelog2
-rw-r--r--sg3_utils.spec2
-rw-r--r--testing/sg_iovec_tst.cpp13
-rw-r--r--testing/sg_mrq_dd.cpp6
-rw-r--r--testing/sgh_dd.cpp28
-rw-r--r--testing/sgs_dd.c427
7 files changed, 319 insertions, 161 deletions
diff --git a/ChangeLog b/ChangeLog
index 1ad6872e..1405135e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for pre-release sg3_utils-1.46 [20210208] [svn: r875]
+Changelog for pre-release sg3_utils-1.46 [20210219] [svn: r876]
- sg_rep_pip: report new provisioning initialization pattern cmd
- sg_turs: estimated time-to-ready [20-061r2]
- add --delay=MS option
diff --git a/debian/changelog b/debian/changelog
index 0779e80d..e5d0e7cb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.46-0.1) unstable; urgency=low
* New upstream version
- -- Douglas Gilbert <dgilbert@interlog.com> Fri, 05 Feb 2021 15:00:00 -0500
+ -- Douglas Gilbert <dgilbert@interlog.com> Mon, 15 Feb 2021 10:00:00 -0500
sg3-utils (1.45-0.1) unstable; urgency=low
diff --git a/sg3_utils.spec b/sg3_utils.spec
index 58f32d85..0691fc7a 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -84,7 +84,7 @@ fi
%{_libdir}/*.la
%changelog
-* Fri Feb 05 2021 - dgilbert at interlog dot com
+* Mon Feb 15 2021 - dgilbert at interlog dot com
- track t10 changes
* sg3_utils-1.46
diff --git a/testing/sg_iovec_tst.cpp b/testing/sg_iovec_tst.cpp
index 3199dc8d..3ee728ac 100644
--- a/testing/sg_iovec_tst.cpp
+++ b/testing/sg_iovec_tst.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2003-2020 D. Gilbert
+ * Copyright (C) 2003-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)
@@ -68,7 +68,7 @@
// C++ local header
#include "sg_scat_gath.h"
-static const char * version_str = "1.07 20201108";
+static const char * version_str = "1.08 20210214";
#define ME "sg_iovec_tst: "
@@ -114,7 +114,7 @@ usage(void)
" [--skip=SKIP] [--verbose] [--version] "
"SG_DEV OUT_F\n");
printf("where:\n"
- " --async|-a async sg use (def: use ioctl(SGIO) )\n");
+ " --async|-a async sg usage (def: use ioctl(SGIO) )\n");
printf(" --bs=BS|-b BS logical block size of SG_DEV (def: 512 "
"bytes)\n");
printf(" --elem_sz=ES|-e ES iovec element size (def: BS bytes)\n");
@@ -125,9 +125,10 @@ usage(void)
printf(" --from_skip|-F sgl output starts from SKIP (def: 0)\n");
printf(" --help|-h this usage message\n");
printf(" --num=NUM|-n NUM number of blocks to read from SG_DEV\n");
- printf(" --sgl=SFN|-S SFN Sgl FileName (SFN) that written to, with "
- "addresses\n"
- " and lengths having ES as their unit\n");
+ printf(" --sgl=SFN|-S SFN Sgl FileName (SFN) that is written to, "
+ "with\n"
+ " addresses and lengths having ES as "
+ "their unit\n");
printf(" --sgv4|-4 use the sg v4 interface (def: v3 "
"interface)\n");
printf(" --skip=SKIP|-s SKIP SKIP blocks before reading S_DEV "
diff --git a/testing/sg_mrq_dd.cpp b/testing/sg_mrq_dd.cpp
index 5beb9b31..21232057 100644
--- a/testing/sg_mrq_dd.cpp
+++ b/testing/sg_mrq_dd.cpp
@@ -30,7 +30,7 @@
*
*/
-static const char * version_str = "1.19 20210208";
+static const char * version_str = "1.20 20210210";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -117,6 +117,10 @@ using namespace std;
// #endif
+#ifndef SGV4_FLAG_HIPRI
+#define SGV4_FLAG_HIPRI 0x800
+#endif
+
#define MAX_SGL_NUM_VAL (INT32_MAX - 1) /* should reduce for testing */
// #define MAX_SGL_NUM_VAL 7 /* should reduce for testing */
#if MAX_SGL_NUM_VAL > INT32_MAX
diff --git a/testing/sgh_dd.cpp b/testing/sgh_dd.cpp
index 35358352..7c0c9ed6 100644
--- a/testing/sgh_dd.cpp
+++ b/testing/sgh_dd.cpp
@@ -36,7 +36,7 @@
* renamed [20181221]
*/
-static const char * version_str = "1.98 20210108";
+static const char * version_str = "1.99 20210216";
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
@@ -120,6 +120,10 @@ using namespace std;
/* comment out following line to stop ioctl(SG_CTL_FLAGM_SNAP_DEV) */
#define SGH_DD_SNAP_DEV 1
+#ifndef SGV4_FLAG_HIPRI
+#define SGV4_FLAG_HIPRI 0x800
+#endif
+
#define DEF_BLOCK_SIZE 512
#define DEF_BLOCKS_PER_TRANSFER 128
#define DEF_BLOCKS_PER_2048TRANSFER 32
@@ -917,7 +921,7 @@ usage(int pg_num)
"[thr=THR]\n"
" [time=0|1|2[,TO]] [unshare=1|0] [verbose=VERB] "
"[--dry-run]\n"
- " [--prefetch] [--verbose] [--verify] "
+ " [--prefetch] [-v|-vv|-vvv] [--verbose] [--verify] "
"[--version]\n\n"
" where the main options (shown in first group above) are:\n"
" bs must be device logical block size (default "
@@ -1895,7 +1899,7 @@ sg_build_scsi_cdb(uint8_t * cdbp, int cdb_sz, unsigned int blocks,
memset(cdbp, 0, cdb_sz);
if (ver_true) { /* only support VERIFY(10) */
if (cdb_sz < 10) {
- pr2serr_lk("%s only support VERIFY(10)\n", my_name);
+ pr2serr_lk("%sonly support VERIFY(10)\n", my_name);
return 1;
}
cdb_sz = 10;
@@ -3532,16 +3536,16 @@ sg_prepare_resbuf(int fd, bool is_in, struct global_collection *clp,
seip->sei_rd_mask |= SG_SEIM_SGAT_ELEM_SZ;
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
if (res < 0)
- pr2serr_lk("sgh_dd: %s: SG_SET_GET_EXTENDED(SGAT_ELEM_SZ) rd "
- "error: %s\n", __func__, strerror(errno));
+ pr2serr_lk("%s%s: SG_SET_GET_EXTENDED(SGAT_ELEM_SZ) rd "
+ "error: %s\n", my_name, __func__, strerror(errno));
if (clp->elem_sz != (int)seip->sgat_elem_sz) {
memset(seip, 0, sizeof(*seip));
seip->sei_wr_mask |= SG_SEIM_SGAT_ELEM_SZ;
seip->sgat_elem_sz = clp->elem_sz;
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
if (res < 0)
- pr2serr_lk("sgh_dd: %s: SG_SET_GET_EXTENDED(SGAT_ELEM_SZ) "
- "wr error: %s\n", __func__, strerror(errno));
+ pr2serr_lk("%s%s: SG_SET_GET_EXTENDED(SGAT_ELEM_SZ) wr "
+ "error: %s\n", my_name, __func__, strerror(errno));
}
}
if (no_dur || masync) {
@@ -3561,8 +3565,8 @@ sg_prepare_resbuf(int fd, bool is_in, struct global_collection *clp,
}
res = ioctl(fd, SG_SET_GET_EXTENDED, seip);
if (res < 0)
- pr2serr_lk("sgh_dd: %s: SG_SET_GET_EXTENDED(NO_DURATION) "
- "error: %s\n", __func__, strerror(errno));
+ pr2serr_lk("%s%s: SG_SET_GET_EXTENDED(NO_DURATION) error: %s\n",
+ my_name, __func__, strerror(errno));
}
bypass:
if (! def_res) {
@@ -3591,8 +3595,8 @@ bypass:
if (MAP_FAILED == mmp) {
int err = errno;
- pr2serr_lk("sgh_dd: %s: sz=%d, fd=%d, mmap() failed: %s\n",
- __func__, num, fd, strerror(err));
+ pr2serr_lk("%s%s: sz=%d, fd=%d, mmap() failed: %s\n",
+ my_name, __func__, num, fd, strerror(err));
return 0;
}
*mmpp = mmp;
@@ -3627,7 +3631,7 @@ bypass:
t = 1;
res = ioctl(fd, SG_SET_DEBUG, &t); /* more info in /proc/scsi/sg/debug */
if (res < 0)
- perror("sgh_dd: SG_SET_DEBUG error");
+ perror("sgs_dd: SG_SET_DEBUG error");
return (res < 0) ? 0 : num;
}
diff --git a/testing/sgs_dd.c b/testing/sgs_dd.c
index ccae39e0..0943340a 100644
--- a/testing/sgs_dd.c
+++ b/testing/sgs_dd.c
@@ -1,7 +1,7 @@
/*
* Test code for the extensions to the Linux OS SCSI generic ("sg")
* device driver.
- * Copyright (C) 1999-2020 D. Gilbert and P. Allworth
+ * Copyright (C) 1999-2021 D. Gilbert and P. Allworth
*
* 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
@@ -51,6 +51,7 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/mman.h> /* for mmap() system call */
#include <sys/eventfd.h>
#include <sys/epoll.h>
#define __STDC_FORMAT_MACROS 1
@@ -83,14 +84,16 @@
#include "sg_unaligned.h"
-static const char * version_str = "4.15 20200916";
+static const char * version_str = "4.17 20210218";
static const char * my_name = "sgs_dd";
+#ifndef SGV4_FLAG_HIPRI
+#define SGV4_FLAG_HIPRI 0x800
+#endif
+
#define DEF_BLOCK_SIZE 512
#define DEF_BPT_TIMES_BS_SZ (64 * 1024) /* 64 KB */
-/* #define SG_DEBUG 1 comment out if not needed */
-
#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
#define DEF_TIMEOUT 40000 /* 40,000 millisecs == 40 seconds */
#define S_RW_LEN 10 /* Use SCSI READ(10) and WRITE(10) */
@@ -109,6 +112,8 @@ static const char * my_name = "sgs_dd";
#define SGQ_CAN_WRITE 2
#define SGQ_TIMEOUT 4
+#define DEF_SIGTIMEDWAIT_USEC 100
+
#define STR_SZ 1024
#define INOUTF_SZ 900
@@ -118,6 +123,7 @@ struct flags_t {
bool dio;
bool evfd;
bool excl;
+ bool hipri;
bool immed;
bool mmap;
bool noxfer;
@@ -126,6 +132,7 @@ struct flags_t {
bool tag;
bool v3;
bool v4;
+ bool given_v3v4;
};
typedef struct request_element
@@ -153,6 +160,7 @@ typedef struct request_collection
bool out_is_sg;
bool no_sig;
bool use_rt_sig;
+ bool both_mmap;
int infd;
int in_evfd;
int in_blk; /* most recent read */
@@ -172,13 +180,16 @@ typedef struct request_collection
int sum_of_resids;
int poll_ms;
int pollerr_count;
- int debug;
+ int debug; /* also set with -v up to -vvvvv */
sigset_t blocked_sigs;
int sigs_waiting;
int sigs_rt_received;
int sigs_io_received;
+ int blk_poll_count;
Rq_elem * rd_posp;
Rq_elem * wr_posp;
+ uint8_t * in_mmapp;
+ uint8_t * out_mmapp;
struct flags_t iflag;
struct flags_t oflag;
Rq_elem elem[SGQ_NUM_ELEMS];
@@ -188,6 +199,10 @@ static bool sgs_old_sg_driver = false; /* true if VERSION_NUM < 4.00.00 */
static bool sgs_full_v4_sg_driver = false; /* set if VERSION_NUM >= 4.00.30 */
static bool sgs_nanosec_unit = false;
+static int sgq_rd_ahead_lim = SGQ_MAX_RD_AHEAD;
+static int sgq_wr_ahead_lim = SGQ_MAX_WR_AHEAD;
+static int sgq_num_elems = (SGQ_MAX_RD_AHEAD + SGQ_MAX_WR_AHEAD + 1);
+
static void
usage(int pg_num)
@@ -206,11 +221,13 @@ usage(int pg_num)
"bs=512))\n"
" bs must be the logical block size of device (def: 512)\n"
" deb debug: 0->no debug (def); > 0 -> more debug\n"
- " iflag comma separated list from: dio,evfd,excl,immed,mmap,"
- "no_waitq,\n"
- " noxfer,null,pack,tag,v3,v4 bound to IFILE\n"
- " no_sig 0-> use signals (def); 1-> no signals, hard polling "
- "instead\n"
+ " -v (up to -vvvvv) sets deb value to number of 'v's\n"
+ " iflag comma separated list from: dio,evfd,excl,hipri,immed,"
+ "mmap\n"
+ " no_waitq,noxfer,null,pack,tag,v3,v4 bound to IFILE\n"
+ " no_sig 0-> use signals; 1-> no signals, hard polling "
+ "instead;\n"
+ " default 0, unless hipri flag(s) given then it's 1\n"
" oflag same flags as iflag but bound to OFILE\n"
" poll_ms number of milliseconds to wait on poll (def: 0)\n"
" rt_sig 0->use SIGIO (def); 1->use RT sig (SIGRTMIN + 1)\n"
@@ -218,7 +235,7 @@ usage(int pg_num)
printf("dd clone for testing Linux sg driver SIGPOLL and/or polling. "
"Either\nIFILE or OFILE must be a scsi generic device. If OFILE "
"not given then\n/dev/null assumed (rather than stdout like "
- "dd). Use '-hh' or '-hhh'\nfor more information.\n");
+ "dd). Use '-hh' for flag\ninformation.\n");
return;
second_page:
printf("flag description:\n"
@@ -226,6 +243,7 @@ second_page:
" evfd when poll() gives POLLIN, use eventfd to find "
"out how many\n"
" excl open IFILE or OFILE with O_EXCL\n"
+ " hipri set HIPRI flag and use blk_poll() for completion\n"
" immed use SGV4_FLAG_IMMED flag on each request\n"
" mmap use mmap()-ed IO on IFILE or OFILE\n"
" no_waitq use SGV4_FLAG_NO_WAIQ flag on each request\n"
@@ -240,6 +258,26 @@ second_page:
" v4 use sg vr interface (i.e. struct sg_io_v4)\n");
}
+static int
+get_mmap_addr(int fd, int num, uint8_t ** mmpp)
+{
+ uint8_t * mmp;
+
+ if (! mmpp)
+ return -EINVAL;
+ mmp = (uint8_t *)mmap(NULL, num, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ if (MAP_FAILED == mmp) {
+ int err = errno;
+
+ pr2serr("%s%s: sz=%d, fd=%d, mmap() failed: %s\n",
+ my_name, __func__, num, fd, strerror(err));
+ return -err;
+ }
+ *mmpp = mmp;
+ return 0;
+}
+
/* Return of 0 -> success, -1 -> failure, 2 -> try again */
static int
read_capacity(int sg_fd, int * num_sect, int * sect_sz)
@@ -273,13 +311,8 @@ read_capacity(int sg_fd, int * num_sect, int * sect_sz)
sg_chk_n_print3("read capacity", &io_hdr, true);
return -1;
}
- *num_sect = 1 + ((rcBuff[0] << 24) | (rcBuff[1] << 16) |
- (rcBuff[2] << 8) | rcBuff[3]);
- *sect_sz = (rcBuff[4] << 24) | (rcBuff[5] << 16) |
- (rcBuff[6] << 8) | rcBuff[7];
-#ifdef SG_DEBUG
- pr2serr("number of sectors=%d, sector size=%d\n", *num_sect, *sect_sz);
-#endif
+ *num_sect = sg_get_unaligned_be32(rcBuff + 0) + 1;
+ *sect_sz = sg_get_unaligned_be32(rcBuff + 4);
return 0;
}
@@ -287,14 +320,18 @@ read_capacity(int sg_fd, int * num_sect, int * sect_sz)
static int
sg_start_io(Rq_coll * clp, Rq_elem * rep)
{
+ bool is_wr = rep->wr;
int res;
- int fd = rep->wr ? clp->outfd : clp->infd;
- struct flags_t * flagp = rep->wr ? rep->oflagp : rep->iflagp;
+ int fd = is_wr ? clp->outfd : clp->infd;
+ int num_bytes = clp->bs * rep->num_blks;
+ struct flags_t * flagp = is_wr ? rep->oflagp : rep->iflagp;
sg_io_hdr_t * hp = &rep->io_hdr;
struct sg_io_v4 * h4p = &rep->io_v4;
+ if (clp->both_mmap && is_wr)
+ memcpy(clp->out_mmapp, clp->in_mmapp, num_bytes);
memset(rep->cmd, 0, sizeof(rep->cmd));
- rep->cmd[0] = rep->wr ? 0x2a : 0x28;
+ rep->cmd[0] = is_wr ? 0x2a : 0x28;
sg_put_unaligned_be32((uint32_t)rep->blk, rep->cmd + 2);
sg_put_unaligned_be16((uint16_t)rep->num_blks, rep->cmd + 7);
if (flagp->v4)
@@ -304,9 +341,8 @@ sg_start_io(Rq_coll * clp, Rq_elem * rep)
hp->interface_id = 'S';
hp->cmd_len = sizeof(rep->cmd);
hp->cmdp = rep->cmd;
- hp->dxfer_direction = rep->wr ? SG_DXFER_TO_DEV : SG_DXFER_FROM_DEV;
- hp->dxfer_len = clp->bs * rep->num_blks;
- hp->dxferp = rep->buffp;
+ hp->dxfer_direction = is_wr ? SG_DXFER_TO_DEV : SG_DXFER_FROM_DEV;
+ hp->dxfer_len = num_bytes;
hp->mx_sb_len = sizeof(rep->sb);
hp->sbp = rep->sb;
hp->timeout = DEF_TIMEOUT;
@@ -314,23 +350,28 @@ sg_start_io(Rq_coll * clp, Rq_elem * rep)
hp->pack_id = rep->blk;
if (flagp->dio)
hp->flags |= SG_FLAG_DIRECT_IO;
+ if (flagp->hipri)
+ hp->flags |= SGV4_FLAG_HIPRI;
if (flagp->noxfer)
hp->flags |= SG_FLAG_NO_DXFER;
if (flagp->immed)
hp->flags |= SGV4_FLAG_IMMED;
- if (flagp->mmap)
+ if (flagp->mmap) {
hp->flags |= SG_FLAG_MMAP_IO;
+ hp->dxferp = is_wr ? clp->out_mmapp : clp->in_mmapp;
+ } else
+ hp->dxferp = rep->buffp;
if (flagp->evfd)
hp->flags |= SGV4_FLAG_EVENTFD;
if (flagp->no_waitq)
hp->flags |= SGV4_FLAG_NO_WAITQ;
-#ifdef SG_DEBUG
- pr2serr("%s: SCSI %s, blk=%d num_blks=%d\n", __func__,
- rep->wr ? "WRITE" : "READ", rep->blk, rep->num_blks);
- sg_print_command(hp->cmdp);
- pr2serr("dir=%d, len=%d, dxfrp=%p, cmd_len=%d\n", hp->dxfer_direction,
- hp->dxfer_len, hp->dxferp, hp->cmd_len);
-#endif
+ if (clp->debug > 5) {
+ pr2serr("%s: SCSI %s, blk=%d num_blks=%d\n", __func__,
+ is_wr ? "WRITE" : "READ", rep->blk, rep->num_blks);
+ sg_print_command(hp->cmdp);
+ pr2serr("dir=%d, len=%d, dxfrp=%p, cmd_len=%d\n", hp->dxfer_direction,
+ hp->dxfer_len, hp->dxferp, hp->cmd_len);
+ }
while (((res = write(fd, hp, sizeof(sg_io_hdr_t))) < 0) &&
(EINTR == errno))
@@ -355,13 +396,10 @@ do_v4:
h4p->guard = 'Q';
h4p->request_len = sizeof(rep->cmd);
h4p->request = (uint64_t)(uintptr_t)rep->cmd;
- if (rep->wr) {
- h4p->dout_xfer_len = clp->bs * rep->num_blks;
- h4p->dout_xferp = (uint64_t)(uintptr_t)rep->buffp;
- } else if (rep->num_blks > 0) {
- h4p->din_xfer_len = clp->bs * rep->num_blks;
- h4p->din_xferp = (uint64_t)(uintptr_t)rep->buffp;
- }
+ if (is_wr)
+ h4p->dout_xfer_len = num_bytes;
+ else if (rep->num_blks > 0)
+ h4p->din_xfer_len = num_bytes;
h4p->max_response_len = sizeof(rep->sb);
h4p->response = (uint64_t)(uintptr_t)rep->sb;
h4p->timeout = DEF_TIMEOUT;
@@ -371,10 +409,19 @@ do_v4:
h4p->flags |= SG_FLAG_DIRECT_IO;
if (flagp->noxfer)
h4p->flags |= SG_FLAG_NO_DXFER;
+ if (flagp->hipri)
+ h4p->flags |= SGV4_FLAG_HIPRI;
if (flagp->immed)
h4p->flags |= SGV4_FLAG_IMMED;
- if (flagp->mmap)
+ if (flagp->mmap) {
h4p->flags |= SG_FLAG_MMAP_IO;
+ hp->dxferp = is_wr ? clp->out_mmapp : clp->in_mmapp;
+ } else {
+ if (is_wr)
+ h4p->dout_xferp = (uint64_t)(uintptr_t)rep->buffp;
+ else if (rep->num_blks > 0)
+ h4p->din_xferp = (uint64_t)(uintptr_t)rep->buffp;
+ }
if (flagp->tag)
h4p->flags |= SGV4_FLAG_YIELD_TAG;
if (flagp->evfd)
@@ -399,11 +446,11 @@ do_v4:
rep->state = SGQ_IO_STARTED;
if (! clp->no_sig)
clp->sigs_waiting++;
-#ifdef SG_DEBUG
- if (rep->wr ? clp->oflag.tag : clp->iflag.tag)
- pr2serr("%s: generated_tag=0x%" PRIx64 "\n", __func__,
- (uint64_t)h4p->generated_tag);
-#endif
+ if (clp->debug > 5) {
+ if (is_wr ? clp->oflag.tag : clp->iflag.tag)
+ pr2serr("%s: generated_tag=0x%" PRIx64 "\n", __func__,
+ (uint64_t)h4p->generated_tag);
+ }
return 0;
}
@@ -426,13 +473,38 @@ sg_finish_io(Rq_coll * clp, bool wr, Rq_elem ** repp)
if (is_v4)
goto do_v4;
+ if (use_pack) {
+ while (true) {
+ if ( ((res = ioctl(fd, SG_GET_NUM_WAITING, &n))) < 0) {
+ res = -errno;
+ pr2serr("%s: ioctl(SG_GET_NUM_WAITING): %s [%d]\n",
+ __func__, strerror(errno), errno);
+ return res;
+ }
+ if (n > 0) {
+ if ( ((res = ioctl(fd, SG_GET_PACK_ID, &id))) < 0) {
+ res = -errno;
+ pr2serr("%s: ioctl(SG_GET_PACK_ID): %s [%d]\n",
+ __func__, strerror(errno), errno);
+ return res;
+ }
+ /* got pack_id or tag of first waiting */
+ break;
+ }
+ }
+ }
memset(&io_hdr, 0 , sizeof(sg_io_hdr_t));
+ if (use_pack)
+ io_hdr.pack_id = id;
while (((res = read(fd, &io_hdr, sizeof(sg_io_hdr_t))) < 0) &&
((EINTR == errno) || (EAGAIN == errno) || (EBUSY == errno)))
;
rep = (Rq_elem *)io_hdr.usr_ptr;
- if (rep)
+ if (rep) {
dio = flagsp->dio;
+ if (rep->io_hdr.flags & SGV4_FLAG_HIPRI)
+ ++clp->blk_poll_count;
+ }
if (res < 0) {
res = -errno;
pr2serr("%s: read(): %s [%d]\n", __func__, strerror(errno), errno);
@@ -461,7 +533,7 @@ sg_finish_io(Rq_coll * clp, bool wr, Rq_elem ** repp)
case SG_LIB_CAT_UNIT_ATTENTION:
return 1;
default:
- sg_chk_n_print3(rep->wr ? "writing": "reading", hp, true);
+ sg_chk_n_print3(wr ? "writing": "reading", hp, true);
rep->state = SGQ_IO_ERR;
return -1;
}
@@ -469,10 +541,10 @@ sg_finish_io(Rq_coll * clp, bool wr, Rq_elem ** repp)
++clp->dio_incomplete; /* count dios done as indirect IO */
clp->sum_of_resids += hp->resid;
rep->state = SGQ_IO_FINISHED;
-#ifdef SG_DEBUG
- pr2serr("%s: %s ", __func__, wr ? "writing" : "reading");
- pr2serr(" SGQ_IO_FINISHED elem idx=%zd\n", rep - clp->elem);
-#endif
+ if (clp->debug > 5) {
+ pr2serr("%s: %s ", __func__, wr ? "writing" : "reading");
+ pr2serr(" SGQ_IO_FINISHED elem idx=%zd\n", rep - clp->elem);
+ }
return 0;
do_v4:
id = -1;
@@ -517,6 +589,10 @@ do_v4:
rep->state = SGQ_IO_ERR;
return res;
}
+ if (rep) {
+ if (rep->io_v4.flags & SGV4_FLAG_HIPRI)
+ ++clp->blk_poll_count;
+ }
if (! (rep && (SGQ_IO_STARTED == rep->state))) {
pr2serr("%s: bad usr_ptr=0x%p\n", __func__, (void *)rep);
if (rep)
@@ -542,7 +618,7 @@ do_v4:
case SG_LIB_CAT_UNIT_ATTENTION:
return 1;
default:
- sg_linux_sense_print(rep->wr ? "writing": "reading",
+ sg_linux_sense_print(wr ? "writing": "reading",
h4p->device_status, h4p->transport_status,
h4p->driver_status,
(const uint8_t *)(unsigned long)h4p->response,
@@ -554,15 +630,15 @@ do_v4:
++clp->dio_incomplete; /* count dios done as indirect IO */
clp->sum_of_resids += h4p->din_resid;
rep->state = SGQ_IO_FINISHED;
-#ifdef SG_DEBUG
- pr2serr("%s: %s ", __func__, wr ? "writing" : "reading");
- pr2serr(" SGQ_IO_FINISHED elem idx=%zd\n", rep - clp->elem);
- if (use_pack)
- pr2serr("%s: pack_id=%d\n", __func__, h4p->request_extra);
- else if (use_tag)
- pr2serr("%s: request_tag=0x%" PRIx64 "\n", __func__,
- (uint64_t)h4p->request_tag);
-#endif
+ if (clp->debug > 5) {
+ pr2serr("%s: %s ", __func__, wr ? "writing" : "reading");
+ pr2serr(" SGQ_IO_FINISHED elem idx=%zd\n", rep - clp->elem);
+ if (use_pack)
+ pr2serr("%s: pack_id=%d\n", __func__, h4p->request_extra);
+ else if (use_tag)
+ pr2serr("%s: request_tag=0x%" PRIx64 "\n", __func__,
+ (uint64_t)h4p->request_tag);
+ }
return 0;
}
@@ -581,11 +657,11 @@ sz_reserve(Rq_coll * clp, bool is_in)
seip = &sei;
res = ioctl(fd, SG_GET_VERSION_NUM, &t);
if ((res < 0) || (t < 30000)) {
- pr2serr("sgs_dd: sg driver prior to 3.0.00\n");
+ pr2serr("%s: sg driver prior to 3.0.00\n", my_name);
return 1;
} else if (t < 40000) {
if (vb)
- pr2serr("sgs_dd: warning: sg driver prior to 4.0.00\n");
+ pr2serr("%s: warning: sg driver prior to 4.0.00\n", my_name);
sgs_old_sg_driver = true;
} else if (t < 40045) {
sgs_old_sg_driver = false;
@@ -689,22 +765,50 @@ sz_reserve(Rq_coll * clp, bool is_in)
static int
init_elems(Rq_coll * clp)
{
- Rq_elem * rep;
+ bool either_mmap = false;
int res = 0;
+ int num_bytes = clp->bpt * clp->bs;
int k;
+ Rq_elem * rep;
clp->wr_posp = &clp->elem[0]; /* making ring buffer */
clp->rd_posp = clp->wr_posp;
- for (k = 0; k < SGQ_NUM_ELEMS - 1; ++k)
+ if (clp->iflag.mmap || clp->oflag.mmap) {
+ int res;
+
+ either_mmap = true;
+ sgq_num_elems = 2;
+ sgq_rd_ahead_lim = 1;
+ sgq_wr_ahead_lim = 1;
+ if (clp->iflag.mmap) {
+ res = get_mmap_addr(clp->infd, num_bytes, &clp->in_mmapp);
+ if (res < 0)
+ return res;
+ }
+ if (clp->oflag.mmap) {
+ res = get_mmap_addr(clp->outfd, num_bytes, &clp->out_mmapp);
+ if (res < 0)
+ return res;
+ }
+ }
+ for (k = 0; k < sgq_num_elems - 1; ++k)
clp->elem[k].nextp = &clp->elem[k + 1];
- clp->elem[SGQ_NUM_ELEMS - 1].nextp = &clp->elem[0];
- for (k = 0; k < SGQ_NUM_ELEMS; ++k) {
+ clp->elem[sgq_num_elems - 1].nextp = &clp->elem[0];
+ for (k = 0; k < sgq_num_elems; ++k) {
rep = &clp->elem[k];
rep->state = SGQ_FREE;
rep->iflagp = &clp->iflag;
rep->oflagp = &clp->oflag;
- rep->buffp = sg_memalign(clp->bpt * clp->bs, 0, &rep->free_buffp,
- false);
+ if (either_mmap) {
+ if (clp->both_mmap)
+ continue;
+ if (clp->iflag.mmap)
+ rep->buffp = clp->in_mmapp;
+ else
+ rep->buffp = clp->out_mmapp;
+ continue;
+ }
+ rep->buffp = sg_memalign(num_bytes, 0, &rep->free_buffp, false);
if (NULL == rep->buffp) {
pr2serr("out of memory creating user buffers\n");
res = -ENOMEM;
@@ -719,7 +823,7 @@ remove_elems(Rq_coll * clp)
Rq_elem * rep;
int k;
- for (k = 0; k < SGQ_NUM_ELEMS; ++k) {
+ for (k = 0; k < sgq_num_elems; ++k) {
rep = &clp->elem[k];
if (rep->free_buffp)
free(rep->free_buffp);
@@ -734,9 +838,8 @@ start_read(Rq_coll * clp)
int buf_sz, res;
char ebuff[EBUFF_SZ];
-#ifdef SG_DEBUG
- pr2serr("%s: elem idx=%zd\n", __func__, rep - clp->elem);
-#endif
+ if (clp->debug > 5)
+ pr2serr("%s: elem idx=%zd\n", __func__, rep - clp->elem);
rep->wr = false;
rep->blk = clp->in_blk;
rep->num_blks = blocks;
@@ -759,7 +862,8 @@ start_read(Rq_coll * clp)
res = -ENOMEM;
}
else if (res < 0) {
- pr2serr("sgs_dd inputting from sg failed, blk=%d\n", rep->blk);
+ pr2serr("%s: inputting from sg failed, blk=%d\n", my_name,
+ rep->blk);
rep->state = SGQ_IO_ERR;
return res;
}
@@ -771,7 +875,8 @@ start_read(Rq_coll * clp)
;
if (res < 0) {
res = -errno;
- snprintf(ebuff, EBUFF_SZ, "sgs_dd: reading, in_blk=%d ", rep->blk);
+ snprintf(ebuff, EBUFF_SZ, "%s: reading, in_blk=%d ", my_name,
+ rep->blk);
perror(ebuff);
rep->state = SGQ_IO_ERR;
return res;
@@ -810,9 +915,8 @@ start_write(Rq_coll * clp)
if (rep == clp->rd_posp)
return -1;
}
-#ifdef SG_DEBUG
- pr2serr("%s: elem idx=%zd\n", __func__, rep - clp->elem);
-#endif
+ if (clp->debug > 5)
+ pr2serr("%s: elem idx=%zd\n", __func__, rep - clp->elem);
rep->wr = true;
blocks = rep->num_blks;
rep->blk = clp->out_blk;
@@ -823,7 +927,7 @@ start_write(Rq_coll * clp)
if (1 == res) /* ENOMEM, give up */
return -ENOMEM;
else if (res < 0) {
- pr2serr("sgs_dd output to sg failed, blk=%d\n", rep->blk);
+ pr2serr("%s: output to sg failed, blk=%d\n", my_name, rep->blk);
rep->state = SGQ_IO_ERR;
return res;
}
@@ -835,7 +939,8 @@ start_write(Rq_coll * clp)
;
if (res < 0) {
res = -errno;
- snprintf(ebuff, EBUFF_SZ, "sgs_dd: output, out_blk=%d ", rep->blk);
+ snprintf(ebuff, EBUFF_SZ, "%s: output, out_blk=%d ", my_name,
+ rep->blk);
perror(ebuff);
rep->state = SGQ_IO_ERR;
return res;
@@ -863,14 +968,16 @@ do_sigwait(Rq_coll * clp, bool inc1_clear0)
if (clp->debug > 9)
pr2serr("%s: inc1_clear0=%d\n", __func__, (int)inc1_clear0);
- ts.tv_sec = 60; /* 60 second timeout */
- ts.tv_nsec = 0;
+ ts.tv_sec = 0;
+ ts.tv_nsec = DEF_SIGTIMEDWAIT_USEC * 1000;
while (sigtimedwait(&clp->blocked_sigs, &info, &ts) < 0) {
- if (EINTR != errno) {
- int err = errno;
+ int err = errno;
+
+ if (EINTR != err) {
- pr2serr("%s: sigtimedwait(): %s [%d]\n", __func__,
- strerror(err), err); /* EAGAIN is timeout */
+ if (EAGAIN != err)
+ pr2serr("%s: sigtimedwait(): %s [%d]\n", __func__,
+ strerror(err), err);
return -err; /* EAGAIN is timeout error */
}
}
@@ -905,7 +1012,7 @@ do_num_poll_in(Rq_coll * clp, int fd, bool is_evfd)
if (clp->sigs_waiting) {
int res = do_sigwait(clp, true);
- if (res < 0)
+ if ((res < 0) && (-EAGAIN != res))
return res;
}
}
@@ -1034,17 +1141,18 @@ can_read_write(Rq_coll * clp)
else
res = 0;
}
- if (clp->debug) {
- if ((clp->debug >= 9) || wr_waiting || rd_waiting)
+ if (clp->debug > 6) {
+ if ((clp->debug > 7) || wr_waiting || rd_waiting) {
pr2serr("%d/%d (nwb/nrb): read=%d/%d (do/wt) "
"write=%d/%d (do/wt) writeable=%d sg_fin=%d\n",
clp->out_blk, clp->in_blk, reading, rd_waiting,
writing, wr_waiting, (int)writeable, sg_finished);
- fflush(stdout);
+ }
+ // fflush(stdout);
}
- if (writeable && (writing < SGQ_MAX_WR_AHEAD) && (clp->out_count > 0))
+ if (writeable && (writing < sgq_wr_ahead_lim) && (clp->out_count > 0))
return SGQ_CAN_WRITE;
- if ((reading < SGQ_MAX_RD_AHEAD) && (clp->in_count > 0) &&
+ if ((reading < sgq_rd_ahead_lim) && (clp->in_count > 0) &&
(0 == rd_waiting) && (clp->rd_posp->nextp != clp->wr_posp))
return SGQ_CAN_READ;
@@ -1054,8 +1162,8 @@ can_read_write(Rq_coll * clp)
/* usleep(10000); */ /* hang about for 10 milliseconds */
if ((! clp->no_sig) && clp->sigs_waiting) {
res = do_sigwait(clp, false);
- if (res < 0)
- return res;
+ if ((res < 0) && (-EAGAIN != res))
+ return res; /* wasn't timeout */
}
/* Now check the _whole_ buffer for pending requests */
for (rep = clp->rd_posp->nextp; rep != clp->rd_posp; rep = rep->nextp) {
@@ -1081,7 +1189,7 @@ process_flags(const char * arg, struct flags_t * fp)
strncpy(buff, arg, sizeof(buff));
buff[sizeof(buff) - 1] = '\0';
if ('\0' == buff[0]) {
- pr2serr("no flag found\n");
+ pr2serr("no flag found, 'null' can be used as a placeholder\n");
return false;
}
cp = buff;
@@ -1095,6 +1203,8 @@ process_flags(const char * arg, struct flags_t * fp)
fp->evfd = true;
else if (0 == strcmp(cp, "excl"))
fp->excl = true;
+ else if (0 == strcmp(cp, "hipri"))
+ fp->hipri = true;
else if (0 == strcmp(cp, "immed"))
fp->immed = true;
else if (0 == strcmp(cp, "mmap"))
@@ -1110,16 +1220,26 @@ process_flags(const char * arg, struct flags_t * fp)
fp->pack = true;
else if (0 == strcmp(cp, "tag"))
fp->tag = true;
- else if (0 == strcmp(cp, "v3"))
+ else if (0 == strcmp(cp, "v3")) {
fp->v3 = true;
- else if (0 == strcmp(cp, "v4"))
+ fp->given_v3v4 = true;
+ } else if (0 == strcmp(cp, "v4")) {
fp->v4 = true;
- else {
+ fp->given_v3v4 = true;
+ } else {
pr2serr("unrecognised flag: %s\n", cp);
return false;
}
cp = np;
} while (cp);
+ if (fp->dio && fp->mmap) {
+ pr2serr(" Can't set both mmap and dio\n");
+ return false;
+ }
+ if ((fp->dio || fp->mmap) && fp->noxfer) {
+ pr2serr(" Can't have mmap or dio with noxfer\n");
+ return false;
+ }
return true;
}
@@ -1128,6 +1248,8 @@ int
main(int argc, char * argv[])
{
bool bs_given = false;
+ bool no_sig_given = false;
+ bool hipri_present;
int skip = 0;
int seek = 0;
int ibs = 0;
@@ -1184,19 +1306,20 @@ main(int argc, char * argv[])
inf[INOUTF_SZ - 1] = '\0';
} else if (0 == strcmp(key, "iflag")) {
if (! process_flags(buf, &clp->iflag)) {
- pr2serr("%sbad argument to 'iflag='\n", my_name);
+ pr2serr("%s: bad argument to 'iflag='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
- } else if (0 == strcmp(key,"no_sig"))
+ } else if (0 == strcmp(key,"no_sig")) { /* default changes */
clp->no_sig = !!sg_get_num(buf);
- else if (0 == strcmp(key,"obs"))
+ no_sig_given = true;
+ } else if (0 == strcmp(key,"obs"))
obs = sg_get_num(buf);
else if (strcmp(key,"of") == 0) {
memcpy(outf, buf, INOUTF_SZ);
outf[INOUTF_SZ - 1] = '\0';
} else if (0 == strcmp(key, "oflag")) {
if (! process_flags(buf, &clp->oflag)) {
- pr2serr("%sbad argument to 'oflag='\n", my_name);
+ pr2serr("%s: bad argument to 'oflag='\n", my_name);
return SG_LIB_SYNTAX_ERROR;
}
} else if (0 == strcmp(key,"poll_ms"))
@@ -1210,20 +1333,26 @@ main(int argc, char * argv[])
else if ((0 == strcmp(key,"-V")) || (0 == strcmp(key,"--version"))) {
pr2serr("%s: version: %s\n", my_name, version_str);
return 0;
- } else if (0 == strcmp(key,"-vvvv"))
- clp->debug +=4;
- else if (0 == strcmp(key,"-vvv"))
- clp->debug +=3;
- else if (0 == strcmp(key,"-vv"))
- clp->debug +=2;
- else if ((0 == strcmp(key,"-v")) || (0 == strcmp(key,"--verbose")))
+ } else if (0 == strncmp(key,"-vvvvvvv", 8))
+ clp->debug += 7;
+ else if (0 == strncmp(key,"-vvvvvv", 7))
+ clp->debug += 6;
+ else if (0 == strncmp(key,"-vvvvv", 6))
+ clp->debug += 5;
+ else if (0 == strncmp(key,"-vvvv", 5))
+ clp->debug += 4;
+ else if (0 == strncmp(key,"-vvv", 4))
+ clp->debug += 3;
+ else if (0 == strncmp(key,"-vv", 3))
+ clp->debug += 2;
+ else if ((0 == strcmp(key,"--verbose")) || (0 == strncmp(key,"-v", 2)))
++clp->debug;
else if (0 == strcmp(key,"-hhhh"))
- help_pg +=4;
+ help_pg += 4;
else if (0 == strcmp(key,"-hhh"))
- help_pg +=3;
+ help_pg += 3;
else if (0 == strcmp(key,"-hh"))
- help_pg +=2;
+ help_pg += 2;
else if ((0 == strcmp(key,"-h")) || (0 == strcmp(key,"--help")))
++help_pg;
else {
@@ -1242,6 +1371,13 @@ main(int argc, char * argv[])
return 0;
}
+ hipri_present = (clp->iflag.hipri || clp->oflag.hipri);
+ if (no_sig_given) {
+ if ((0 == clp->no_sig) && hipri_present)
+ pr2serr("Warning: signalling doesn't work with hipri\n");
+ } else /* no_sig default varies: 0 normally and 1 if hipri present */
+ clp->no_sig = hipri_present ? 1 : 0;
+
if ((ibs && (ibs != clp->bs)) || (obs && (obs != clp->bs))) {
pr2serr("If 'ibs' or 'obs' given must be same as 'bs'\n");
usage(1);
@@ -1258,13 +1394,15 @@ main(int argc, char * argv[])
pr2serr("Assume 'bs' (block size) of %d bytes\n", clp->bs);
if ((skip < 0) || (seek < 0)) {
- pr2serr("skip and seek cannot be negative\n");
+ pr2serr("%s: skip and seek cannot be negative\n", my_name);
return 1;
}
-#ifdef SG_DEBUG
- pr2serr("sgs_dd: if=%s skip=%d of=%s seek=%d count=%d\n",
- inf, skip, outf, seek, count);
-#endif
+ if (clp->iflag.mmap && clp->oflag.mmap)
+ clp->both_mmap = true;;
+
+ if (clp->debug > 3)
+ pr2serr("%s: if=%s skip=%d of=%s seek=%d count=%d\n", my_name,
+ inf, skip, outf, seek, count);
if (! clp->no_sig) {
/* Need to block signals before SIGPOLL is enabled in sz_reserve() */
sigemptyset(&clp->blocked_sigs);
@@ -1280,8 +1418,8 @@ main(int argc, char * argv[])
if (inf[0] && ('-' != inf[0])) {
open_fl = clp->iflag.excl ? O_EXCL : 0;
if ((clp->infd = open(inf, open_fl | O_RDONLY)) < 0) {
- snprintf(ebuff, EBUFF_SZ, "sgs_dd: could not open %s for reading",
- inf);
+ snprintf(ebuff, EBUFF_SZ, "%s: could not open %s for reading",
+ my_name, inf);
perror(ebuff);
return 1;
}
@@ -1292,8 +1430,8 @@ main(int argc, char * argv[])
offset *= clp->bs; /* could overflow here! */
if (lseek(clp->infd, offset, SEEK_SET) < 0) {
- snprintf(ebuff, EBUFF_SZ,
- "sgs_dd: couldn't skip to required position on %s", inf);
+ snprintf(ebuff, EBUFF_SZ, "%s: couldn't skip to required "
+ "position on %s", my_name, inf);
perror(ebuff);
return 1;
}
@@ -1343,7 +1481,7 @@ main(int argc, char * argv[])
open_fl |= (O_WRONLY | O_CREAT);
if ((clp->outfd = open(outf, open_fl, 0666)) < 0) {
snprintf(ebuff, EBUFF_SZ,
- "sgs_dd: could not open %s for writing", outf);
+ "%s: could not open %s for writing", my_name, outf);
perror(ebuff);
return 1;
}
@@ -1352,8 +1490,8 @@ main(int argc, char * argv[])
offset *= clp->bs; /* could overflow here! */
if (lseek(clp->outfd, offset, SEEK_SET) < 0) {
- snprintf(ebuff, EBUFF_SZ,
- "sgs_dd: couldn't seek to required position on %s", outf);
+ snprintf(ebuff, EBUFF_SZ, "%s: couldn't seek to required "
+ "position on %s", my_name, outf);
perror(ebuff);
return 1;
}
@@ -1378,6 +1516,11 @@ main(int argc, char * argv[])
return 1;
}
}
+ if ((clp->in_is_sg || clp->out_is_sg) && !clp->iflag.given_v3v4 &&
+ !clp->oflag.given_v3v4 && (clp->debug > 0))
+ pr2serr("using sg driver version 3 interface on %s\n",
+ clp->in_is_sg ? inf : outf);
+
if (0 == count)
return 0;
else if (count < 0) {
@@ -1390,8 +1533,10 @@ main(int argc, char * argv[])
if (0 != res) {
pr2serr("Unable to read capacity on %s\n", inf);
in_num_sect = -1;
- }
- else {
+ } else {
+ if (clp->debug > 4)
+ pr2serr("ifile: number of sectors=%d, sector size=%d\n",
+ in_num_sect, in_sect_sz);
if (in_num_sect > skip)
in_num_sect -= skip;
}
@@ -1405,16 +1550,17 @@ main(int argc, char * argv[])
if (0 != res) {
pr2serr("Unable to read capacity on %s\n", outf);
out_num_sect = -1;
- }
- else {
+ } else {
+ if (clp->debug > 4)
+ pr2serr("ofile: number of sectors=%d, sector size=%d\n",
+ out_num_sect, out_sect_sz);
if (out_num_sect > seek)
out_num_sect -= seek;
}
}
-#ifdef SG_DEBUG
- pr2serr("Start of loop, count=%d, in_num_sect=%d, out_num_sect=%d\n",
- count, in_num_sect, out_num_sect);
-#endif
+ if (clp->debug > 3)
+ pr2serr("Start of loop, count=%d, in_num_sect=%d, "
+ "out_num_sect=%d\n", count, in_num_sect, out_num_sect);
if (in_num_sect > 0) {
if (out_num_sect > 0)
count = (in_num_sect > out_num_sect) ? out_num_sect :
@@ -1425,10 +1571,8 @@ main(int argc, char * argv[])
else
count = out_num_sect;
}
-
-#ifdef SG_DEBUG
- pr2serr("Start of loop, count=%d, bpt=%d\n", count, clp->bpt);
-#endif
+ if (clp->debug > 4)
+ pr2serr("Start of loop, count=%d, bpt=%d\n", count, clp->bpt);
clp->in_count = count;
clp->in_done_count = count;
@@ -1480,9 +1624,14 @@ main(int argc, char * argv[])
if (clp->sum_of_resids)
pr2serr(">> Non-zero sum of residual counts=%d\n",
clp->sum_of_resids);
- if ((! clp->no_sig) && clp->debug > 0)
- pr2serr("SIGIO/SIGPOLL signals received: %d, RT sigs: %d\n",
- clp->sigs_io_received, clp->sigs_rt_received);
+ if (clp->debug > 0) {
+ if (! clp->no_sig)
+ pr2serr("SIGIO/SIGPOLL signals received: %d, RT sigs: %d\n",
+ clp->sigs_io_received, clp->sigs_rt_received);
+ if (hipri_present)
+ pr2serr("HIPRI (blk_poll) used to complete %d commands\n",
+ clp->blk_poll_count);
+ }
if (clp->pollerr_count > 0)
pr2serr(">> poll() system call gave POLLERR %d times\n",
clp->pollerr_count);