Commit ea393c93 authored by Jon Grimm's avatar Jon Grimm Committed by Sridhar Samudrala

[SCTP] Add jitter to the heartbeat interval. (ardelle.fan)

Per RFC 2960 (well, impl-guide corrections really) add a jitter in the
range of -50% to +50% of the current rto to the heartbeat interval. 
parent 1c5f1800
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Copyright (c) 1999-2000 Cisco, Inc. * Copyright (c) 1999-2000 Cisco, Inc.
* Copyright (c) 1999-2001 Motorola, Inc. * Copyright (c) 1999-2001 Motorola, Inc.
* Copyright (c) 2001-2003 International Business Machines, Corp. * Copyright (c) 2001-2003 International Business Machines, Corp.
* Copyright (c) 2001 Intel Corp. * Copyright (c) 2001-2003 Intel Corp.
* *
* This file is part of the SCTP kernel reference Implementation * This file is part of the SCTP kernel reference Implementation
* *
...@@ -36,8 +36,9 @@ ...@@ -36,8 +36,9 @@
* La Monte H.P. Yarroll <piggy@acm.org> * La Monte H.P. Yarroll <piggy@acm.org>
* Xingang Guo <xingang.guo@intel.com> * Xingang Guo <xingang.guo@intel.com>
* Jon Grimm <jgrimm@us.ibm.com> * Jon Grimm <jgrimm@us.ibm.com>
* Daisy Chang <daisyc@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com>
* Sridhar Samudrala <sri@us.ibm.com> * Sridhar Samudrala <sri@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
...@@ -422,6 +423,23 @@ static inline size_t get_user_iov_size(struct iovec *iov, int iovlen) ...@@ -422,6 +423,23 @@ static inline size_t get_user_iov_size(struct iovec *iov, int iovlen)
return retval; return retval;
} }
/* Generate a random jitter in the range of -50% ~ +50% of input RTO. */
static inline __s32 sctp_jitter(__u32 rto)
{
static __u32 sctp_rand;
__s32 ret;
sctp_rand += jiffies;
sctp_rand ^= (sctp_rand << 12);
sctp_rand ^= (sctp_rand >> 20);
/* Choose random number from 0 to rto, then move to -50% ~ +50%
* of rto.
*/
ret = sctp_rand % rto - (rto >> 1);
return ret;
}
/* Walk through a list of TLV parameters. Don't trust the /* Walk through a list of TLV parameters. Don't trust the
* individual parameter lengths and instead depend on * individual parameter lengths and instead depend on
* the chunk length to indicate when to stop. Make sure * the chunk length to indicate when to stop. Make sure
......
...@@ -1134,8 +1134,8 @@ static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *cmds, ...@@ -1134,8 +1134,8 @@ static void sctp_cmd_hb_timers_start(sctp_cmd_seq_t *cmds,
*/ */
list_for_each(pos, &asoc->peer.transport_addr_list) { list_for_each(pos, &asoc->peer.transport_addr_list) {
t = list_entry(pos, sctp_transport_t, transports); t = list_entry(pos, sctp_transport_t, transports);
if (!mod_timer(&t->hb_timer, if (!mod_timer(&t->hb_timer, t->hb_interval + t->rto +
t->hb_interval + t->rto + jiffies)) { sctp_jitter(t->rto) + jiffies)) {
sctp_transport_hold(t); sctp_transport_hold(t);
} }
} }
...@@ -1147,7 +1147,8 @@ static void sctp_cmd_hb_timers_update(sctp_cmd_seq_t *cmds, ...@@ -1147,7 +1147,8 @@ static void sctp_cmd_hb_timers_update(sctp_cmd_seq_t *cmds,
sctp_transport_t *t) sctp_transport_t *t)
{ {
/* Update the heartbeat timer. */ /* Update the heartbeat timer. */
if (!mod_timer(&t->hb_timer, t->hb_interval + t->rto + jiffies)) if (!mod_timer(&t->hb_timer, t->hb_interval + t->rto +
sctp_jitter(t->rto) + jiffies))
sctp_transport_hold(t); sctp_transport_hold(t);
} }
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
* Xingang Guo <xingang.guo@intel.com> * Xingang Guo <xingang.guo@intel.com>
* Hui Huang <hui.huang@nokia.com> * Hui Huang <hui.huang@nokia.com>
* Sridhar Samudrala <sri@us.ibm.com> * Sridhar Samudrala <sri@us.ibm.com>
* Ardelle Fan <ardelle.fan@intel.com>
* *
* Any bugs reported given to us we will try to fix... any fixes shared will * Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release. * be incorporated into the next SCTP release.
...@@ -184,8 +185,9 @@ void sctp_transport_reset_timers(sctp_transport_t *transport) ...@@ -184,8 +185,9 @@ void sctp_transport_reset_timers(sctp_transport_t *transport)
} }
/* When a data chunk is sent, reset the heartbeat interval. */ /* When a data chunk is sent, reset the heartbeat interval. */
if (!mod_timer(&transport->hb_timer, if (!mod_timer(&transport->hb_timer, transport->hb_interval +
transport->hb_interval + transport->rto + jiffies)) transport->rto + sctp_jitter(transport->rto) +
jiffies))
sctp_transport_hold(transport); sctp_transport_hold(transport);
} }
...@@ -202,7 +204,7 @@ void sctp_transport_set_owner(sctp_transport_t *transport, ...@@ -202,7 +204,7 @@ void sctp_transport_set_owner(sctp_transport_t *transport,
/* Caches the dst entry for a transport's destination address and an optional /* Caches the dst entry for a transport's destination address and an optional
* souce address. * souce address.
*/ */
void sctp_transport_route(sctp_transport_t *transport, union sctp_addr *saddr, void sctp_transport_route(sctp_transport_t *transport, union sctp_addr *saddr,
struct sctp_opt *opt) struct sctp_opt *opt)
{ {
...@@ -245,10 +247,10 @@ void sctp_transport_route(sctp_transport_t *transport, union sctp_addr *saddr, ...@@ -245,10 +247,10 @@ void sctp_transport_route(sctp_transport_t *transport, union sctp_addr *saddr,
goto out_unlock; goto out_unlock;
} }
sctp_read_unlock(addr_lock); sctp_read_unlock(addr_lock);
/* None of the bound addresses match the source address of the /* None of the bound addresses match the source address of the
* dst. So release it. * dst. So release it.
*/ */
dst_release(dst); dst_release(dst);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment