diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index 078d01014a61..52d2d3d1437c 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 19, 2007 +.Dd November 17, 2007 .Dt IPFW 8 .Os .Sh NAME @@ -1756,6 +1756,16 @@ Depending on local policies, a flow can contain packets for a single TCP connection, or from/to a given host, or entire subnet, or a protocol type, etc. .Pp +There are two modes of dummynet operation: normal and fast. +Normal mode tries to emulate real link: dummynet scheduler ensures packet will +not leave pipe faster than it would be on real link with given bandwidth. +Fast mode allows certain packets to bypass dummynet scheduler (if packet flow +does not exceed pipe's bandwidth). Thus fast mode requires less cpu cycles +per packet (in average) but packet latency can be significantly lower comparing +to real link with same bandwidth. Default is normal mode, fast mode can be +enabled by setting net.inet.ip.dummynet.io_fast sysctl(8) variable to non-zero +value. +.Pp Packets belonging to the same flow are then passed to either of two different objects, which implement the traffic regulation: .Bl -hang -offset XXXX @@ -2120,6 +2130,14 @@ Default size of the hash table used for dynamic pipes/queues. This value is used when no .Cm buckets option is specified when configuring a pipe/queue. +.It Em net.inet.ip.dummynet.io_fast : No 0 +If set to non-zero value enables "fast" mode of dummynet operation (see above). +.It Em net.inet.ip.dummynet.io_pkt +Number of packets passed to by dummynet. +.It Em net.inet.ip.dummynet.io_pkt_drop +Number of packets dropped by dummynet. +.It Em net.inet.ip.dummynet.io_pkt_fast +Number of packets bypassed dummynet scheduler. .It Em net.inet.ip.dummynet.max_chain_len : No 16 Target value for the maximum number of pipes/queues in a hash bucket. The product diff --git a/sys/netinet/ip_dummynet.c b/sys/netinet/ip_dummynet.c index d6f1880a5375..cb079a5443b1 100644 --- a/sys/netinet/ip_dummynet.c +++ b/sys/netinet/ip_dummynet.c @@ -110,6 +110,7 @@ static long tick_lost; /* Lost(coalesced) ticks number. */ /* Adjusted vs non-adjusted curr_time difference (ticks). */ static long tick_diff; +static int io_fast; static unsigned long io_pkt; static unsigned long io_pkt_fast; static unsigned long io_pkt_drop; @@ -185,6 +186,8 @@ SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_diff, SYSCTL_LONG(_net_inet_ip_dummynet, OID_AUTO, tick_lost, CTLFLAG_RD, &tick_lost, 0, "Number of ticks coalesced by dummynet taskqueue."); +SYSCTL_INT(_net_inet_ip_dummynet, OID_AUTO, io_fast, + CTLFLAG_RW, &io_fast, 0, "Enable fast dummynet io."); SYSCTL_ULONG(_net_inet_ip_dummynet, OID_AUTO, io_pkt, CTLFLAG_RD, &io_pkt, 0, "Number of packets passed to dummynet."); @@ -967,7 +970,7 @@ create_queue(struct dn_flow_set *fs, int i) q->hash_slot = i; q->next = fs->rq[i]; q->S = q->F + 1; /* hack - mark timestamp as invalid. */ - q->numbytes = fs->pipe->bandwidth; + q->numbytes = io_fast ? fs->pipe->bandwidth : 0; fs->rq[i] = q; fs->rq_elements++; return (q); @@ -1325,7 +1328,7 @@ dummynet_io(struct mbuf **m0, int dir, struct ip_fw_args *fwa) goto done; if (q->q_time < curr_time) - q->numbytes = fs->pipe->bandwidth; + q->numbytes = io_fast ? fs->pipe->bandwidth : 0; q->q_time = curr_time; /* @@ -1736,7 +1739,7 @@ config_pipe(struct dn_pipe *p) /* Flush accumulated credit for all queues. */ for (i = 0; i <= pipe->fs.rq_size; i++) for (q = pipe->fs.rq[i]; q; q = q->next) - q->numbytes = p->bandwidth; + q->numbytes = io_fast ? p->bandwidth : 0; pipe->bandwidth = p->bandwidth; pipe->numbytes = 0; /* just in case... */