diff options
| author | Vlad Yasevich <vladislav.yasevich@hp.com> | 2009-11-23 15:53:57 -0500 |
|---|---|---|
| committer | Vlad Yasevich <vladislav.yasevich@hp.com> | 2009-11-23 15:53:57 -0500 |
| commit | 90f2f5318b3a5b0898fef0fec9b91376c7de7a2c (patch) | |
| tree | 33622d2b9e2064c36c17cd108c9b3a23af1fd6a4 | |
| parent | e0e9db178a5ba4dbb5f16f958f1affbdc63d2cc4 (diff) | |
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>
| -rw-r--r-- | include/net/sctp/constants.h | 4 | ||||
| -rw-r--r-- | include/net/sctp/structs.h | 6 | ||||
| -rw-r--r-- | net/sctp/associola.c | 5 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 3 | ||||
| -rw-r--r-- | net/sctp/sm_sideeffect.c | 3 | ||||
| -rw-r--r-- | net/sctp/sysctl.c | 13 |
6 files changed, 30 insertions, 4 deletions
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 58f714a3b670..63908840eef0 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h | |||
| @@ -308,6 +308,10 @@ enum { SCTP_MAX_GABS = 16 }; | |||
| 308 | 308 | ||
| 309 | #define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */ | 309 | #define SCTP_DEFAULT_MINWINDOW 1500 /* default minimum rwnd size */ |
| 310 | #define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */ | 310 | #define SCTP_DEFAULT_MAXWINDOW 65535 /* default rwnd size */ |
| 311 | #define SCTP_DEFAULT_RWND_SHIFT 4 /* by default, update on 1/16 of | ||
| 312 | * rcvbuf, which is 1/8 of initial | ||
| 313 | * window | ||
| 314 | */ | ||
| 311 | #define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the limit | 315 | #define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the limit |
| 312 | * to which we will raise the P-MTU. | 316 | * to which we will raise the P-MTU. |
| 313 | */ | 317 | */ |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index cd2e18778f81..90876b657775 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
| @@ -231,6 +231,11 @@ extern struct sctp_globals { | |||
| 231 | /* Flag to indicate whether computing and verifying checksum | 231 | /* Flag to indicate whether computing and verifying checksum |
| 232 | * is disabled. */ | 232 | * is disabled. */ |
| 233 | int checksum_disable; | 233 | int checksum_disable; |
| 234 | |||
| 235 | /* Threshold for rwnd update SACKS. Receive buffer shifted this many | ||
| 236 | * bits is an indicator of when to send and window update SACK. | ||
| 237 | */ | ||
| 238 | int rwnd_update_shift; | ||
| 234 | } sctp_globals; | 239 | } sctp_globals; |
| 235 | 240 | ||
| 236 | #define sctp_rto_initial (sctp_globals.rto_initial) | 241 | #define sctp_rto_initial (sctp_globals.rto_initial) |
| @@ -267,6 +272,7 @@ extern struct sctp_globals { | |||
| 267 | #define sctp_prsctp_enable (sctp_globals.prsctp_enable) | 272 | #define sctp_prsctp_enable (sctp_globals.prsctp_enable) |
| 268 | #define sctp_auth_enable (sctp_globals.auth_enable) | 273 | #define sctp_auth_enable (sctp_globals.auth_enable) |
| 269 | #define sctp_checksum_disable (sctp_globals.checksum_disable) | 274 | #define sctp_checksum_disable (sctp_globals.checksum_disable) |
| 275 | #define sctp_rwnd_upd_shift (sctp_globals.rwnd_update_shift) | ||
| 270 | 276 | ||
| 271 | /* SCTP Socket type: UDP or TCP style. */ | 277 | /* SCTP Socket type: UDP or TCP style. */ |
| 272 | typedef enum { | 278 | typedef enum { |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 8e755ebff3b8..37e982510bea 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -1383,8 +1383,9 @@ static inline int sctp_peer_needs_update(struct sctp_association *asoc) | |||
| 1383 | case SCTP_STATE_SHUTDOWN_RECEIVED: | 1383 | case SCTP_STATE_SHUTDOWN_RECEIVED: |
| 1384 | case SCTP_STATE_SHUTDOWN_SENT: | 1384 | case SCTP_STATE_SHUTDOWN_SENT: |
| 1385 | if ((asoc->rwnd > asoc->a_rwnd) && | 1385 | if ((asoc->rwnd > asoc->a_rwnd) && |
| 1386 | ((asoc->rwnd - asoc->a_rwnd) >= | 1386 | ((asoc->rwnd - asoc->a_rwnd) >= max_t(__u32, |
| 1387 | min_t(__u32, (asoc->base.sk->sk_rcvbuf >> 1), asoc->pathmtu))) | 1387 | (asoc->base.sk->sk_rcvbuf >> sctp_rwnd_upd_shift), |
| 1388 | asoc->pathmtu))) | ||
| 1388 | return 1; | 1389 | return 1; |
| 1389 | break; | 1390 | break; |
| 1390 | default: | 1391 | default: |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 08ef203d36ac..a3c8988758b1 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
| @@ -1258,6 +1258,9 @@ SCTP_STATIC __init int sctp_init(void) | |||
| 1258 | /* Set SCOPE policy to enabled */ | 1258 | /* Set SCOPE policy to enabled */ |
| 1259 | sctp_scope_policy = SCTP_SCOPE_POLICY_ENABLE; | 1259 | sctp_scope_policy = SCTP_SCOPE_POLICY_ENABLE; |
| 1260 | 1260 | ||
| 1261 | /* Set the default rwnd update threshold */ | ||
| 1262 | sctp_rwnd_upd_shift = SCTP_DEFAULT_RWND_SHIFT; | ||
| 1263 | |||
| 1261 | sctp_sysctl_register(); | 1264 | sctp_sysctl_register(); |
| 1262 | 1265 | ||
| 1263 | INIT_LIST_HEAD(&sctp_address_families); | 1266 | INIT_LIST_HEAD(&sctp_address_families); |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index eda4fe783be5..8ae67098e094 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -217,8 +217,7 @@ static int sctp_gen_sack(struct sctp_association *asoc, int force, | |||
| 217 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, | 217 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
| 218 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); | 218 | SCTP_TO(SCTP_EVENT_TIMEOUT_SACK)); |
| 219 | } else { | 219 | } else { |
| 220 | if (asoc->a_rwnd > asoc->rwnd) | 220 | asoc->a_rwnd = asoc->rwnd; |
| 221 | asoc->a_rwnd = asoc->rwnd; | ||
| 222 | sack = sctp_make_sack(asoc); | 221 | sack = sctp_make_sack(asoc); |
| 223 | if (!sack) | 222 | if (!sack) |
| 224 | goto nomem; | 223 | goto nomem; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index ab7151da120f..ae03ded2bf1a 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
| @@ -52,6 +52,7 @@ static int int_max = INT_MAX; | |||
| 52 | static int sack_timer_min = 1; | 52 | static int sack_timer_min = 1; |
| 53 | static int sack_timer_max = 500; | 53 | static int sack_timer_max = 500; |
| 54 | static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ | 54 | static int addr_scope_max = 3; /* check sctp_scope_policy_t in include/net/sctp/constants.h for max entries */ |
| 55 | static int rwnd_scale_max = 16; | ||
| 55 | 56 | ||
| 56 | extern int sysctl_sctp_mem[3]; | 57 | extern int sysctl_sctp_mem[3]; |
| 57 | extern int sysctl_sctp_rmem[3]; | 58 | extern int sysctl_sctp_rmem[3]; |
| @@ -284,6 +285,18 @@ static ctl_table sctp_table[] = { | |||
| 284 | .extra1 = &zero, | 285 | .extra1 = &zero, |
| 285 | .extra2 = &addr_scope_max, | 286 | .extra2 = &addr_scope_max, |
| 286 | }, | 287 | }, |
| 288 | { | ||
| 289 | .ctl_name = CTL_UNNUMBERED, | ||
| 290 | .procname = "rwnd_update_shift", | ||
| 291 | .data = &sctp_rwnd_upd_shift, | ||
| 292 | .maxlen = sizeof(int), | ||
| 293 | .mode = 0644, | ||
| 294 | .proc_handler = &proc_dointvec_minmax, | ||
| 295 | .strategy = &sysctl_intvec, | ||
| 296 | .extra1 = &one, | ||
| 297 | .extra2 = &rwnd_scale_max, | ||
| 298 | }, | ||
| 299 | |||
| 287 | { .ctl_name = 0 } | 300 | { .ctl_name = 0 } |
| 288 | }; | 301 | }; |
| 289 | 302 | ||
