Re: i/o scheduling (was Re: NEW_BUFQ_STRATEGY)
YAMAMOTO Takashi <[email protected]>
| Newsgroups | gmane.os.netbsd.devel.performance,gmane.os.netbsd.devel.kernel |
|---|---|
| Message-ID | <[email protected]> |
> > > One thing I'm not so sure about is using a FCFS queue for the "time > > > sensitive" requests. I think that the average latency for requests from > > > that queue is probably significantly increased by using FCFS rather than > > > the increasing-block-number sort, because we lose the benefit of > > > readahead, which will be particularly severe if the queues are long. The > > > sort seems particularly likely to be beneficial given the rather large > > > number of requests we take from the queues in a "burst" and the consequent > > > likelihood that we'd get a lot of track cache hits. > > > > then how do you think about the attached one? > > Just at a first glance, why three queues? > > Thor i forgot to attach a header part.. three queues are for - time sensitive requests. e.g. sync read/write, requests from pagedaemon(?) - time non sensitive requests which should be served by some period because they will likely become time sensitive requests later. e.g. read ahead - time non sensitive requests. e.g. delayed writes YAMAMOTO Takashi
a.diff
(text/plain, 1.7 KB)
Index: buf.h
===================================================================
--- buf.h (revision 455)
+++ buf.h (working copy)
@@ -110,6 +110,7 @@ struct bufq_state {
#define BUFQ_FCFS 0x0010 /* First-come first-serve */
#define BUFQ_DISKSORT 0x0020 /* Min seek sort */
#define BUFQ_READ_PRIO 0x0030 /* Min seek and read priority */
+#define BUFQ_PRIOCSCAN 0x0040 /* Per-priority CSCAN */
#define BUFQ_SORT_MASK 0x000f
#define BUFQ_METHOD_MASK 0x00f0
@@ -153,6 +154,7 @@ struct buf {
struct simplelock b_interlock; /* Lock for b_flags changes */
volatile long b_flags; /* B_* flags. */
int b_error; /* Errno value. */
+ int b_prio; /* Hint for buffer queue discipline. */
long b_bufsize; /* Allocated buffer size. */
long b_bcount; /* Valid bytes in buffer. */
long b_resid; /* Remaining I/O. */
@@ -191,12 +193,15 @@ struct buf {
LIST_ENTRY(buf) b_vnbufs; /* Buffer's associated vnode. */
TAILQ_ENTRY(buf) b_freelist; /* Free list position if not active. */
daddr_t b_lblkno; /* Logical block number. */
+
+ int b_bufqpriv; /* XXX */
};
#define BUF_INIT(bp) \
do { \
LIST_INIT(&(bp)->b_dep); \
simple_lock_init(&(bp)->b_interlock); \
+ BIO_SETPRIO((bp), BPRIO_DEFAULT); \
} while (/*CONSTCOND*/0)
/*
@@ -265,6 +270,15 @@ do { \
#ifdef _KERNEL
+#define BIO_GETPRIO(bp) ((bp)->b_prio)
+#define BIO_SETPRIO(bp, prio) (bp)->b_prio = (prio)
+#define BIO_COPYPRIO(bp1, bp2) BIO_SETPRIO(bp1, BIO_GETPRIO(bp2))
+
+#define BPRIO_TIMECRITICAL 2
+#define BPRIO_TIMELIMITED 1
+#define BPRIO_TIMENONCRITICAL 0
+#define BPRIO_DEFAULT BPRIO_TIMELIMITED
+
extern struct bio_ops bioops;
extern u_int nbuf; /* The number of buffer headers */
extern struct buf *buf; /* The buffer headers. */