diff options
author | Thordur I. Bjornsson <thib@cvs.openbsd.org> | 2009-06-03 22:09:31 +0000 |
---|---|---|
committer | Thordur I. Bjornsson <thib@cvs.openbsd.org> | 2009-06-03 22:09:31 +0000 |
commit | b25274aac4d1fef726702d299f285d361d17febc (patch) | |
tree | bf0a0eecf0269cbaf678c70381c20b040e57ed02 /sys | |
parent | b96794b04ab20a0aba439e48813238555739661d (diff) |
add a flexible buffer queue (bufq) api, based on the never used
one by tedu@. It doesn't do anything smart yet, it just uses
plain old disksort. we also keep the old method of queueing bufs
since some miods have crazy MD drivers that need some love.
ok beck@, art@
tested by many on many archs.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/conf/files | 3 | ||||
-rw-r--r-- | sys/ddb/db_command.c | 17 | ||||
-rw-r--r-- | sys/ddb/db_command.h | 3 | ||||
-rw-r--r-- | sys/ddb/db_interface.h | 6 | ||||
-rw-r--r-- | sys/dev/ata/wd.c | 18 | ||||
-rw-r--r-- | sys/dev/flash.c | 8 | ||||
-rw-r--r-- | sys/dev/flashvar.h | 3 | ||||
-rw-r--r-- | sys/dev/vnd.c | 28 | ||||
-rw-r--r-- | sys/kern/kern_bufq.c | 152 | ||||
-rw-r--r-- | sys/kern/subr_disk.c | 13 | ||||
-rw-r--r-- | sys/scsi/cd.c | 40 | ||||
-rw-r--r-- | sys/scsi/cd.h | 3 | ||||
-rw-r--r-- | sys/scsi/sd.c | 40 | ||||
-rw-r--r-- | sys/scsi/sdvar.h | 3 | ||||
-rw-r--r-- | sys/sys/buf.h | 24 | ||||
-rw-r--r-- | sys/sys/disk.h | 4 | ||||
-rw-r--r-- | sys/uvm/uvm_swap.c | 18 |
17 files changed, 264 insertions, 119 deletions
diff --git a/sys/conf/files b/sys/conf/files index b312c42a9ea..e9ce4e9392a 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.457 2009/06/03 14:45:54 jj Exp $ +# $OpenBSD: files,v 1.458 2009/06/03 22:09:30 thib Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -655,6 +655,7 @@ file kern/exec_subr.c file kern/init_main.c file kern/init_sysent.c file kern/kern_acct.c accounting +file kern/kern_bufq.c file kern/kern_clock.c file kern/kern_descrip.c file kern/kern_event.c diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c index 309bbf2034d..e814d5c39e9 100644 --- a/sys/ddb/db_command.c +++ b/sys/ddb/db_command.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_command.c,v 1.51 2009/01/20 22:46:49 thib Exp $ */ +/* $OpenBSD: db_command.c,v 1.52 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: db_command.c,v 1.20 1996/03/30 22:30:05 christos Exp $ */ /* @@ -39,6 +39,7 @@ #include <sys/msgbuf.h> #include <sys/malloc.h> #include <sys/mount.h> +#include <sys/buf.h> #include <uvm/uvm_extern.h> #include <machine/db_machdep.h> /* type definitions */ @@ -296,6 +297,19 @@ db_buf_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) /*ARGSUSED*/ void +db_bufq_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) +{ + boolean_t full = FALSE; + + if (modif[0] == 'f') + full = TRUE; + + db_bufq_print((struct bufq *) addr, full, db_printf); +} + + +/*ARGSUSED*/ +void db_map_print_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif) { boolean_t full = FALSE; @@ -458,6 +472,7 @@ struct db_command db_show_cmds[] = { { "all", NULL, 0, db_show_all_cmds }, { "breaks", db_listbreak_cmd, 0, NULL }, { "buf", db_buf_print_cmd, 0, NULL }, + { "bufq", db_bufq_print_cmd, 0, NULL }, { "extents", db_extent_print_cmd, 0, NULL }, { "malloc", db_malloc_print_cmd, 0, NULL }, { "map", db_map_print_cmd, 0, NULL }, diff --git a/sys/ddb/db_command.h b/sys/ddb/db_command.h index 9ed9da28f50..af92b6a6cbd 100644 --- a/sys/ddb/db_command.h +++ b/sys/ddb/db_command.h @@ -1,4 +1,4 @@ -/* $OpenBSD: db_command.h,v 1.22 2009/01/18 13:36:56 thib Exp $ */ +/* $OpenBSD: db_command.h,v 1.23 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: db_command.h,v 1.8 1996/02/05 01:56:55 christos Exp $ */ /* @@ -39,6 +39,7 @@ int db_cmd_search(char *, struct db_command *, struct db_command **); void db_cmd_list(struct db_command *); void db_command(struct db_command **, struct db_command *); void db_buf_print_cmd(db_expr_t, int, db_expr_t, char *); +void db_bufq_print_cmd(db_expr_t, int, db_expr_t, char *); void db_map_print_cmd(db_expr_t, int, db_expr_t, char *); void db_malloc_print_cmd(db_expr_t, int, db_expr_t, char *); void db_mount_print_cmd(db_expr_t, int, db_expr_t, char *); diff --git a/sys/ddb/db_interface.h b/sys/ddb/db_interface.h index 5e5a5f110e5..90b19086b8f 100644 --- a/sys/ddb/db_interface.h +++ b/sys/ddb/db_interface.h @@ -1,4 +1,4 @@ -/* $OpenBSD: db_interface.h,v 1.10 2009/01/18 13:36:56 thib Exp $ */ +/* $OpenBSD: db_interface.h,v 1.11 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: db_interface.h,v 1.1 1996/02/05 01:57:03 christos Exp $ */ /* @@ -61,6 +61,10 @@ struct nfsreq; void db_show_all_nfsreqs(db_expr_t, int, db_expr_t, char *); void db_nfsreq_print(struct nfsreq *, int, int (*)(const char *, ...)); +/* kern/kern_bufq.c */ +struct bufq; +void db_bufq_print(struct bufq *, int, int (*)(const char *, ...)); + /* ufs/ffs/ffs_softdep.c */ struct worklist; void worklist_print(struct worklist *, int, int (*)(const char *, ...)); diff --git a/sys/dev/ata/wd.c b/sys/dev/ata/wd.c index 045f8188f3b..e6d9f45e2f6 100644 --- a/sys/dev/ata/wd.c +++ b/sys/dev/ata/wd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wd.c,v 1.73 2008/11/08 01:32:06 chl Exp $ */ +/* $OpenBSD: wd.c,v 1.74 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */ /* @@ -119,7 +119,7 @@ struct wd_softc { /* General disk infos */ struct device sc_dev; struct disk sc_dk; - struct buf sc_q; + /* IDE disk soft states */ struct ata_bio sc_wdc_bio; /* current transfer */ struct buf *sc_bp; /* buf being transferred */ @@ -396,13 +396,12 @@ int wddetach(struct device *self, int flags) { struct wd_softc *sc = (struct wd_softc *)self; - struct buf *dp, *bp; + struct buf *bp; int s, bmaj, cmaj, mn; /* Remove unprocessed buffers from queue */ s = splbio(); - for (dp = &sc->sc_q; (bp = dp->b_actf) != NULL; ) { - dp->b_actf = bp->b_actf; + while ((bp = BUFQ_GET(sc->sc_dk.dk_bufq)) != NULL) { bp->b_error = ENXIO; bp->b_flags |= B_ERROR; biodone(bp); @@ -475,7 +474,7 @@ wdstrategy(struct buf *bp) goto done; /* Queue transfer on drive, activate drive and controller if idle. */ s = splbio(); - disksort(&wd->sc_q, bp); + BUFQ_ADD(wd->sc_dk.dk_bufq, bp); wdstart(wd); splx(s); device_unref(&wd->sc_dev); @@ -499,18 +498,15 @@ void wdstart(void *arg) { struct wd_softc *wd = arg; - struct buf *dp, *bp = NULL; + struct buf *bp = NULL; WDCDEBUG_PRINT(("wdstart %s\n", wd->sc_dev.dv_xname), DEBUG_XFERS); while (wd->openings > 0) { /* Is there a buf for us ? */ - dp = &wd->sc_q; - if ((bp = dp->b_actf) == NULL) /* yes, an assign */ + if ((bp = BUFQ_GET(wd->sc_dk.dk_bufq)) == NULL) return; - dp->b_actf = bp->b_actf; - /* * Make the command. First lock the device */ diff --git a/sys/dev/flash.c b/sys/dev/flash.c index c6ea5ccb26b..e7918184463 100644 --- a/sys/dev/flash.c +++ b/sys/dev/flash.c @@ -1,4 +1,4 @@ -/* $OpenBSD: flash.c,v 1.9 2008/06/15 00:36:41 krw Exp $ */ +/* $OpenBSD: flash.c,v 1.10 2009/06/03 22:09:30 thib Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@openbsd.org> @@ -814,7 +814,7 @@ flashstrategy(struct buf *bp) /* Queue the transfer. */ s = splbio(); - disksort(&sc->sc_q, bp); + BUFQ_ADD(sc->sc_dk.dk_bufq, bp); flashstart(sc); splx(s); device_unref(&sc->sc_dev); @@ -881,11 +881,9 @@ flashstart(struct flash_softc *sc) while (1) { /* Remove the next buffer from the queue or stop. */ - dp = &sc->sc_q; - bp = dp->b_actf; + bp = BUFQ_GET(sc->sc_dk.dk_bufq); if (bp == NULL) return; - dp->b_actf = bp->b_actf; /* Transfer this buffer now. */ _flashstart(sc, bp); diff --git a/sys/dev/flashvar.h b/sys/dev/flashvar.h index 940b3bce320..0be3d979424 100644 --- a/sys/dev/flashvar.h +++ b/sys/dev/flashvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: flashvar.h,v 1.2 2007/06/20 18:15:46 deraadt Exp $ */ +/* $OpenBSD: flashvar.h,v 1.3 2009/06/03 22:09:30 thib Exp $ */ /* * Copyright (c) 2005 Uwe Stuehler <uwe@openbsd.org> @@ -77,7 +77,6 @@ struct flash_softc { struct device sc_dev; /* Disk device information */ struct disk sc_dk; - struct buf sc_q; struct buf *sc_bp; int sc_flags; /* Flash controller tag */ diff --git a/sys/dev/vnd.c b/sys/dev/vnd.c index d1540534f7b..1ac734d5233 100644 --- a/sys/dev/vnd.c +++ b/sys/dev/vnd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vnd.c,v 1.90 2008/09/03 23:24:25 krw Exp $ */ +/* $OpenBSD: vnd.c,v 1.91 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: vnd.c,v 1.26 1996/03/30 23:06:11 christos Exp $ */ /* @@ -125,6 +125,7 @@ struct pool vndbufpl; struct vnd_softc { struct device sc_dev; struct disk sc_dk; + int sc_active; /* XXX */ char sc_file[VNDNLEN]; /* file we're covering */ int sc_flags; /* flags */ @@ -134,7 +135,6 @@ struct vnd_softc { size_t sc_ntracks; /* # of tracks per cylinder */ struct vnode *sc_vp; /* vnode */ struct ucred *sc_cred; /* credentials */ - struct buf sc_tab; /* transfer queue */ blf_ctx *sc_keyctx; /* key context */ struct rwlock sc_rwlock; }; @@ -499,8 +499,8 @@ vndstrategy(struct buf *bp) biodone(bp); splx(s); - /* If nothing more is queued, we are done. */ - if (!vnd->sc_tab.b_active) + /* If nothing more is queued, we are done. */ + if (!vnd->sc_active) return; /* @@ -508,9 +508,8 @@ vndstrategy(struct buf *bp) * routine might queue using same links. */ s = splbio(); - bp = vnd->sc_tab.b_actf; - vnd->sc_tab.b_actf = bp->b_actf; - vnd->sc_tab.b_active--; + bp = BUFQ_GET(vnd->sc_dk.dk_bufq); + vnd->sc_active--; splx(s); } } @@ -610,8 +609,8 @@ vndstrategy(struct buf *bp) */ nbp->vb_buf.b_cylinder = nbp->vb_buf.b_blkno; s = splbio(); - disksort(&vnd->sc_tab, &nbp->vb_buf); - vnd->sc_tab.b_active++; + BUFQ_ADD(vnd->sc_dk.dk_bufq, &nbp->vb_buf); + vnd->sc_active++; vndstart(vnd); splx(s); bn += sz; @@ -634,8 +633,9 @@ vndstart(struct vnd_softc *vnd) * Dequeue now since lower level strategy routine might * queue using same links */ - bp = vnd->sc_tab.b_actf; - vnd->sc_tab.b_actf = bp->b_actf; + bp = BUFQ_GET(vnd->sc_dk.dk_bufq); + if (bp == NULL) + return; DNPRINTF(VDB_IO, "vndstart(%d): bp %p vp %p blkno %x addr %p cnt %lx\n", @@ -675,11 +675,11 @@ vndiodone(struct buf *bp) } pbp->b_resid -= vbp->vb_buf.b_bcount; putvndbuf(vbp); - if (vnd->sc_tab.b_active) { + if (vnd->sc_active) { disk_unbusy(&vnd->sc_dk, (pbp->b_bcount - pbp->b_resid), (pbp->b_flags & B_READ)); - if (!vnd->sc_tab.b_actf) - vnd->sc_tab.b_active--; + if (BUFQ_PEEK(vnd->sc_dk.dk_bufq) != NULL) + vnd->sc_active--; } if (pbp->b_resid == 0) { DNPRINTF(VDB_IO, "vndiodone: pbp %p iodone\n", pbp); diff --git a/sys/kern/kern_bufq.c b/sys/kern/kern_bufq.c new file mode 100644 index 00000000000..74a1c6be363 --- /dev/null +++ b/sys/kern/kern_bufq.c @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2008, 2009 Thordur I. Bjornsson <thib@openbsd.org> + * Copyright (c) 2004 Ted Unangst <tedu@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/pool.h> +#include <sys/proc.h> +#include <sys/buf.h> +#include <sys/errno.h> + +#include <sys/disklabel.h> + +/* plain old disksort. */ +struct buf *bufq_disksort_get(struct bufq *, int); +void bufq_disksort_add(struct bufq *, struct buf *); +int bufq_disksort_init(struct bufq *); + +struct bufq * +bufq_init(int type) +{ + struct bufq *bq; + int error; + + KASSERT(type = BUFQ_DISKSORT); + + bq = malloc(sizeof(*bq), M_DEVBUF, M_NOWAIT|M_ZERO); + if (bq == NULL) + return (NULL); + + /* For now, only plain old disksort. */ + bq->bufq_type = type; + bq->bufq_get = bufq_disksort_get; + bq->bufq_add = bufq_disksort_add; + + error = bufq_disksort_init(bq); + if (error) { + free(bq, M_DEVBUF); + return (NULL); + } + + return (bq); +} + +void +bufq_destroy(struct bufq *bq) +{ + bufq_drain(bq); + + if (bq->bufq_data != NULL) + free(bq->bufq_data, M_DEVBUF); + + free(bq, M_DEVBUF); +} + +void +bufq_drain(struct bufq *bq) +{ + struct buf *bp; + int s; + + s = splbio(); + while ((bp = BUFQ_GET(bq)) != NULL) { + bp->b_error = ENXIO; + bp->b_flags |= B_ERROR; + biodone(bp); + } + splx(s); + +} + +void +bufq_disksort_add(struct bufq *bq, struct buf *bp) +{ + struct buf *bufq; + + splassert(IPL_BIO); + + bufq = (struct buf *)bq->bufq_data; + + disksort(bufq, bp); +} + +struct buf * +bufq_disksort_get(struct bufq *bq, int peeking) +{ + struct buf *bufq, *bp; + + splassert(IPL_BIO); + + bufq = (struct buf *)bq->bufq_data; + bp = bufq->b_actf; + if (bp == NULL) + return (NULL); + if (!peeking) + bufq->b_actf = bp->b_actf; + return (bp); +} + +int +bufq_disksort_init(struct bufq *bq) +{ + int error = 0; + + bq->bufq_data = malloc(sizeof(struct buf), M_DEVBUF, + M_WAITOK|M_ZERO); + + if (bq->bufq_data == NULL) + error = ENOMEM; + + return (error); +} + +#ifdef DDB +#include <machine/db_machdep.h> +#include <ddb/db_interface.h> +#include <ddb/db_output.h> + +void +db_bufq_print(struct bufq *bq, int full, int (*pr)(const char *, ...)) +{ + struct buf *bp, *dp; + + + (*pr)(" type %i\n bufq_add %p bufq_get %p bufq_data %p", + bq->bufq_type, bq->bufq_add, bq->bufq_get, bq->bufq_data); + + if (full) { + printf("bufs on queue:\n"); + bp = (struct buf *)bq->bufq_data; + while ((dp = bp->b_actf) != NULL) { + printf("%p\n", bp); + bp = dp; + } + } +} + +#endif diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index d39c97b8971..81d7da5e4fe 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_disk.c,v 1.90 2009/06/03 06:25:27 marco Exp $ */ +/* $OpenBSD: subr_disk.c,v 1.91 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */ /* @@ -762,7 +762,11 @@ disk_construct(struct disk *diskp, char *lockname) { rw_init(&diskp->dk_lock, "dklk"); mtx_init(&diskp->dk_mtx, IPL_BIO); - + + diskp->dk_bufq = bufq_init(BUFQ_DEFAULT); + if (diskp->dk_bufq == NULL) + return (1); + diskp->dk_flags |= DKF_CONSTRUCTED; return (0); @@ -776,7 +780,8 @@ disk_attach(struct disk *diskp) { if (!ISSET(diskp->dk_flags, DKF_CONSTRUCTED)) - disk_construct(diskp, diskp->dk_name); + if (disk_construct(diskp, diskp->dk_name)) + panic("disk_attach: can't construct disk"); /* * Allocate and initialize the disklabel structures. Note that @@ -819,6 +824,8 @@ disk_detach(struct disk *diskp) */ free(diskp->dk_label, M_DEVBUF); + bufq_destroy(diskp->dk_bufq); + /* * Remove from the disklist. */ diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index 560bd202e1f..619b06aad28 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cd.c,v 1.146 2009/02/16 21:19:07 miod Exp $ */ +/* $OpenBSD: cd.c,v 1.147 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: cd.c,v 1.100 1997/04/02 02:29:30 mycroft Exp $ */ /* @@ -98,7 +98,6 @@ void cdrestart(void *); void cdminphys(struct buf *); void cdgetdisklabel(dev_t, struct cd_softc *, struct disklabel *, int); void cddone(struct scsi_xfer *); -void cd_kill_buffers(struct cd_softc *); int cd_setchan(struct cd_softc *, int, int, int, int, int); int cd_getvol(struct cd_softc *cd, struct ioc_vol *, int); int cd_setvol(struct cd_softc *, const struct ioc_vol *, int); @@ -248,7 +247,7 @@ cddetach(struct device *self, int flags) struct cd_softc *cd = (struct cd_softc *)self; int bmaj, cmaj, mn; - cd_kill_buffers(cd); + bufq_drain(cd->sc_dk.dk_bufq); /* Locate the lowest minor number to be detached. */ mn = DISKMINOR(self->dv_unit, 0); @@ -499,7 +498,7 @@ cdstrategy(struct buf *bp) /* * Place it in the queue of disk activities for this disk */ - disksort(&cd->buf_queue, bp); + BUFQ_ADD(cd->sc_dk.dk_bufq, bp); /* * Tell the device to get going on the transfer if it's @@ -546,8 +545,7 @@ cdstart(void *v) { struct cd_softc *cd = v; struct scsi_link *sc_link = cd->sc_link; - struct buf *bp = 0; - struct buf *dp; + struct buf *bp = NULL; struct scsi_rw_big cmd_big; struct scsi_rw cmd_small; struct scsi_generic *cmdp; @@ -572,13 +570,9 @@ cdstart(void *v) return; } - /* - * See if there is a buf with work for us to do.. - */ - dp = &cd->buf_queue; - if ((bp = dp->b_actf) == NULL) /* yes, an assign */ + /* See if there is a buf with work for us to do..*/ + if ((bp = BUFQ_GET(cd->sc_dk.dk_bufq)) == NULL) return; - dp->b_actf = bp->b_actf; /* * If the device has become invalid, abort all the @@ -655,7 +649,7 @@ cdstart(void *v) /* * The device can't start another i/o. Try again later. */ - dp->b_actf = bp; + BUFQ_ADD(cd->sc_dk.dk_bufq, bp); disk_unbusy(&cd->sc_dk, 0, 0); timeout_add(&cd->sc_timeout, 1); return; @@ -1953,26 +1947,6 @@ cd_interpret_sense(struct scsi_xfer *xs) return (EJUSTRETURN); /* use generic handler in scsi_base */ } -/* - * Remove unprocessed buffers from queue. - */ -void -cd_kill_buffers(struct cd_softc *cd) -{ - struct buf *dp, *bp; - int s; - - s = splbio(); - for (dp = &cd->buf_queue; (bp = dp->b_actf) != NULL; ) { - dp->b_actf = bp->b_actf; - - bp->b_error = ENXIO; - bp->b_flags |= B_ERROR; - biodone(bp); - } - splx(s); -} - #if defined(__macppc__) int cd_eject(void) diff --git a/sys/scsi/cd.h b/sys/scsi/cd.h index 72929119707..e5ef94bcea5 100644 --- a/sys/scsi/cd.h +++ b/sys/scsi/cd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cd.h,v 1.19 2008/07/28 20:58:41 fgsch Exp $ */ +/* $OpenBSD: cd.h,v 1.20 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: scsi_cd.h,v 1.6 1996/03/19 03:06:39 mycroft Exp $ */ /* @@ -293,7 +293,6 @@ struct cd_softc { #ifdef CDDA struct cd_parms orig_params; /* filled in when CD-DA mode starts */ #endif - struct buf buf_queue; struct timeout sc_timeout; void *sc_cdpwrhook; /* our power hook */ }; diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index e291af5815e..27e9ee7e65e 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sd.c,v 1.154 2009/02/16 21:19:07 miod Exp $ */ +/* $OpenBSD: sd.c,v 1.155 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: sd.c,v 1.111 1997/04/02 02:29:41 mycroft Exp $ */ /*- @@ -90,7 +90,6 @@ int sd_reassign_blocks(struct sd_softc *, u_long); int sd_interpret_sense(struct scsi_xfer *); int sd_get_parms(struct sd_softc *, struct disk_parms *, int); void sd_flush(struct sd_softc *, int); -void sd_kill_buffers(struct sd_softc *); void viscpy(u_char *, u_char *, int); @@ -268,7 +267,7 @@ sdactivate(struct device *self, enum devact act) case DVACT_DEACTIVATE: sd->flags |= SDF_DYING; - sd_kill_buffers(sd); + bufq_drain(sd->sc_dk.dk_bufq); break; } @@ -282,7 +281,7 @@ sddetach(struct device *self, int flags) struct sd_softc *sd = (struct sd_softc *)self; int bmaj, cmaj, mn; - sd_kill_buffers(sd); + bufq_drain(sd->sc_dk.dk_bufq); /* Locate the lowest minor number to be detached. */ mn = DISKMINOR(self->dv_unit, 0); @@ -550,10 +549,8 @@ sdstrategy(struct buf *bp) s = splbio(); - /* - * Place it in the queue of disk activities for this disk - */ - disksort(&sd->buf_queue, bp); + /* Place it in the queue of disk activities for this disk */ + BUFQ_ADD(sd->sc_dk.dk_bufq, bp); /* * Tell the device to get going on the transfer if it's @@ -602,7 +599,6 @@ sdstart(void *v) struct sd_softc *sd = (struct sd_softc *)v; struct scsi_link *sc_link = sd->sc_link; struct buf *bp = 0; - struct buf *dp; struct scsi_rw_big cmd_big; struct scsi_rw_12 cmd_12; struct scsi_rw_16 cmd_16; @@ -637,10 +633,8 @@ sdstart(void *v) /* * See if there is a buf with work for us to do.. */ - dp = &sd->buf_queue; - if ((bp = dp->b_actf) == NULL) /* yes, an assign */ + if ((bp = BUFQ_GET(sd->sc_dk.dk_bufq)) == NULL) return; - dp->b_actf = bp->b_actf; /* * If the device has become invalid, abort all the @@ -747,7 +741,7 @@ sdstart(void *v) /* * The device can't start another i/o. Try again later. */ - dp->b_actf = bp; + BUFQ_ADD(sd->sc_dk.dk_bufq, bp); disk_unbusy(&sd->sc_dk, 0, 0); timeout_add(&sd->sc_timeout, 1); return; @@ -1495,23 +1489,3 @@ sd_flush(struct sd_softc *sd, int flags) } else sd->flags &= ~SDF_DIRTY; } - -/* - * Remove unprocessed buffers from queue. - */ -void -sd_kill_buffers(struct sd_softc *sd) -{ - struct buf *dp, *bp; - int s; - - s = splbio(); - for (dp = &sd->buf_queue; (bp = dp->b_actf) != NULL; ) { - dp->b_actf = bp->b_actf; - - bp->b_error = ENXIO; - bp->b_flags |= B_ERROR; - biodone(bp); - } - splx(s); -} diff --git a/sys/scsi/sdvar.h b/sys/scsi/sdvar.h index ba0519634d0..2498b15edac 100644 --- a/sys/scsi/sdvar.h +++ b/sys/scsi/sdvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sdvar.h,v 1.16 2008/11/10 18:04:41 deraadt Exp $ */ +/* $OpenBSD: sdvar.h,v 1.17 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: sdvar.h,v 1.7 1998/08/17 00:49:03 mycroft Exp $ */ /*- @@ -69,7 +69,6 @@ struct sd_softc { u_long rot_rate; /* rotational rate, in RPM */ daddr64_t disksize; /* total number sectors */ } params; - struct buf buf_queue; void *sc_sdhook; /* our shutdown hook */ struct timeout sc_timeout; }; diff --git a/sys/sys/buf.h b/sys/sys/buf.h index a537c6b95aa..d8b021a5f81 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: buf.h,v 1.63 2009/06/03 04:30:57 beck Exp $ */ +/* $OpenBSD: buf.h,v 1.64 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: buf.h,v 1.25 1997/04/09 21:12:17 mycroft Exp $ */ /* @@ -110,6 +110,28 @@ struct buf { struct workhead b_dep; /* List of filesystem dependencies. */ }; +/* BUFQ: flexible buffer queue routines. */ +#define BUFQ_DISKSORT 1 +#define BUFQ_DEFAULT BUFQ_DISKSORT + +struct bufq { + struct buf *(*bufq_get)(struct bufq *, int); + void (*bufq_add)(struct bufq *, struct buf *); + void *bufq_data; + int bufq_type; +}; + +TAILQ_HEAD(bufq_tailq, buf); + +#define BUFQ_ADD(_bufq, _bp) (_bufq)->bufq_add(_bufq, _bp) +#define BUFQ_GET(_bufq) (_bufq)->bufq_get(_bufq, 0) +#define BUFQ_PEEK(_bufq) (_bufq)->bufq_get(_bufq, 1) + +struct bufq *bufq_init(int); +void bufq_destroy(struct bufq *); +void bufq_drain(struct bufq *); + + /* * For portability with historic industry practice, the cylinder number has * to be maintained in the `b_resid' field. diff --git a/sys/sys/disk.h b/sys/sys/disk.h index e045bb08f5f..d044367c5af 100644 --- a/sys/sys/disk.h +++ b/sys/sys/disk.h @@ -1,4 +1,4 @@ -/* $OpenBSD: disk.h,v 1.18 2007/12/23 01:59:58 dlg Exp $ */ +/* $OpenBSD: disk.h,v 1.19 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: disk.h,v 1.11 1996/04/28 20:22:50 thorpej Exp $ */ /* @@ -54,6 +54,7 @@ #include <sys/mutex.h> struct buf; +struct bufq; struct disklabel; #define DS_DISKNAMELEN 16 @@ -101,6 +102,7 @@ struct disk { int dk_byteshift; /* shift to convert bytes to blks */ struct dkdriver *dk_driver; /* pointer to driver */ + struct bufq *dk_bufq; /* * Disk label information. Storage for the in-core disk label diff --git a/sys/uvm/uvm_swap.c b/sys/uvm/uvm_swap.c index cc439744d0c..1822533daa8 100644 --- a/sys/uvm/uvm_swap.c +++ b/sys/uvm/uvm_swap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_swap.c,v 1.88 2009/05/08 13:50:15 ariane Exp $ */ +/* $OpenBSD: uvm_swap.c,v 1.89 2009/06/03 22:09:30 thib Exp $ */ /* $NetBSD: uvm_swap.c,v 1.40 2000/11/17 11:39:39 mrg Exp $ */ /* @@ -138,7 +138,8 @@ struct swapdev { int swd_bsize; /* blocksize (bytes) */ int swd_maxactive; /* max active i/o reqs */ - struct buf swd_tab; /* buffer list */ + int swd_active; /* i/o reqs in progress */ + struct bufq *swd_bufq; /* buffer queue */ struct ucred *swd_cred; /* cred for file access */ #ifdef UVM_SWAP_ENCRYPT #define SWD_KEY_SHIFT 7 /* One key per 0.5 MByte */ @@ -802,6 +803,7 @@ sys_swapctl(struct proc *p, void *v, register_t *retval) sdp->swd_flags = SWF_FAKE; /* placeholder only */ sdp->swd_vp = vp; sdp->swd_dev = (vp->v_type == VBLK) ? vp->v_rdev : NODEV; + sdp->swd_bufq = bufq_init(BUFQ_DEFAULT); /* * XXX Is NFS elaboration necessary? @@ -1148,6 +1150,7 @@ swap_off(struct proc *p, struct swapdev *sdp) extent_free(swapmap, sdp->swd_drumoffset, sdp->swd_drumsize, EX_WAITOK); extent_destroy(sdp->swd_ex); + bufq_destroy(sdp->swd_bufq); free(sdp, M_VMSWAP); simple_unlock(&uvm.swap_data_lock); return (0); @@ -1382,7 +1385,7 @@ sw_reg_strategy(struct swapdev *sdp, struct buf *bp, int bn) bgetvp(vp, &nbp->vb_buf); /* sort it in and start I/O if we are not over our limit */ - disksort(&sdp->swd_tab, &nbp->vb_buf); + BUFQ_ADD(sdp->swd_bufq, &nbp->vb_buf); sw_reg_start(sdp); splx(s); @@ -1425,12 +1428,11 @@ sw_reg_start(struct swapdev *sdp) sdp->swd_flags |= SWF_BUSY; - while (sdp->swd_tab.b_active < sdp->swd_maxactive) { - bp = sdp->swd_tab.b_actf; + while (sdp->swd_active < sdp->swd_maxactive) { + bp = BUFQ_GET(sdp->swd_bufq); if (bp == NULL) break; - sdp->swd_tab.b_actf = bp->b_actf; - sdp->swd_tab.b_active++; + sdp->swd_active++; UVMHIST_LOG(pdhist, "sw_reg_start: bp %p vp %p blkno 0x%lx cnt 0x%lx", @@ -1514,7 +1516,7 @@ sw_reg_iodone(struct buf *bp) /* * done! start next swapdev I/O if one is pending */ - sdp->swd_tab.b_active--; + sdp->swd_active--; sw_reg_start(sdp); } |