Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern - don't forget to decrement burst count after reset



details:   https://anonhg.NetBSD.org/src/rev/ec03e76ed210
branches:  trunk
changeset: 770805:ec03e76ed210
user:      yamt <yamt%NetBSD.org@localhost>
date:      Wed Nov 02 15:14:49 2011 +0000

description:
- don't forget to decrement burst count after reset
- signed -> unsigned where appropriate
- comments

diffstat:

 sys/kern/bufq_priocscan.c |  129 ++++++++++++++++++++++++++++-----------------
 1 files changed, 80 insertions(+), 49 deletions(-)

diffs (222 lines):

diff -r 7093aa7c8e7c -r ec03e76ed210 sys/kern/bufq_priocscan.c
--- a/sys/kern/bufq_priocscan.c Wed Nov 02 14:42:43 2011 +0000
+++ b/sys/kern/bufq_priocscan.c Wed Nov 02 15:14:49 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bufq_priocscan.c,v 1.14 2009/01/19 14:54:28 yamt Exp $ */
+/*     $NetBSD: bufq_priocscan.c,v 1.15 2011/11/02 15:14:49 yamt Exp $ */
 
 /*-
  * Copyright (c)2004,2005,2006,2008,2009 YAMAMOTO Takashi,
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bufq_priocscan.c,v 1.14 2009/01/19 14:54:28 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bufq_priocscan.c,v 1.15 2011/11/02 15:14:49 yamt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -42,7 +42,7 @@
 TAILQ_HEAD(bqhead, buf);
 struct cscan_queue {
        struct bqhead cq_head[2];       /* actual lists of buffers */
-       int cq_idx;                     /* current list index */
+       unsigned int cq_idx;            /* current list index */
        int cq_lastcylinder;            /* b_cylinder of the last request */
        daddr_t cq_lastrawblkno;        /* b_rawblkno of the last request */
 };
@@ -65,7 +65,7 @@
        struct buf tmp;
        struct buf *it;
        struct bqhead *bqh;
-       int idx;
+       unsigned int idx;
 
        tmp.b_cylinder = q->cq_lastcylinder;
        tmp.b_rawblkno = q->cq_lastrawblkno;
