1
linux/net
Gerrit Renker de6f2b59e5 dccp ccid-3: Bug fix for the inter-packet scheduling algorithm
This fixes a subtle bug in the calculation of the inter-packet gap and shows
that t_delta, as it is currently used, is not needed. And hence replaced.

The algorithm from RFC 3448, 4.6 below continually computes a send time t_nom,
which is initialised with the current time t_now; t_gran = 1E6 / HZ specifies
the scheduling granularity, s the packet size, and X the sending rate:

  t_distance = t_nom - t_now;		// in microseconds
  t_delta    = min(t_ipi, t_gran) / 2;	// `delta' parameter in microseconds

  if (t_distance >= t_delta) {
	reschedule after (t_distance / 1000) milliseconds;
  } else {
  	t_ipi  = s / X;			// inter-packet interval in usec
	t_nom += t_ipi;			// compute the next send time
	send packet now;
  }


1) Description of the bug
-------------------------
Rescheduling requires a conversion into milliseconds, due to this call chain:

 * ccid3_hc_tx_send_packet() returns a timeout in milliseconds,
 * this value is converted by msecs_to_jiffies() in dccp_write_xmit(),
 * and finally used as jiffy-expires-value for sk_reset_timer().

The highest jiffy resolution with HZ=1000 is 1 millisecond, so using a higher
granularity does not make much sense here.

As a consequence, values of t_distance < 1000 are truncated to 0. This issue 
has so far been resolved by using instead

  if (t_distance >= t_delta + 1000)
	reschedule after (t_distance / 1000) milliseconds;

The bug is in artificially inflating t_delta to t_delta' = t_delta + 1000. This
is unnecessarily large, a more adequate value is t_delta' = max(t_delta, 1000).


2) Consequences of using the corrected t_delta'
-----------------------------------------------
Since t_delta <= t_gran/2 = 10^6/(2*HZ), we have t_delta <= 1000 as long as
HZ >= 500. This means that t_delta' = max(1000, t_delta) is constant at 1000.

On the other hand, when using a coarse HZ value of HZ < 500, we have three
sub-cases that can all be reduced to using another constant of t_gran/2.

 (a) The first case arises when t_ipi > t_gran. Here t_delta' is the constant
     t_delta' = max(1000, t_gran/2) = t_gran/2.

 (b) If t_ipi <= 2000 < t_gran = 10^6/HZ usec, then t_delta = t_ipi/2 <= 1000,
     so that t_delta' = max(1000, t_delta) = 1000 < t_gran/2. 

 (c) If 2000 < t_ipi <= t_gran, we have t_delta' = max(t_delta, 1000) = t_ipi/2.

In the second and third cases we have delay values less than t_gran/2, which is
in the order of less than or equal to half a jiffy. 

How these are treated depends on how fractions of a jiffy are handled: they
are either always rounded down to 0, or always rounded up to 1 jiffy (assuming
non-zero values). In both cases the error is on average in the order of 50%.

Thus we are not increasing the error when in the second/third case we replace
a value less than t_gran/2 with 0, by setting t_delta' to the constant t_gran/2.


3) Summary
----------
Fixing (1) and considering (2), the patch replaces t_delta with a constant,
whose value depends on CONFIG_HZ, changing the above algorithm to:
 
  if (t_distance >= t_delta')
	reschedule after (t_distance / 1000) milliseconds;

where t_delta' = 10^6/(2*HZ) if HZ < 500, and t_delta' = 1000 otherwise.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
2008-09-04 07:45:33 +02:00
..
9p flag parameters: socket and socketpair 2008-07-24 10:47:27 -07:00
802 list_for_each_rcu must die: networking 2008-07-25 10:53:27 -07:00
8021q netdev: Handle ->addr_list_lock just like ->_xmit_lock for lockdep. 2008-07-22 14:16:42 -07:00
appletalk net: convert BUG_TRAP to generic WARN_ON 2008-07-25 21:43:18 -07:00
atm atm: fix const assignment/discard warnings in the ATM networking driver 2008-07-30 16:31:46 -07:00
ax25 AX.25: Fix sysctl registration if !CONFIG_AX25_DAMA_SLAVE 2008-08-05 18:46:57 -07:00
bluetooth [Bluetooth] Consolidate maintainers information 2008-08-18 13:23:53 +02:00
bridge bridge: show offload settings 2008-08-15 19:51:07 -07:00
can
core pkt_sched: Prevent livelock in TX queue running. 2008-08-19 04:00:36 -07:00
dccp dccp ccid-3: Bug fix for the inter-packet scheduling algorithm 2008-09-04 07:45:33 +02:00
decnet
econet
ethernet
ieee80211
ipv4 ipv: Re-enable IP when MTU > 68 2008-09-02 17:28:58 -07:00
ipv6 ipv6: When we droped a packet, we should return NET_RX_DROP instead of 0 2008-08-29 14:27:51 -07:00
ipx
irda Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 2008-07-20 17:43:29 -07:00
iucv Merge branch 'linus' into cpus4096-for-linus 2008-07-21 17:19:50 +02:00
key net: convert BUG_TRAP to generic WARN_ON 2008-07-25 21:43:18 -07:00
lapb
llc
mac80211 mac80211: Fix debugfs union misuse and pointer corruption 2008-09-02 17:39:50 -04:00
netfilter netfilter: ctnetlink: sleepable allocation with spin lock bh 2008-08-18 21:31:46 -07:00
netlabel
netlink net: convert BUG_TRAP to generic WARN_ON 2008-07-25 21:43:18 -07:00
netrom netdev: Handle ->addr_list_lock just like ->_xmit_lock for lockdep. 2008-07-22 14:16:42 -07:00
packet net: convert BUG_TRAP to generic WARN_ON 2008-07-25 21:43:18 -07:00
rfkill net: rfkill: add missing line break 2008-08-26 20:06:31 -04:00
rose netdev: Handle ->addr_list_lock just like ->_xmit_lock for lockdep. 2008-07-22 14:16:42 -07:00
rxrpc net/rxrpc: Use an IS_ERR test rather than a NULL test 2008-08-13 02:40:48 -07:00
sched pkt_sched: Fix locking of qdisc_root with qdisc_root_sleeping_lock() 2008-08-29 14:27:52 -07:00
sctp sctp: fix random memory dereference with SCTP_HMAC_IDENT option. 2008-08-27 16:09:49 -07:00
sunrpc Merge branch 'linus' into cpus4096 2008-07-28 21:14:43 +02:00
tipc tipc: Don't use structure names which easily globally conflict. 2008-09-02 23:38:32 -07:00
unix Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6 2008-07-26 20:23:44 -07:00
wanrouter wanmain.c doesn't need syncppp.h 2008-07-23 23:00:36 +02:00
wireless net/wireless/Kconfig: clarify the description for CONFIG_WIRELESS_EXT_SYSFS 2008-09-02 15:03:19 -04:00
x25
xfrm ipsec: Fix deadlock in xfrm_state management. 2008-09-02 20:14:15 -07:00
compat.c flag parameters: paccept 2008-07-24 10:47:27 -07:00
Kconfig net: Make "networking" one-click deselectable. 2008-07-30 03:27:53 -07:00
Makefile
nonet.c
socket.c SL*B: drop kmem cache argument from constructor 2008-07-26 12:00:07 -07:00
sysctl_net.c missing bits of net-namespace / sysctl 2008-07-27 09:45:34 -07:00
TUNABLE