Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Nov 2009 10:13:24 +0000 (UTC)
From:      Oleg Bulyzhin <oleg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r199075 - stable/8/sys/netinet/ipfw
Message-ID:  <200911091013.nA9ADP9f016051@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: oleg
Date: Mon Nov  9 10:13:24 2009
New Revision: 199075
URL: http://svn.freebsd.org/changeset/base/199075

Log:
  MFC r198845:
  Fix two issues that can lead to exceeding configured pipe bandwidth:
  - do not expire queues which are not ready to be expired.
  - properly calculate available burst size.
  
  MFC r199073:
  style(9): add missing parentheses

Modified:
  stable/8/sys/netinet/ipfw/ip_dummynet.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/netinet/ipfw/ip_dummynet.c
==============================================================================
--- stable/8/sys/netinet/ipfw/ip_dummynet.c	Mon Nov  9 09:27:09 2009	(r199074)
+++ stable/8/sys/netinet/ipfw/ip_dummynet.c	Mon Nov  9 10:13:24 2009	(r199075)
@@ -244,6 +244,17 @@ void		dummynet_drain(void);
 static int	dummynet_io(struct mbuf **, int , struct ip_fw_args *);
 
 /*
+ * Flow queue is idle if:
+ *   1) it's empty for at least 1 tick
+ *   2) it has invalid timestamp (WF2Q case)
+ *   3) parent pipe has no 'exhausted' burst.
+ */
+#define QUEUE_IS_IDLE(q) ((q)->head == NULL && (q)->S == (q)->F + 1 && \
+	curr_time > (q)->idle_time + 1 && \
+	((q)->numbytes + (curr_time - (q)->idle_time - 1) * \
+	(q)->fs->pipe->bandwidth >= (q)->fs->pipe->burst))
+
+/*
  * Heap management functions.
  *
  * In the heap, first node is element 0. Children of i are 2i+1 and 2i+2.
@@ -1004,7 +1015,7 @@ expire_queues(struct dn_flow_set *fs)
     fs->last_expired = time_uptime ;
     for (i = 0 ; i <= fs->rq_size ; i++) /* last one is overflow */
 	for (prev=NULL, q = fs->rq[i] ; q != NULL ; )
-	    if (q->head != NULL || q->S != q->F+1) {
+	    if (!QUEUE_IS_IDLE(q)) {
   		prev = q ;
   	        q = q->next ;
   	    } else { /* entry is idle, expire it */
@@ -1134,7 +1145,7 @@ find_queue(struct dn_flow_set *fs, struc
 		break ; /* found */
 
 	    /* No match. Check if we can expire the entry */
-	    if (pipe_expire && q->head == NULL && q->S == q->F+1 ) {
+	    if (pipe_expire && QUEUE_IS_IDLE(q)) {
 		/* entry is idle and not in any heap, expire it */
 		struct dn_flow_queue *old_q = q ;
 
@@ -1408,7 +1419,7 @@ dummynet_io(struct mbuf **m0, int dir, s
 		if (q->idle_time < curr_time) {
 			/* Calculate available burst size. */
 			q->numbytes +=
-			    (curr_time - q->idle_time) * pipe->bandwidth;
+			    (curr_time - q->idle_time - 1) * pipe->bandwidth;
 			if (q->numbytes > pipe->burst)
 				q->numbytes = pipe->burst;
 			if (io_fast)
@@ -1418,8 +1429,8 @@ dummynet_io(struct mbuf **m0, int dir, s
 		if (pipe->idle_time < curr_time) {
 			/* Calculate available burst size. */
 			pipe->numbytes +=
-			    (curr_time - pipe->idle_time) * pipe->bandwidth;
-			if (pipe->numbytes > pipe->burst)
+			    (curr_time - pipe->idle_time - 1) * pipe->bandwidth;
+			if (pipe->numbytes > 0 && pipe->numbytes > pipe->burst)
 				pipe->numbytes = pipe->burst;
 			if (io_fast)
 				pipe->numbytes += pipe->bandwidth;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911091013.nA9ADP9f016051>