From 8d1e3aed2de0f1c8b2dc6800e5544bc7f1a72579 Mon Sep 17 00:00:00 2001 From: Oleg Bulyzhin Date: Sat, 17 Nov 2007 21:54:57 +0000 Subject: [PATCH] - New sysctl variable: net.inet.ip.dummynet.io_fast If it is set to zero value (default) dummynet module will try to emulate real link as close as possible (bandwidth & latency): packet will not leave pipe faster than it should be on real link with given bandwidth. (This is original behaviour of dummynet which was altered in previous commit) If it is set to non-zero value only bandwidth is enforced: packet's latency can be lower comparing to real link with given bandwidth. - Document recently introduced dummynet(4) sysctl variables. Requested by: luigi, julian MFC after: 3 month --- sbin/ipfw/ipfw.8 | 20 +++++++++++++++++++- sys/netinet/ip_dummynet.c | 9 ++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) 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... */