aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Horman <nhorman@tuxdriver.com>2005-11-11 19:08:24 -0500
committerDavid S. Miller <davem@davemloft.net>2005-11-11 19:08:24 -0500
commit049b3ff5a86d0187184a189d2e31b8654d58fe22 (patch)
treeaed83ae799e444c57d76597bad6e3b41957a828e
parent19c7e9eef503dc1ae926f3d26c56f88bee568d7b (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.h1
-rw-r--r--include/net/sctp/structs.h16
-rw-r--r--net/sctp/associola.c9
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/input.c20
-rw-r--r--net/sctp/protocol.c3
-rw-r--r--net/sctp/sm_statefuns.c22
-rw-r--r--net/sctp/socket.c4
-rw-r--r--net/sctp/sysctl.c8
-rw-r--r--net/sctp/ulpevent.c24
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 */
104static 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 */
111static 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
118struct sctp_input_cb { 103struct 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 */