Commit 90f2f531 authored by Vlad Yasevich's avatar Vlad Yasevich

sctp: Update SWS avaoidance receiver side algorithm

We currently send window update SACKs every time we free up 1 PMTU
worth of data.  That a lot more SACKs then necessary.  Instead, we'll
now send back the actuall window every time we send a sack, and do
window-update SACKs when a fraction of the receive buffer has been
opened.  The fraction is controlled with a sysctl.
Signed-off-by: default avatarVlad Yasevich <vladislav.yasevich@hp.com>
parent e0e9db17
...@@ -308,6 +308,10 @@ enum { SCTP_MAX_GABS = 16 }; ...@@ -308,6 +308,10 @@ enum { SCTP_MAX_GABS = 16 };
#define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */ #define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */
#define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */ #define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */
#define SCTP_DEFAULT_RWND_SHIFT 4 /* by default, update on 1/16 of
* rcvbuf, which is 1/8 of initial
* window
*/
#define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the limit #define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the limit
* to which we will raise the P-MTU. * to which we will raise the P-MTU.
*/ */
......
...@@ -231,6 +231,11 @@ extern struct sctp_globals { ...@@ -231,6 +231,11 @@ extern struct sctp_globals {
/* Flag to indicate whether computing and verifying checksum /* Flag to indicate whether computing and verifying checksum
* is disabled. */ * is disabled. */
int checksum_disable; int checksum_disable;
/* Threshold for rwnd update SACKS. Receive buffer shifted this many
* bits is an indicator of when to send and window update SACK.
*/
int rwnd_update_shift;
} sctp_globals; } sctp_globals;
#define sctp_rto_initial (sctp_globals.rto_initial) #define sctp_rto_initial (sctp_globals.rto_initial)
...@@ -267,6 +272,7 @@ extern struct sctp_globals { ...@@ -267,6 +272,7 @@ extern struct sctp_globals {
#define sctp_prsctp_enable (sctp_globals.prsctp_enable) #define sctp_prsctp_enable (sctp_globals.prsctp_enable)
#define sctp_auth_enable (sctp_globals.auth_enable) #define sctp_auth_enable (sctp_globals.auth_enable)
#define sctp_checksum_disable (sctp_globals.checksum_disable) #define sctp_checksum_disable (sctp_globals.checksum_disable)
#define sctp_rwnd_upd_shift (sctp_globals.rwnd_update_shift)
/* SCTP Socket type: UDP or TCP style. */ /* SCTP Socket type: UDP or TCP style. */
typedef enum { typedef enum {
......
...@@ -1383,8 +1383,9 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc) ...@@ -1383,8 +1383,9 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc)
case SCTP_STATE_SHUTDOWN_RECEIVED: case SCTP_STATE_SHUTDOWN_RECEIVED:
case SCTP_STATE_SHUTDOWN_SENT: case SCTP_STATE_SHUTDOWN_SENT:
if ((asoc->rwnd > asoc->a_rwnd) && if ((asoc->rwnd > asoc->a_rwnd) &&
((asoc->rwnd - asoc->a_rwnd) >= ((asoc->rwnd - asoc->a_rwnd) >= max_t(__u32,
min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pathmtu))) (asoc->base.sk->sk_rcvbuf >> sctp_rwnd_upd_shift),
asoc->pathmtu)))
return 1; return 1;
break; break;
default: default:
......
...@@ -1258,6 +1258,9 @@ SCTP_STATIC __init int sctp_init(void) ...@@ -1258,6 +1258,9 @@ SCTP_STATIC __init int sctp_init(void)
/* Set SCOPE policy to enabled */ /* Set SCOPE policy to enabled */
sctp_scope_policy = SCTP_SCOPE_POLICY_ENABLE; sctp_scope_policy = SCTP_SCOPE_POLICY_ENABLE;
/* Set the default rwnd update threshold */
sctp_rwnd_upd_shift = SCTP_DEFAULT_RWND_SHIFT;
sctp_sysctl_register(); sctp_sysctl_register();
INIT_LIST_HEAD(&sctp_address_families); INIT_LIST_HEAD(&sctp_address_families);
......
...@@ -217,8 +217,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, ...@@ -217,8 +217,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force,
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); SCTP_TO(SCTP_EVENT_TIMEOUT_SACK));
} else { } else {
if (asoc->a_rwnd > asoc->rwnd) asoc->a_rwnd = asoc->rwnd;
asoc->a_rwnd = asoc->rwnd;
sack = sctp_make_sack(asoc); sack = sctp_make_sack(asoc);
if (!sack) if (!sack)
goto nomem; goto nomem;
......
...@@ -52,6 +52,7 @@ static int int_max = INT_MAX; ...@@ -52,6 +52,7 @@ static int int_max = INT_MAX;
static int sack_timer_min = 1; static int sack_timer_min = 1;
static int sack_timer_max = 500; static int sack_timer_max = 500;
static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */
static int rwnd_scale_max = 16;
extern int sysctl_sctp_mem[3]; extern int sysctl_sctp_mem[3];
extern int sysctl_sctp_rmem[3]; extern int sysctl_sctp_rmem[3];
...@@ -284,6 +285,18 @@ static ctl_table sctp_table[] = { ...@@ -284,6 +285,18 @@ static ctl_table sctp_table[] = {
.extra1 = &zero, .extra1 = &zero,
.extra2 = &addr_scope_max, .extra2 = &addr_scope_max,
}, },
{
.ctl_name = CTL_UNNUMBERED,
.procname = "rwnd_update_shift",
.data = &sctp_rwnd_upd_shift,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.strategy = &sysctl_intvec,
.extra1 = &one,
.extra2 = &rwnd_scale_max,
},
{ .ctl_name = 0 } { .ctl_name = 0 }
}; };
......
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