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: Vlad Yasevich <vladislav.yasevich@hp.com>
This commit is contained in:
parent
e0e9db178a
commit
90f2f5318b
|
@ -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 {
|
||||||
/* 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 {
|
||||||
#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)
|
||||||
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)
|
||||||
/* 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,7 +217,6 @@ 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)
|
||||||
|
|
|
@ -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[] = {
|
||||||
.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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue