git://git.onelab.eu
/
ipfw.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
integrated
[ipfw.git]
/
dummynet2
/
include
/
netinet
/
ipfw
/
dn_sched.h
diff --git
a/dummynet2/include/netinet/ipfw/dn_sched.h
b/dummynet2/include/netinet/ipfw/dn_sched.h
index
3c75b64
..
a755e86
100644
(file)
--- 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.
* 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 *);
*/
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 (*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 */
/* 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;
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;
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) {
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;
}
return m;
}