svn commit: r203035 - user/luigi/ipfw3-head/sys/netinet/ipfw

Luigi Rizzo luigi at FreeBSD.org
Tue Jan 26 16:47:34 UTC 2010


Author: luigi
Date: Tue Jan 26 16:47:34 2010
New Revision: 203035
URL: http://svn.freebsd.org/changeset/base/203035

Log:
  fix two bugs in the scheduler
  
  Submitted by:	Riccardo Panicucci

Modified:
  user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c

Modified: user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c
==============================================================================
--- user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c	Tue Jan 26 16:18:45 2010	(r203034)
+++ user/luigi/ipfw3-head/sys/netinet/ipfw/dn_sched_wf2q.c	Tue Jan 26 16:47:34 2010	(r203035)
@@ -182,7 +182,20 @@ wf2qp_dequeue(struct new_sch_inst *_si)
 	idle_check(si, 1, 0);	/* drain something from the idle heap */
 
 	/* make sure at least one element is eligible, bumping V
-	 * and moving entries that have become eligible
+	 * and moving entries that have become eligible.
+	 * We need to repeat the first part twice, before and
+	 * after extracting the candidate, or enqueue() will
+	 * find the data structure in a wrong state.
+	 */
+  pkt = NULL;
+  for(;;) {
+	/*
+	 * Compute V = max(V, min(S_i)). Remember that all elements
+	 * in sch have by definition S_i <= V so if sch is not empty,
+	 * V is surely the max and we must not update it. Conversely,
+	 * if sch is empty we only need to look at neh.
+	 * We don't need to move the queues, as it will be done at the
+	 * next enqueue
 	 */
 	if (sch->elements == 0 && neh->elements > 0) {
 		si->V = MAX64(si->V, HEAP_TOP(neh)->key);
@@ -190,10 +203,12 @@ wf2qp_dequeue(struct new_sch_inst *_si)
 	while (neh->elements > 0 &&
 		    DN_KEY_LEQ(HEAP_TOP(neh)->key, si->V)) {
 		q = HEAP_TOP(neh)->object;
-		alg_fq = (struct wf2qp_queue *)q;
+		alg_fq = (struct wf2qp_queue *)(q + 1);
 		heap_extract(neh, NULL);
 		heap_insert(sch, alg_fq->F, q);
 	}
+	if (pkt) /* pkt found in previous iteration */
+		break;
 	/* ok we have at least one eligible pkt */
 	q = HEAP_TOP(sch)->object;
 	alg_fq = (struct wf2qp_queue *)(q + 1);
@@ -213,18 +228,7 @@ wf2qp_dequeue(struct new_sch_inst *_si)
 			heap_insert(neh, alg_fq->S, q);
 		}
 	}
-
-	/*
-	 * Now compute V = max(V, min(S_i)). Remember that all elements
-	 * in sch have by definition S_i <= V so if sch is not empty,
-	 * V is surely the max and we must not update it. Conversely,
-	 * if sch is empty we only need to look at neh.
-	 * We don't need to move the queues, as it will be done at the
-	 * next enqueue
-	 */
-	if (sch->elements == 0 && neh->elements > 0) {
-		si->V = MAX64(si->V, HEAP_TOP(neh)->key);
-	}
+    }
 	return pkt;
 }
 


More information about the svn-src-user mailing list