X-Git-Url: http://git.onelab.eu/?p=ipfw.git;a=blobdiff_plain;f=dummynet2%2Finclude%2Fnetinet%2Fipfw%2Fdn_sched.h;fp=dummynet2%2Finclude%2Fnetinet%2Fipfw%2Fdn_sched.h;h=a755e864b53d55307760155cd863a94178bf5ae5;hp=3c75b642070400c386431d9891cdf3e11c0993b1;hb=28a7fe9d930667786b902af6697c01eb87694173;hpb=2a8b6c544cf5ea3c84f763144c7ecfa79daea969 diff --git a/dummynet2/include/netinet/ipfw/dn_sched.h b/dummynet2/include/netinet/ipfw/dn_sched.h index 3c75b64..a755e86 100644 --- a/dummynet2/include/netinet/ipfw/dn_sched.h +++ b/dummynet2/include/netinet/ipfw/dn_sched.h @@ -119,6 +119,10 @@ struct dn_alg { * free_queue actions related to a queue removal, e.g. undo * all the above. If the queue has data in it, also remove * from the scheduler. This can e.g. happen during a reconfigure. + * If safe == 1 remove the queue only if the scheduler no longer + * need it, otherwise delete it even if the scheduler is using + * it. Usually, the flag safe is set when the drain routine is + * running to delete idle queues. */ int (*enqueue)(struct dn_sch_inst *, struct dn_queue *, struct mbuf *); @@ -131,7 +135,7 @@ struct dn_alg { int (*new_fsk)(struct dn_fsk *f); int (*free_fsk)(struct dn_fsk *f); int (*new_queue)(struct dn_queue *q); - int (*free_queue)(struct dn_queue *q); + int (*free_queue)(struct dn_queue *q, int safe); /* run-time fields */ int ref_count; /* XXX number of instances in the system */ @@ -166,14 +170,27 @@ dn_dequeue(struct dn_queue *q) if (m == NULL) return NULL; q->mq.head = m->m_nextpkt; + + /* Update stats for the queue */ q->ni.length--; q->ni.len_bytes -= m->m_pkthdr.len; + /* When the queue becomes idle, update idle_time (used by RED) + * and also update the count of idle queues (for garbage collection). + */ + if (q->ni.length == 0) { + dn_cfg.idle_queue++; + q->q_time = dn_cfg.curr_time; + } if (q->_si) { - q->_si->ni.length--; - q->_si->ni.len_bytes -= m->m_pkthdr.len; + struct dn_flow *ni = &(q->_si->ni); + /* update stats for the scheduler instance, and keep track + * of idle scheduler instances if needed + */ + ni->length--; + ni->len_bytes -= m->m_pkthdr.len; + if (ni->length == 0) + dn_cfg.idle_si++; } - if (q->ni.length == 0) /* queue is now idle */ - q->q_time = dn_cfg.curr_time; return m; }