diff options
| author | Neil Horman <nhorman@tuxdriver.com> | 2005-11-11 19:08:24 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2005-11-11 19:08:24 -0500 |
| commit | 049b3ff5a86d0187184a189d2e31b8654d58fe22 (patch) | |
| tree | aed83ae799e444c57d76597bad6e3b41957a828e | |
| parent | 19c7e9eef503dc1ae926f3d26c56f88bee568d7b (diff) | |
[SCTP]: Include ulpevents in socket receive buffer accounting.
Also introduces a sysctl option to configure the receive buffer
accounting policy to be either at socket or association level.
Default is all the associations on the same socket share the
receive buffer.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/linux/sysctl.h | 1 | ||||
| -rw-r--r-- | include/net/sctp/structs.h | 16 | ||||
| -rw-r--r-- | net/sctp/associola.c | 9 | ||||
| -rw-r--r-- | net/sctp/endpointola.c | 3 | ||||
| -rw-r--r-- | net/sctp/input.c | 20 | ||||
| -rw-r--r-- | net/sctp/protocol.c | 3 | ||||
| -rw-r--r-- | net/sctp/sm_statefuns.c | 22 | ||||
| -rw-r--r-- | net/sctp/socket.c | 4 | ||||
| -rw-r--r-- | net/sctp/sysctl.c | 8 | ||||
| -rw-r--r-- | net/sctp/ulpevent.c | 24 |
10 files changed, 71 insertions, 39 deletions
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index ab2791b3189d..64f203c45378 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
| @@ -715,6 +715,7 @@ enum { | |||
| 715 | NET_SCTP_PRSCTP_ENABLE = 14, | 715 | NET_SCTP_PRSCTP_ENABLE = 14, |
| 716 | NET_SCTP_SNDBUF_POLICY = 15, | 716 | NET_SCTP_SNDBUF_POLICY = 15, |
| 717 | NET_SCTP_SACK_TIMEOUT = 16, | 717 | NET_SCTP_SACK_TIMEOUT = 16, |
| 718 | NET_SCTP_RCVBUF_POLICY = 17, | ||
| 718 | }; | 719 | }; |
| 719 | 720 | ||
| 720 | /* /proc/sys/net/bridge */ | 721 | /* /proc/sys/net/bridge */ |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 2aad4468797e..8e7794ee27ff 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
| @@ -161,6 +161,13 @@ extern struct sctp_globals { | |||
| 161 | */ | 161 | */ |
| 162 | int sndbuf_policy; | 162 | int sndbuf_policy; |
| 163 | 163 | ||
| 164 | /* | ||
| 165 | * Policy for preforming sctp/socket accounting | ||
| 166 | * 0 - do socket level accounting, all assocs share sk_rcvbuf | ||
| 167 | * 1 - do sctp accounting, each asoc may use sk_rcvbuf bytes | ||
| 168 | */ | ||
| 169 | int rcvbuf_policy; | ||
| 170 | |||
| 164 | /* Delayed SACK timeout 200ms default*/ | 171 | /* Delayed SACK timeout 200ms default*/ |
| 165 | int sack_timeout; | 172 | int sack_timeout; |
| 166 | 173 | ||
| @@ -218,6 +225,7 @@ extern struct sctp_globals { | |||
| 218 | #define sctp_cookie_preserve_enable (sctp_globals.cookie_preserve_enable) | 225 | #define sctp_cookie_preserve_enable (sctp_globals.cookie_preserve_enable) |
| 219 | #define sctp_max_retrans_association (sctp_globals.max_retrans_association) | 226 | #define sctp_max_retrans_association (sctp_globals.max_retrans_association) |
| 220 | #define sctp_sndbuf_policy (sctp_globals.sndbuf_policy) | 227 | #define sctp_sndbuf_policy (sctp_globals.sndbuf_policy) |
| 228 | #define sctp_rcvbuf_policy (sctp_globals.rcvbuf_policy) | ||
| 221 | #define sctp_max_retrans_path (sctp_globals.max_retrans_path) | 229 | #define sctp_max_retrans_path (sctp_globals.max_retrans_path) |
| 222 | #define sctp_max_retrans_init (sctp_globals.max_retrans_init) | 230 | #define sctp_max_retrans_init (sctp_globals.max_retrans_init) |
| 223 | #define sctp_sack_timeout (sctp_globals.sack_timeout) | 231 | #define sctp_sack_timeout (sctp_globals.sack_timeout) |
| @@ -1224,6 +1232,9 @@ struct sctp_endpoint { | |||
| 1224 | 1232 | ||
| 1225 | /* sendbuf acct. policy. */ | 1233 | /* sendbuf acct. policy. */ |
| 1226 | __u32 sndbuf_policy; | 1234 | __u32 sndbuf_policy; |
| 1235 | |||
| 1236 | /* rcvbuf acct. policy. */ | ||
| 1237 | __u32 rcvbuf_policy; | ||
| 1227 | }; | 1238 | }; |
| 1228 | 1239 | ||
| 1229 | /* Recover the outter endpoint structure. */ | 1240 | /* Recover the outter endpoint structure. */ |
| @@ -1550,6 +1561,11 @@ struct sctp_association { | |||
| 1550 | */ | 1561 | */ |
| 1551 | int sndbuf_used; | 1562 | int sndbuf_used; |
| 1552 | 1563 | ||
| 1564 | /* This is the amount of memory that this association has allocated | ||
| 1565 | * in the receive path at any given time. | ||
| 1566 | */ | ||
| 1567 | atomic_t rmem_alloc; | ||
| 1568 | |||
| 1553 | /* This is the wait queue head for send requests waiting on | 1569 | /* This is the wait queue head for send requests waiting on |
| 1554 | * the association sndbuf space. | 1570 | * the association sndbuf space. |
| 1555 | */ | 1571 | */ |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index 5f07ddb19554..dec68a604773 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -177,10 +177,10 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 177 | * RFC 6 - A SCTP receiver MUST be able to receive a minimum of | 177 | * RFC 6 - A SCTP receiver MUST be able to receive a minimum of |
| 178 | * 1500 bytes in one SCTP packet. | 178 | * 1500 bytes in one SCTP packet. |
| 179 | */ | 179 | */ |
| 180 | if (sk->sk_rcvbuf < SCTP_DEFAULT_MINWINDOW) | 180 | if ((sk->sk_rcvbuf/2) < SCTP_DEFAULT_MINWINDOW) |
| 181 | asoc->rwnd = SCTP_DEFAULT_MINWINDOW; | 181 | asoc->rwnd = SCTP_DEFAULT_MINWINDOW; |
| 182 | else | 182 | else |
| 183 | asoc->rwnd = sk->sk_rcvbuf; | 183 | asoc->rwnd = sk->sk_rcvbuf/2; |
| 184 | 184 | ||
| 185 | asoc->a_rwnd = asoc->rwnd; | 185 | asoc->a_rwnd = asoc->rwnd; |
| 186 | 186 | ||
| @@ -192,6 +192,9 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a | |||
| 192 | /* Set the sndbuf size for transmit. */ | 192 | /* Set the sndbuf size for transmit. */ |
| 193 | asoc->sndbuf_used = 0; | 193 | asoc->sndbuf_used = 0; |
| 194 | 194 | ||
| 195 | /* Initialize the receive memory counter */ | ||
| 196 | atomic_set(&asoc->rmem_alloc, 0); | ||
| 197 | |||
| 195 | init_waitqueue_head(&asoc->wait); | 198 | init_waitqueue_head(&asoc->wait); |
| 196 | 199 | ||
| 197 | asoc->c.my_vtag = sctp_generate_tag(ep); | 200 | asoc->c.my_vtag = sctp_generate_tag(ep); |
| @@ -400,6 +403,8 @@ static void sctp_association_destroy(struct sctp_association *asoc) | |||
| 400 | spin_unlock_bh(&sctp_assocs_id_lock); | 403 | spin_unlock_bh(&sctp_assocs_id_lock); |
| 401 | } | 404 | } |
| 402 | 405 | ||
| 406 | BUG_TRAP(!atomic_read(&asoc->rmem_alloc)); | ||
| 407 | |||
| 403 | if (asoc->base.malloced) { | 408 | if (asoc->base.malloced) { |
| 404 | kfree(asoc); | 409 | kfree(asoc); |
| 405 | SCTP_DBG_OBJCNT_DEC(assoc); | 410 | SCTP_DBG_OBJCNT_DEC(assoc); |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 0df76897f563..67bd53070ee0 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
| @@ -104,6 +104,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
| 104 | sk->sk_write_space = sctp_write_space; | 104 | sk->sk_write_space = sctp_write_space; |
| 105 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); | 105 | sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); |
| 106 | 106 | ||
| 107 | /* Get the receive buffer policy for this endpoint */ | ||
| 108 | ep->rcvbuf_policy = sctp_rcvbuf_policy; | ||
| 109 | |||
| 107 | /* Initialize the secret key used with cookie. */ | 110 | /* Initialize the secret key used with cookie. */ |
| 108 | get_random_bytes(&ep->secret_key[0], SCTP_SECRET_SIZE); | 111 | get_random_bytes(&ep->secret_key[0], SCTP_SECRET_SIZE); |
| 109 | ep->last_key = ep->current_key = 0; | 112 | ep->last_key = ep->current_key = 0; |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 28f32243397f..b24ff2c1aef5 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
| @@ -100,21 +100,6 @@ static inline int sctp_rcv_checksum(struct sk_buff *skb) | |||
| 100 | return 0; | 100 | return 0; |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /* The free routine for skbuffs that sctp receives */ | ||
| 104 | static void sctp_rfree(struct sk_buff *skb) | ||
| 105 | { | ||
| 106 | atomic_sub(sizeof(struct sctp_chunk),&skb->sk->sk_rmem_alloc); | ||
| 107 | sock_rfree(skb); | ||
| 108 | } | ||
| 109 | |||
| 110 | /* The ownership wrapper routine to do receive buffer accounting */ | ||
| 111 | static void sctp_rcv_set_owner_r(struct sk_buff *skb, struct sock *sk) | ||
| 112 | { | ||
| 113 | skb_set_owner_r(skb,sk); | ||
| 114 | skb->destructor = sctp_rfree; | ||
| 115 | atomic_add(sizeof(struct sctp_chunk),&sk->sk_rmem_alloc); | ||
| 116 | } | ||
| 117 | |||
| 118 | struct sctp_input_cb { | 103 | struct sctp_input_cb { |
| 119 | union { | 104 | union { |
| 120 | struct inet_skb_parm h4; | 105 | struct inet_skb_parm h4; |
| @@ -217,9 +202,6 @@ int sctp_rcv(struct sk_buff *skb) | |||
| 217 | rcvr = &ep->base; | 202 | rcvr = &ep->base; |
| 218 | } | 203 | } |
| 219 | 204 | ||
| 220 | if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) | ||
| 221 | goto discard_release; | ||
| 222 | |||
| 223 | /* | 205 | /* |
| 224 | * RFC 2960, 8.4 - Handle "Out of the blue" Packets. | 206 | * RFC 2960, 8.4 - Handle "Out of the blue" Packets. |
| 225 | * An SCTP packet is called an "out of the blue" (OOTB) | 207 | * An SCTP packet is called an "out of the blue" (OOTB) |
| @@ -256,8 +238,6 @@ int sctp_rcv(struct sk_buff *skb) | |||
| 256 | } | 238 | } |
| 257 | SCTP_INPUT_CB(skb)->chunk = chunk; | 239 | SCTP_INPUT_CB(skb)->chunk = chunk; |
| 258 | 240 | ||
| 259 | sctp_rcv_set_owner_r(skb,sk); | ||
| 260 | |||
| 261 | /* Remember what endpoint is to handle this packet. */ | 241 | /* Remember what endpoint is to handle this packet. */ |
| 262 | chunk->rcvr = rcvr; | 242 | chunk->rcvr = rcvr; |
| 263 | 243 | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index dc9dff396fad..f775d78aa59d 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
| @@ -1050,6 +1050,9 @@ SCTP_STATIC __init int sctp_init(void) | |||
| 1050 | /* Sendbuffer growth - do per-socket accounting */ | 1050 | /* Sendbuffer growth - do per-socket accounting */ |
| 1051 | sctp_sndbuf_policy = 0; | 1051 | sctp_sndbuf_policy = 0; |
| 1052 | 1052 | ||
| 1053 | /* Rcvbuffer growth - do per-socket accounting */ | ||
