summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorjsing <jsing@openbsd.org>2013-03-27 14:30:11 +0000
committerjsing <jsing@openbsd.org>2013-03-27 14:30:11 +0000
commit2b14bff0c4b4d0087305b613115ceaa8ff203764 (patch)
treee86338f5e145a067fab1591bb5dbeff0d8edfcfb /sys
parentUse the correct src/dst ports depending on direction (one of src or dst was (diff)
downloadwireguard-openbsd-2b14bff0c4b4d0087305b613115ceaa8ff203764.tar.xz
wireguard-openbsd-2b14bff0c4b4d0087305b613115ceaa8ff203764.zip
Rewrite the work unit handling code in the RAID 1/4/5/6 interrupt handlers.
This simplifies the code and will allow for easier conversion to the workq based work unit completion routines. It also ensures that work units are always removed from the pending queue and that colliders are started, even in the event of an I/O failure. ok krw@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/softraid_raid1.c121
-rw-r--r--sys/dev/softraid_raid6.c128
-rw-r--r--sys/dev/softraid_raidp.c126
3 files changed, 161 insertions, 214 deletions
diff --git a/sys/dev/softraid_raid1.c b/sys/dev/softraid_raid1.c
index d430ae10a4c..5a281112f52 100644
--- a/sys/dev/softraid_raid1.c
+++ b/sys/dev/softraid_raid1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_raid1.c,v 1.42 2013/03/25 16:01:49 jsing Exp $ */
+/* $OpenBSD: softraid_raid1.c,v 1.43 2013/03/27 14:30:11 jsing Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
*
@@ -470,7 +470,7 @@ sr_raid1_intr(struct buf *bp)
struct sr_discipline *sd = wu->swu_dis;
struct scsi_xfer *xs = wu->swu_xs;
struct sr_softc *sc = sd->sd_sc;
- int s, pend;
+ int s;
DNPRINTF(SR_D_INTR, "%s: sr_intr bp %x xs %x\n",
DEVNAME(sc), bp, xs);
@@ -483,84 +483,67 @@ sr_raid1_intr(struct buf *bp)
DEVNAME(sc), wu->swu_ios_complete, wu->swu_io_count,
wu->swu_ios_failed);
- if (wu->swu_ios_complete >= wu->swu_io_count) {
- /* if all ios failed, retry reads and give up on writes */
- if (wu->swu_ios_failed == wu->swu_ios_complete) {
- if (xs->flags & SCSI_DATA_IN) {
- printf("%s: retrying read on block %lld\n",
- DEVNAME(sc), ccb->ccb_buf.b_blkno);
- sr_ccb_put(ccb);
- if (wu->swu_cb_active == 1)
- panic("%s: sr_raid1_intr_cb",
- DEVNAME(sd->sd_sc));
- TAILQ_INIT(&wu->swu_ccb);
- wu->swu_state = SR_WU_RESTART;
- if (sd->sd_scsi_rw(wu))
- goto bad;
- else
- goto retry;
- } else {
- printf("%s: permanently fail write on block "
- "%lld\n", DEVNAME(sc),
- ccb->ccb_buf.b_blkno);
- xs->error = XS_DRIVER_STUFFUP;
- goto bad;
- }
- }
-
- xs->error = XS_NOERROR;
-
- pend = 0;
- TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) {
- if (wu == wup) {
- /* wu on pendq, remove */
- TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
- pend = 1;
-
- if (wu->swu_collider) {
- if (wu->swu_ios_failed)
- /* toss all ccbs and recreate */
- sr_raid_recreate_wu(wu->swu_collider);
-
- /* restart deferred wu */
- wu->swu_collider->swu_state =
- SR_WU_INPROGRESS;
- TAILQ_REMOVE(&sd->sd_wu_defq,
- wu->swu_collider, swu_link);
- sr_raid_startwu(wu->swu_collider);
- }
- break;
- }
- }
+ if (wu->swu_ios_complete < wu->swu_io_count)
+ goto done;
- if (!pend)
- printf("%s: wu: %p not on pending queue\n",
- DEVNAME(sc), wu);
+ xs->error = XS_NOERROR;
- if (wu->swu_flags & SR_WUF_REBUILD) {
- if (wu->swu_xs->flags & SCSI_DATA_OUT) {
- wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
- wakeup(wu);
- }
+ /* if all ios failed, retry reads and give up on writes */
+ if (wu->swu_ios_failed == wu->swu_ios_complete) {
+ if (xs->flags & SCSI_DATA_IN) {
+ printf("%s: retrying read on block %lld\n",
+ DEVNAME(sc), ccb->ccb_buf.b_blkno);
+ sr_ccb_put(ccb);
+ if (wu->swu_cb_active == 1)
+ panic("%s: sr_raid1_intr_cb",
+ DEVNAME(sd->sd_sc));
+ TAILQ_INIT(&wu->swu_ccb);
+ wu->swu_state = SR_WU_RESTART;
+ if (sd->sd_scsi_rw(wu) == 0)
+ goto done;
+ xs->error = XS_DRIVER_STUFFUP;
} else {
- sr_scsi_done(sd, xs);
+ printf("%s: permanently failing write on block %lld\n",
+ DEVNAME(sc), ccb->ccb_buf.b_blkno);
+ xs->error = XS_DRIVER_STUFFUP;
}
+ }
+
+ TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link)
+ if (wu == wup)
+ break;
+
+ if (wup == NULL)
+ panic("%s: wu %p not on pending queue",
+ DEVNAME(sd->sd_sc), wu);
+
+ /* wu on pendq, remove */
+ TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
+
+ if (wu->swu_collider) {
+ if (wu->swu_ios_failed)
+ sr_raid_recreate_wu(wu->swu_collider);
- if (sd->sd_sync && sd->sd_wu_pending == 0)
- wakeup(sd);
+ /* XXX Should the collider be failed if this xs failed? */
+ /* restart deferred wu */
+ wu->swu_collider->swu_state = SR_WU_INPROGRESS;
+ TAILQ_REMOVE(&sd->sd_wu_defq, wu->swu_collider, swu_link);
+ sr_raid_startwu(wu->swu_collider);
}
-retry:
- splx(s);
- return;
-bad:
- xs->error = XS_DRIVER_STUFFUP;
if (wu->swu_flags & SR_WUF_REBUILD) {
- wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
- wakeup(wu);
+ /* XXX - decouple from SCSI_DATA_OUT. */
+ if (wu->swu_xs->flags & SCSI_DATA_OUT) {
+ wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
+ wakeup(wu);
+ }
} else {
sr_scsi_done(sd, xs);
}
+ if (sd->sd_sync && sd->sd_wu_pending == 0)
+ wakeup(sd);
+
+done:
splx(s);
}
diff --git a/sys/dev/softraid_raid6.c b/sys/dev/softraid_raid6.c
index 0904859cea1..7a29fd0772f 100644
--- a/sys/dev/softraid_raid6.c
+++ b/sys/dev/softraid_raid6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_raid6.c,v 1.35 2013/03/25 16:01:49 jsing Exp $ */
+/* $OpenBSD: softraid_raid6.c,v 1.36 2013/03/27 14:30:11 jsing Exp $ */
/*
* Copyright (c) 2009 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2009 Jordan Hargrave <jordan@openbsd.org>
@@ -719,7 +719,7 @@ sr_raid6_intr(struct buf *bp)
struct scsi_xfer *xs = wu->swu_xs;
struct sr_softc *sc = sd->sd_sc;
struct sr_raid6_opaque *pq = ccb->ccb_opaque;
- int s, pend;
+ int s;
DNPRINTF(SR_D_INTR, "%s: sr_intr bp %p xs %p\n",
DEVNAME(sc), bp, xs);
@@ -772,88 +772,70 @@ sr_raid6_intr(struct buf *bp)
DEVNAME(sc), wu->swu_ios_complete, wu->swu_io_count,
wu->swu_ios_failed);
- if (wu->swu_ios_complete >= wu->swu_io_count) {
-
- /* if all ios failed, retry reads and give up on writes */
- if (wu->swu_ios_failed == wu->swu_ios_complete) {
- if (xs->flags & SCSI_DATA_IN) {
- printf("%s: retrying read on block %lld\n",
- DEVNAME(sc), ccb->ccb_buf.b_blkno);
- sr_ccb_put(ccb);
- TAILQ_INIT(&wu->swu_ccb);
- wu->swu_state = SR_WU_RESTART;
- if (sd->sd_scsi_rw(wu))
- goto bad;
- else
- goto retry;
- } else {
- printf("%s: permanently fail write on block "
- "%lld\n", DEVNAME(sc),
- ccb->ccb_buf.b_blkno);
- xs->error = XS_DRIVER_STUFFUP;
- goto bad;
- }
- }
-
- if (xs != NULL)
- xs->error = XS_NOERROR;
-
- pend = 0;
- TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) {
- if (wu == wup) {
- /* wu on pendq, remove */
- TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
- pend = 1;
-
- if (wu->swu_collider) {
- if (wu->swu_ios_failed)
- /* toss all ccbs and recreate */
- sr_raid_recreate_wu(wu->swu_collider);
-
- /* restart deferred wu */
- wu->swu_collider->swu_state =
- SR_WU_INPROGRESS;
- TAILQ_REMOVE(&sd->sd_wu_defq,
- wu->swu_collider, swu_link);
- if (sr_failio(wu->swu_collider) == 0)
- sr_raid_startwu(wu->swu_collider);
- }
- break;
- }
- }
+ if (wu->swu_ios_complete < wu->swu_io_count)
+ goto done;
- if (!pend)
- printf("%s: wu: %p not on pending queue\n",
- DEVNAME(sc), wu);
+ if (xs != NULL)
+ xs->error = XS_NOERROR;
- if (wu->swu_flags & SR_WUF_REBUILD) {
- if (wu->swu_xs->flags & SCSI_DATA_OUT) {
- wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
- wakeup(wu);
- }
+ /* if all ios failed, retry reads and give up on writes */
+ if (wu->swu_ios_failed == wu->swu_ios_complete) {
+ /* XXX xs could be NULL. */
+ if (xs->flags & SCSI_DATA_IN) {
+ printf("%s: retrying read on block %lld\n",
+ DEVNAME(sc), ccb->ccb_buf.b_blkno);
+ sr_ccb_put(ccb);
+ TAILQ_INIT(&wu->swu_ccb);
+ wu->swu_state = SR_WU_RESTART;
+ if (sd->sd_scsi_rw(wu) == 0)
+ goto done;
+ xs->error = XS_DRIVER_STUFFUP;
} else {
- if (xs != NULL)
- sr_scsi_done(sd, xs);
- else
- scsi_io_put(&sd->sd_iopool, wu);
+ printf("%s: permanently fail write on block %lld\n",
+ DEVNAME(sc), ccb->ccb_buf.b_blkno);
+ xs->error = XS_DRIVER_STUFFUP;
}
+ }
+
+ TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link)
+ if (wu == wup)
+ break;
+
+ if (wup == NULL)
+ panic("%s: wu %p not on pending queue",
+ DEVNAME(sd->sd_sc), wu);
+
+ TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
+
+ if (wu->swu_collider) {
+ if (wu->swu_ios_failed)
+ sr_raid_recreate_wu(wu->swu_collider);
- if (sd->sd_sync && sd->sd_wu_pending == 0)
- wakeup(sd);
+ /* XXX Should the collider be failed if this xs failed? */
+ /* restart deferred wu */
+ wu->swu_collider->swu_state = SR_WU_INPROGRESS;
+ TAILQ_REMOVE(&sd->sd_wu_defq, wu->swu_collider, swu_link);
+ if (sr_failio(wu->swu_collider) == 0)
+ sr_raid_startwu(wu->swu_collider);
}
-retry:
- splx(s);
- return;
-bad:
- xs->error = XS_DRIVER_STUFFUP;
if (wu->swu_flags & SR_WUF_REBUILD) {
- wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
- wakeup(wu);
+ /* XXX - decouple from SCSI_DATA_OUT. */
+ if (wu->swu_xs->flags & SCSI_DATA_OUT) {
+ wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
+ wakeup(wu);
+ }
} else {
- sr_scsi_done(sd, xs);
+ if (xs != NULL)
+ sr_scsi_done(sd, xs);
+ else
+ scsi_io_put(&sd->sd_iopool, wu);
}
+ if (sd->sd_sync && sd->sd_wu_pending == 0)
+ wakeup(sd);
+
+done:
splx(s);
}
diff --git a/sys/dev/softraid_raidp.c b/sys/dev/softraid_raidp.c
index 73918d3d66d..2b69dec5515 100644
--- a/sys/dev/softraid_raidp.c
+++ b/sys/dev/softraid_raidp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_raidp.c,v 1.32 2013/03/25 16:01:49 jsing Exp $ */
+/* $OpenBSD: softraid_raidp.c,v 1.33 2013/03/27 14:30:11 jsing Exp $ */
/*
* Copyright (c) 2009 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2009 Jordan Hargrave <jordan@openbsd.org>
@@ -546,7 +546,7 @@ sr_raidp_intr(struct buf *bp)
struct sr_discipline *sd = wu->swu_dis;
struct scsi_xfer *xs = wu->swu_xs;
struct sr_softc *sc = sd->sd_sc;
- int s, pend;
+ int s;
DNPRINTF(SR_D_INTR, "%s: sr_intr bp %p xs %p\n",
DEVNAME(sc), bp, xs);
@@ -589,87 +589,69 @@ sr_raidp_intr(struct buf *bp)
DEVNAME(sc), wu->swu_ios_complete, wu->swu_io_count,
wu->swu_ios_failed);
- if (wu->swu_ios_complete >= wu->swu_io_count) {
-
- /* if all ios failed, retry reads and give up on writes */
- if (wu->swu_ios_failed == wu->swu_ios_complete) {
- if (xs->flags & SCSI_DATA_IN) {
- printf("%s: retrying read on block %lld\n",
- DEVNAME(sc), ccb->ccb_buf.b_blkno);
- sr_ccb_put(ccb);
- TAILQ_INIT(&wu->swu_ccb);
- wu->swu_state = SR_WU_RESTART;
- if (sd->sd_scsi_rw(wu))
- goto bad;
- else
- goto retry;
- } else {
- printf("%s: permanently fail write on block "
- "%lld\n", DEVNAME(sc),
- ccb->ccb_buf.b_blkno);
- xs->error = XS_DRIVER_STUFFUP;
- goto bad;
- }
- }
-
- if (xs != NULL)
- xs->error = XS_NOERROR;
-
- pend = 0;
- TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) {
- if (wu == wup) {
- /* wu on pendq, remove */
- TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
- pend = 1;
-
- if (wu->swu_collider) {
- if (wu->swu_ios_failed)
- /* toss all ccbs and recreate */
- sr_raid_recreate_wu(wu->swu_collider);
-
- /* restart deferred wu */
- wu->swu_collider->swu_state =
- SR_WU_INPROGRESS;
- TAILQ_REMOVE(&sd->sd_wu_defq,
- wu->swu_collider, swu_link);
- sr_raid_startwu(wu->swu_collider);
- }
- break;
- }
- }
+ if (wu->swu_ios_complete < wu->swu_io_count)
+ goto done;
- if (!pend)
- printf("%s: wu: %p not on pending queue\n",
- DEVNAME(sc), wu);
+ if (xs != NULL)
+ xs->error = XS_NOERROR;
- if (wu->swu_flags & SR_WUF_REBUILD) {
- if (wu->swu_xs->flags & SCSI_DATA_OUT) {
- wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
- wakeup(wu);
- }
+ /* if all ios failed, retry reads and give up on writes */
+ if (wu->swu_ios_failed == wu->swu_ios_complete) {
+ /* XXX xs could be NULL here. */
+ if (xs->flags & SCSI_DATA_IN) {
+ printf("%s: retrying read on block %lld\n",
+ DEVNAME(sc), ccb->ccb_buf.b_blkno);
+ sr_ccb_put(ccb);
+ TAILQ_INIT(&wu->swu_ccb);
+ wu->swu_state = SR_WU_RESTART;
+ if (sd->sd_scsi_rw(wu) == 0)
+ goto done;
+ xs->error = XS_DRIVER_STUFFUP;
} else {
- if (xs != NULL)
- sr_scsi_done(sd, xs);
- else
- scsi_io_put(&sd->sd_iopool, wu);
+ printf("%s: permanently fail write on block %lld\n",
+ DEVNAME(sc), ccb->ccb_buf.b_blkno);
+ xs->error = XS_DRIVER_STUFFUP;
}
+ }
- if (sd->sd_sync && sd->sd_wu_pending == 0)
- wakeup(sd);
+ TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link)
+ if (wu == wup)
+ break;
+
+ if (wup == NULL)
+ panic("%s: wu %p not on pending queue",
+ DEVNAME(sd->sd_sc), wu);
+
+ TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
+
+ if (wu->swu_collider) {
+ if (wu->swu_ios_failed)
+ sr_raid_recreate_wu(wu->swu_collider);
+
+ /* XXX Should the collider be failed if this xs failed? */
+ /* restart deferred wu */
+ wu->swu_collider->swu_state = SR_WU_INPROGRESS;
+ TAILQ_REMOVE(&sd->sd_wu_defq, wu->swu_collider, swu_link);
+ sr_raid_startwu(wu->swu_collider);
}
-retry:
- splx(s);
- return;
-bad:
- xs->error = XS_DRIVER_STUFFUP;
if (wu->swu_flags & SR_WUF_REBUILD) {
- wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
- wakeup(wu);
+ /* XXX - decouple from SCSI_DATA_OUT. */
+ if (wu->swu_xs->flags & SCSI_DATA_OUT) {
+ wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
+ wakeup(wu);
+ }
} else {
- sr_scsi_done(sd, xs);
+ if (xs != NULL)
+ sr_scsi_done(sd, xs);
+ else
+ scsi_io_put(&sd->sd_iopool, wu);
}
+ if (sd->sd_sync && sd->sd_wu_pending == 0)
+ wakeup(sd);
+
+done:
splx(s);
}