@@ -90,7 +90,7 @@
 static struct buf *
 cscan_get(struct cscan_queue *q, int remove)
 {
-       int idx = q->cq_idx;
+       unsigned int idx = q->cq_idx;
        struct bqhead *bqh;
        struct buf *bp;
 
@@ -138,7 +138,7 @@
 
 struct priocscan_queue {
        struct cscan_queue q_queue;
-       int q_burst;
+       unsigned int q_burst;
 };
 
 struct bufq_priocscan {
@@ -204,77 +204,108 @@
 {
        struct bufq_priocscan *q = bufq->bq_private;
        struct priocscan_queue *pq, *npq;
-       struct priocscan_queue *first; /* first non-empty queue */
+       struct priocscan_queue *first; /* highest priority non-empty queue */
        const struct priocscan_queue *epq;
-       const struct cscan_queue *cq;
        struct buf *bp;
        bool single; /* true if there's only one non-empty queue */
 
+       /*
+        * find the highest priority non-empty queue.
+        */
        pq = &q->bq_queue[0];
        epq = pq + PRIOCSCAN_NQUEUE;
        for (; pq < epq; pq++) {
-               cq = &pq->q_queue;
-               if (!cscan_empty(cq))
+               if (!cscan_empty(&pq->q_queue)) {
                        break;
+               }
        }
        if (pq == epq) {
-               /* there's no requests */
+               /*
+                * all our queues are empty.  there's nothing to serve.
+                */
                return NULL;
        }
+       first = pq;
 
-       first = pq;
+       /*
+        * scan the rest of queues.
+        *
+        * if we have two or more non-empty queues, we serve the highest
+        * priority one with non-zero burst count.
+        */
        single = true;
-       for (npq = first + 1; npq < epq; npq++) {
-               cq = &npq->q_queue;
-               if (!cscan_empty(cq)) {
+       for (npq = pq + 1; npq < epq; npq++) {
+               if (!cscan_empty(&npq->q_queue)) {
+                       /*
+                        * we found another non-empty queue.
+                        * it means that a queue needs to consume its burst
+                        * count to be served.
+                        */
                        single = false;
-                       if (pq->q_burst > 0)
+
+                       /*
+                        * check if our current candidate queue has already
+                        * exhausted its burst count.
+                        */
+                       if (pq->q_burst > 0) {
                                break;
+                       }
                        pq = npq;
                }
        }
        if (single) {
                /*
-                * there's only a non-empty queue.  just serve it.
+                * there's only a non-empty queue.
+                * just serve it without consuming its burst count.
+                */
+               KASSERT(pq == first);
+       } else {
+               /*
+                * there are two or more non-empty queues.
                 */
-               pq = first;
-       } else if (pq->q_burst > 0) {
+               if (pq->q_burst == 0) {
+                       /*
+                        * no queues can be served because they have already
+                        * exhausted their burst count.
+                        */
+                       unsigned int i;
+#ifdef DEBUG
+                       for (i = 0; i < PRIOCSCAN_NQUEUE; i++) {
+                               pq = &q->bq_queue[i];
+                               if (!cscan_empty(&pq->q_queue) && pq->q_burst) {
+                                       panic("%s: inconsist", __func__);
+                               }
+                       }
+#endif /* DEBUG */
+                       /*
+                        * reset burst counts.
+                        */
+                       if (remove) {
+                               for (i = 0; i < PRIOCSCAN_NQUEUE; i++) {
+                                       pq = &q->bq_queue[i];
+                                       pq->q_burst = priocscan_burst[i];
+                               }
+                       }
+
+                       /*
+                        * serve the highest priority non-empty queue.
+                        */
+                       pq = first;
+               }
                /*
+                * consume the burst count.
+                *
                 * XXX account only by number of requests.  is it good enough?
                 */
+               KASSERT(pq->q_burst > 0);
                if (remove) {
                        pq->q_burst--;
                }
-       } else {
-               /*
-                * no queue was selected due to burst counts
-                */
-               int i;
-#ifdef DEBUG
-               for (i = 0; i < PRIOCSCAN_NQUEUE; i++) {
-                       pq = &q->bq_queue[i];
-                       cq = &pq->q_queue;
-                       if (!cscan_empty(cq) && pq->q_burst)
-                               panic("%s: inconsist", __func__);
-               }
-#endif /* DEBUG */
-
-               /*
-                * reset burst counts
-                */
-               if (remove) {
-                       for (i = 0; i < PRIOCSCAN_NQUEUE; i++) {
-                               pq = &q->bq_queue[i];
-                               pq->q_burst = priocscan_burst[i];
-                       }
-               }
-
-               /*
-                * serve first non-empty queue.
-                */
-               pq = first;
        }
 
+       /*
+        * finally, get a request from the selected queue.
+        */
        KDASSERT(!cscan_empty(&pq->q_queue));
        bp = cscan_get(&pq->q_queue, remove);
        KDASSERT(bp != NULL);
@@ -287,7 +318,7 @@
 bufq_priocscan_cancel(struct bufq_state *bufq, struct buf *bp)
 {
        struct bufq_priocscan * const q = bufq->bq_private;
-       int i, j;
+       unsigned int i, j;
 
        for (i = 0; i < PRIOCSCAN_NQUEUE; i++) {
                struct cscan_queue * const cq = &q->bq_queue[i].q_queue;
@@ -318,7 +349,7 @@
 bufq_priocscan_init(struct bufq_state *bufq)
 {
        struct bufq_priocscan *q;
-       int i;
+       unsigned int i;
 
        bufq->bq_get = bufq_priocscan_get;
        bufq->bq_put = bufq_priocscan_put;



Home | Main Index | Thread Index | Old Index