Avoid using bioq_* in gmirror.

gmirror does not perform any sorting of I/O requests, so the bioq API
doesn't provide any advantages over plain TAILQs. The API also does not
provide operations needed by an upcoming change.

No functional change intended. The diff shrinks the geom_mirror.ko
text and the gmirror softc slightly.

Tested by:	pho (part of a larger patch)
MFC after:	1 week
Sponsored by:	Dell EMC Isilon
This commit is contained in:
Mark Johnston 2017-12-19 17:13:04 +00:00
parent 22fd1b5dc6
commit 9abe2e7e98
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=326983
2 changed files with 58 additions and 49 deletions

View file

@ -307,7 +307,7 @@ g_mirror_nrequests(struct g_mirror_softc *sc, struct g_consumer *cp)
u_int nreqs = 0;
mtx_lock(&sc->sc_queue_mtx);
TAILQ_FOREACH(bp, &sc->sc_queue.queue, bio_queue) {
TAILQ_FOREACH(bp, &sc->sc_queue, bio_queue) {
if (bp->bio_from == cp)
nreqs++;
}
@ -920,7 +920,7 @@ g_mirror_done(struct bio *bp)
sc = bp->bio_from->geom->softc;
bp->bio_cflags = G_MIRROR_BIO_FLAG_REGULAR;
mtx_lock(&sc->sc_queue_mtx);
bioq_insert_tail(&sc->sc_queue, bp);
TAILQ_INSERT_TAIL(&sc->sc_queue, bp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
wakeup(sc);
}
@ -965,7 +965,7 @@ g_mirror_regular_request(struct bio *bp)
pbp->bio_completed = pbp->bio_length;
if (pbp->bio_cmd == BIO_WRITE ||
pbp->bio_cmd == BIO_DELETE) {
bioq_remove(&sc->sc_inflight, pbp);
TAILQ_REMOVE(&sc->sc_inflight, pbp, bio_queue);
/* Release delayed sync requests if possible. */
g_mirror_sync_release(sc);
}
@ -1020,7 +1020,7 @@ g_mirror_regular_request(struct bio *bp)
else {
pbp->bio_error = 0;
mtx_lock(&sc->sc_queue_mtx);
bioq_insert_tail(&sc->sc_queue, pbp);
TAILQ_INSERT_TAIL(&sc->sc_queue, pbp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc);
wakeup(sc);
@ -1040,7 +1040,7 @@ g_mirror_regular_request(struct bio *bp)
pbp->bio_error = 0;
pbp->bio_completed = pbp->bio_length;
}
bioq_remove(&sc->sc_inflight, pbp);
TAILQ_REMOVE(&sc->sc_inflight, pbp, bio_queue);
/* Release delayed sync requests if possible. */
g_mirror_sync_release(sc);
g_io_deliver(pbp, pbp->bio_error);
@ -1060,7 +1060,7 @@ g_mirror_sync_done(struct bio *bp)
sc = bp->bio_from->geom->softc;
bp->bio_cflags = G_MIRROR_BIO_FLAG_SYNC;
mtx_lock(&sc->sc_queue_mtx);
bioq_insert_tail(&sc->sc_queue, bp);
TAILQ_INSERT_TAIL(&sc->sc_queue, bp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
wakeup(sc);
}
@ -1117,30 +1117,33 @@ g_mirror_kernel_dump(struct bio *bp)
static void
g_mirror_flush(struct g_mirror_softc *sc, struct bio *bp)
{
struct bio_queue_head queue;
struct bio_queue queue;
struct g_mirror_disk *disk;
struct g_consumer *cp;
struct bio *cbp;
bioq_init(&queue);
TAILQ_INIT(&queue);
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
continue;
cbp = g_clone_bio(bp);
if (cbp == NULL) {
while ((cbp = bioq_takefirst(&queue)) != NULL)
while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
TAILQ_REMOVE(&queue, cbp, bio_queue);
g_destroy_bio(cbp);
}
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_io_deliver(bp, bp->bio_error);
return;
}
bioq_insert_tail(&queue, cbp);
TAILQ_INSERT_TAIL(&queue, cbp, bio_queue);
cbp->bio_done = g_mirror_flush_done;
cbp->bio_caller1 = disk;
cbp->bio_to = disk->d_consumer->provider;
}
while ((cbp = bioq_takefirst(&queue)) != NULL) {
while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
TAILQ_REMOVE(&queue, cbp, bio_queue);
G_MIRROR_LOGREQ(3, cbp, "Sending request.");
disk = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
@ -1194,7 +1197,7 @@ g_mirror_start(struct bio *bp)
g_io_deliver(bp, bp->bio_to->error);
return;
}
bioq_insert_tail(&sc->sc_queue, bp);
TAILQ_INSERT_TAIL(&sc->sc_queue, bp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
G_MIRROR_DEBUG(4, "%s: Waking up %p.", __func__, sc);
wakeup(sc);
@ -1246,7 +1249,7 @@ g_mirror_regular_collision(struct g_mirror_softc *sc, struct bio *sbp)
return (false);
sstart = sbp->bio_offset;
send = sbp->bio_offset + sbp->bio_length;
TAILQ_FOREACH(bp, &sc->sc_inflight.queue, bio_queue) {
TAILQ_FOREACH(bp, &sc->sc_inflight, bio_queue) {
rstart = bp->bio_offset;
rend = bp->bio_offset + bp->bio_length;
if (rend > sstart && rstart < send)
@ -1263,7 +1266,7 @@ g_mirror_regular_delay(struct g_mirror_softc *sc, struct bio *bp)
{
G_MIRROR_LOGREQ(2, bp, "Delaying request.");
bioq_insert_head(&sc->sc_regular_delayed, bp);
TAILQ_INSERT_HEAD(&sc->sc_regular_delayed, bp, bio_queue);
}
/*
@ -1274,7 +1277,7 @@ g_mirror_sync_delay(struct g_mirror_softc *sc, struct bio *bp)
{
G_MIRROR_LOGREQ(2, bp, "Delaying synchronization request.");
bioq_insert_tail(&sc->sc_sync_delayed, bp);
TAILQ_INSERT_TAIL(&sc->sc_sync_delayed, bp, bio_queue);
}
/*
@ -1286,13 +1289,13 @@ g_mirror_regular_release(struct g_mirror_softc *sc)
{
struct bio *bp, *bp2;
TAILQ_FOREACH_SAFE(bp, &sc->sc_regular_delayed.queue, bio_queue, bp2) {
TAILQ_FOREACH_SAFE(bp, &sc->sc_regular_delayed, bio_queue, bp2) {
if (g_mirror_sync_collision(sc, bp))
continue;
bioq_remove(&sc->sc_regular_delayed, bp);
TAILQ_REMOVE(&sc->sc_regular_delayed, bp, bio_queue);
G_MIRROR_LOGREQ(2, bp, "Releasing delayed request (%p).", bp);
mtx_lock(&sc->sc_queue_mtx);
bioq_insert_head(&sc->sc_queue, bp);
TAILQ_INSERT_HEAD(&sc->sc_queue, bp, bio_queue);
mtx_unlock(&sc->sc_queue_mtx);
}
}
@ -1306,10 +1309,10 @@ g_mirror_sync_release(struct g_mirror_softc *sc)
{
struct bio *bp, *bp2;
TAILQ_FOREACH_SAFE(bp, &sc->sc_sync_delayed.queue, bio_queue, bp2) {
TAILQ_FOREACH_SAFE(bp, &sc->sc_sync_delayed, bio_queue, bp2) {
if (g_mirror_regular_collision(sc, bp))
continue;
bioq_remove(&sc->sc_sync_delayed, bp);
TAILQ_REMOVE(&sc->sc_sync_delayed, bp, bio_queue);
G_MIRROR_LOGREQ(2, bp,
"Releasing delayed synchronization request.");
g_io_request(bp, bp->bio_from);
@ -1615,7 +1618,7 @@ g_mirror_request_load(struct g_mirror_softc *sc, struct bio *bp)
static void
g_mirror_request_split(struct g_mirror_softc *sc, struct bio *bp)
{
struct bio_queue_head queue;
struct bio_queue queue;
struct g_mirror_disk *disk;
struct g_consumer *cp;
struct bio *cbp;
@ -1639,20 +1642,22 @@ g_mirror_request_split(struct g_mirror_softc *sc, struct bio *bp)
left = bp->bio_length;
offset = bp->bio_offset;
data = bp->bio_data;
bioq_init(&queue);
TAILQ_INIT(&queue);
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
if (disk->d_state != G_MIRROR_DISK_STATE_ACTIVE)
continue;
cbp = g_clone_bio(bp);
if (cbp == NULL) {
while ((cbp = bioq_takefirst(&queue)) != NULL)
while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
TAILQ_REMOVE(&queue, cbp, bio_queue);
g_destroy_bio(cbp);
}
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_io_deliver(bp, bp->bio_error);
return;
}
bioq_insert_tail(&queue, cbp);
TAILQ_INSERT_TAIL(&queue, cbp, bio_queue);
cbp->bio_done = g_mirror_done;
cbp->bio_caller1 = disk;
cbp->bio_to = disk->d_consumer->provider;
@ -1665,7 +1670,8 @@ g_mirror_request_split(struct g_mirror_softc *sc, struct bio *bp)
offset += cbp->bio_length;
data += cbp->bio_length;
}
while ((cbp = bioq_takefirst(&queue)) != NULL) {
while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
TAILQ_REMOVE(&queue, cbp, bio_queue);
G_MIRROR_LOGREQ(3, cbp, "Sending request.");
disk = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
@ -1704,9 +1710,9 @@ g_mirror_register_request(struct bio *bp)
case BIO_WRITE:
case BIO_DELETE:
{
struct bio_queue queue;
struct g_mirror_disk *disk;
struct g_mirror_disk_sync *sync;
struct bio_queue_head queue;
struct g_consumer *cp;
struct bio *cbp;
@ -1736,7 +1742,7 @@ g_mirror_register_request(struct bio *bp)
* Allocate all bios before sending any request, so we can
* return ENOMEM in nice and clean way.
*/
bioq_init(&queue);
TAILQ_INIT(&queue);
LIST_FOREACH(disk, &sc->sc_disks, d_next) {
sync = &disk->d_sync;
switch (disk->d_state) {
@ -1754,14 +1760,16 @@ g_mirror_register_request(struct bio *bp)
continue;
cbp = g_clone_bio(bp);
if (cbp == NULL) {
while ((cbp = bioq_takefirst(&queue)) != NULL)
while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
TAILQ_REMOVE(&queue, cbp, bio_queue);
g_destroy_bio(cbp);
}
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_io_deliver(bp, bp->bio_error);
return;
}
bioq_insert_tail(&queue, cbp);
TAILQ_INSERT_TAIL(&queue, cbp, bio_queue);
cbp->bio_done = g_mirror_done;
cp = disk->d_consumer;
cbp->bio_caller1 = cp;
@ -1770,12 +1778,13 @@ g_mirror_register_request(struct bio *bp)
("Consumer %s not opened (r%dw%de%d).",
cp->provider->name, cp->acr, cp->acw, cp->ace));
}
if (bioq_first(&queue) == NULL) {
if (TAILQ_EMPTY(&queue)) {
g_io_deliver(bp, EOPNOTSUPP);
return;
}
while ((cbp = bioq_takefirst(&queue)) != NULL) {
while ((cbp = TAILQ_FIRST(&queue)) != NULL) {
G_MIRROR_LOGREQ(3, cbp, "Sending request.");
TAILQ_REMOVE(&queue, cbp, bio_queue);
cp = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
cp->index++;
@ -1786,7 +1795,7 @@ g_mirror_register_request(struct bio *bp)
* Put request onto inflight queue, so we can check if new
* synchronization requests don't collide with it.
*/
bioq_insert_tail(&sc->sc_inflight, bp);
TAILQ_INSERT_TAIL(&sc->sc_inflight, bp, bio_queue);
return;
}
default:
@ -1929,8 +1938,10 @@ g_mirror_worker(void *arg)
*/
/* Get first request from the queue. */
mtx_lock(&sc->sc_queue_mtx);
bp = bioq_takefirst(&sc->sc_queue);
if (bp == NULL) {
bp = TAILQ_FIRST(&sc->sc_queue);
if (bp != NULL)
TAILQ_REMOVE(&sc->sc_queue, bp, bio_queue);
else {
if ((sc->sc_flags &
G_MIRROR_DEVICE_FLAG_DESTROY) != 0) {
mtx_unlock(&sc->sc_queue_mtx);
@ -1940,7 +1951,7 @@ g_mirror_worker(void *arg)
kproc_exit(0);
}
mtx_lock(&sc->sc_queue_mtx);
if (bioq_first(&sc->sc_queue) != NULL) {
if (!TAILQ_EMPTY(&sc->sc_queue)) {
mtx_unlock(&sc->sc_queue_mtx);
continue;
}
@ -2190,7 +2201,8 @@ g_mirror_destroy_provider(struct g_mirror_softc *sc)
g_topology_lock();
g_error_provider(sc->sc_provider, ENXIO);
mtx_lock(&sc->sc_queue_mtx);
while ((bp = bioq_takefirst(&sc->sc_queue)) != NULL) {
while ((bp = TAILQ_FIRST(&sc->sc_queue)) != NULL) {
TAILQ_REMOVE(&sc->sc_queue, bp, bio_queue);
/*
* Abort any pending I/O that wasn't generated by us.
* Synchronization requests and requests destined for individual
@ -3009,11 +3021,11 @@ g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md,
sc->sc_writes = 0;
sc->sc_refcnt = 1;
sx_init(&sc->sc_lock, "gmirror:lock");
bioq_init(&sc->sc_queue);
TAILQ_INIT(&sc->sc_queue);
mtx_init(&sc->sc_queue_mtx, "gmirror:queue", NULL, MTX_DEF);
bioq_init(&sc->sc_regular_delayed);
bioq_init(&sc->sc_inflight);
bioq_init(&sc->sc_sync_delayed);
TAILQ_INIT(&sc->sc_regular_delayed);
TAILQ_INIT(&sc->sc_inflight);
TAILQ_INIT(&sc->sc_sync_delayed);
LIST_INIT(&sc->sc_disks);
TAILQ_INIT(&sc->sc_events);
mtx_init(&sc->sc_events_mtx, "gmirror:events", NULL, MTX_DEF);

View file

@ -193,17 +193,14 @@ struct g_mirror_softc {
uint32_t sc_id; /* Mirror unique ID. */
struct sx sc_lock;
struct bio_queue_head sc_queue;
struct bio_queue sc_queue;
struct mtx sc_queue_mtx;
struct proc *sc_worker;
struct bio_queue_head sc_regular_delayed; /* Delayed I/O requests due
collision with sync
requests. */
struct bio_queue_head sc_inflight; /* In-flight regular write
requests. */
struct bio_queue_head sc_sync_delayed; /* Delayed sync requests due
collision with regular
requests. */
struct bio_queue sc_inflight; /* In-flight regular write requests. */
struct bio_queue sc_regular_delayed; /* Delayed I/O requests due to
collision with sync requests. */
struct bio_queue sc_sync_delayed; /* Delayed sync requests due to
collision with regular requests. */
LIST_HEAD(, g_mirror_disk) sc_disks;
u_int sc_ndisks; /* Number of disks. */