[BACK]Return to bufq_priocscan.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/kern/bufq_priocscan.c between version 1.14 and 1.15

version 1.14, 2009/01/19 14:54:28 version 1.15, 2011/11/02 15:14:49
Line 42  __KERNEL_RCSID(0, "$NetBSD$");
Line 42  __KERNEL_RCSID(0, "$NetBSD$");
 TAILQ_HEAD(bqhead, buf);  TAILQ_HEAD(bqhead, buf);
 struct cscan_queue {  struct cscan_queue {
         struct bqhead cq_head[2];       /* actual lists of buffers */          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 */          int cq_lastcylinder;            /* b_cylinder of the last request */
         daddr_t cq_lastrawblkno;        /* b_rawblkno of the last request */          daddr_t cq_lastrawblkno;        /* b_rawblkno of the last request */
 };  };
Line 65  cscan_put(struct cscan_queue *q, struct 
Line 65  cscan_put(struct cscan_queue *q, struct 
         struct buf tmp;          struct buf tmp;
         struct buf *it;          struct buf *it;
         struct bqhead *bqh;          struct bqhead *bqh;
         int idx;          unsigned int idx;
   
         tmp.b_cylinder = q->cq_lastcylinder;          tmp.b_cylinder = q->cq_lastcylinder;
         tmp.b_rawblkno = q->cq_lastrawblkno;          tmp.b_rawblkno = q->cq_lastrawblkno;
Line 90  cscan_put(struct cscan_queue *q, struct 
Line 90  cscan_put(struct cscan_queue *q, struct 
 static struct buf *  static struct buf *
 cscan_get(struct cscan_queue *q, int remove)  cscan_get(struct cscan_queue *q, int remove)
 {  {
         int idx = q->cq_idx;          unsigned int idx = q->cq_idx;
         struct bqhead *bqh;          struct bqhead *bqh;
         struct buf *bp;          struct buf *bp;
   
Line 138  cscan_init(struct cscan_queue *q)
Line 138  cscan_init(struct cscan_queue *q)
   
 struct priocscan_queue {  struct priocscan_queue {
         struct cscan_queue q_queue;          struct cscan_queue q_queue;
         int q_burst;          unsigned int q_burst;
 };  };
   
 struct bufq_priocscan {  struct bufq_priocscan {
Line 204  bufq_priocscan_get(struct bufq_state *bu
Line 204  bufq_priocscan_get(struct bufq_state *bu
 {  {
         struct bufq_priocscan *q = bufq->bq_private;          struct bufq_priocscan *q = bufq->bq_private;
         struct priocscan_queue *pq, *npq;          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 priocscan_queue *epq;
         const struct cscan_queue *cq;  
         struct buf *bp;          struct buf *bp;
         bool single; /* true if there's only one non-empty queue */          bool single; /* true if there's only one non-empty queue */
   
           /*
            * find the highest priority non-empty queue.
            */
         pq = &q->bq_queue[0];          pq = &q->bq_queue[0];
         epq = pq + PRIOCSCAN_NQUEUE;          epq = pq + PRIOCSCAN_NQUEUE;
         for (; pq < epq; pq++) {          for (; pq < epq; pq++) {
                 cq = &pq->q_queue;                  if (!cscan_empty(&pq->q_queue)) {
                 if (!cscan_empty(cq))  
                         break;                          break;
                   }
         }          }
         if (pq == epq) {          if (pq == epq) {
                 /* there's no requests */                  /*
                    * all our queues are empty.  there's nothing to serve.
                    */
                 return NULL;                  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;          single = true;
         for (npq = first + 1; npq < epq; npq++) {          for (npq = pq + 1; npq < epq; npq++) {
                 cq = &npq->q_queue;                  if (!cscan_empty(&npq->q_queue)) {
                 if (!cscan_empty(cq)) {                          /*
                            * we found another non-empty queue.
                            * it means that a queue needs to consume its burst
                            * count to be served.
                            */
                         single = false;                          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;                                  break;
                           }
                         pq = npq;                          pq = npq;
                 }                  }
         }          }
         if (single) {          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.
                 pq = first;  
         } else if (pq->q_burst > 0) {  
                 /*  
                  * XXX account only by number of requests.  is it good enough?  
                  */                   */
                 if (remove) {                  KASSERT(pq == first);
                         pq->q_burst--;  
                 }  
         } else {          } else {
                 /*                  /*
                  * no queue was selected due to burst counts                   * there are two or more non-empty queues.
                  */                   */
                 int i;                  if (pq->q_burst == 0) {
                           /*
                            * no queues can be served because they have already
                            * exhausted their burst count.
                            */
                           unsigned int i;
 #ifdef DEBUG  #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++) {                          for (i = 0; i < PRIOCSCAN_NQUEUE; i++) {
                                 pq = &q->bq_queue[i];                                  pq = &q->bq_queue[i];
                                 pq->q_burst = priocscan_burst[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;
                   }
                 /*                  /*
                  * serve first non-empty queue.                   * consume the burst count.
                    *
                    * XXX account only by number of requests.  is it good enough?
                  */                   */
                 pq = first;                  KASSERT(pq->q_burst > 0);
                   if (remove) {
                           pq->q_burst--;
                   }
         }          }
   
           /*
            * finally, get a request from the selected queue.
            */
         KDASSERT(!cscan_empty(&pq->q_queue));          KDASSERT(!cscan_empty(&pq->q_queue));
         bp = cscan_get(&pq->q_queue, remove);          bp = cscan_get(&pq->q_queue, remove);
         KDASSERT(bp != NULL);          KDASSERT(bp != NULL);
Line 287  static struct buf *
Line 318  static struct buf *
 bufq_priocscan_cancel(struct bufq_state *bufq, struct buf *bp)  bufq_priocscan_cancel(struct bufq_state *bufq, struct buf *bp)
 {  {
         struct bufq_priocscan * const q = bufq->bq_private;          struct bufq_priocscan * const q = bufq->bq_private;
         int i, j;          unsigned int i, j;
   
         for (i = 0; i < PRIOCSCAN_NQUEUE; i++) {          for (i = 0; i < PRIOCSCAN_NQUEUE; i++) {
                 struct cscan_queue * const cq = &q->bq_queue[i].q_queue;                  struct cscan_queue * const cq = &q->bq_queue[i].q_queue;
Line 318  static void
Line 349  static void
 bufq_priocscan_init(struct bufq_state *bufq)  bufq_priocscan_init(struct bufq_state *bufq)
 {  {
         struct bufq_priocscan *q;          struct bufq_priocscan *q;
         int i;          unsigned int i;
   
         bufq->bq_get = bufq_priocscan_get;          bufq->bq_get = bufq_priocscan_get;
         bufq->bq_put = bufq_priocscan_put;          bufq->bq_put = bufq_priocscan_put;

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

CVSweb <webmaster@jp.NetBSD.org>