aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/socket.c
diff options
context:
space:
mode:
authorNeil Horman <nhorman@redhat.com>2005-04-28 15:02:04 -0400
committerDavid S. Miller <davem@davemloft.net>2005-04-28 15:02:04 -0400
commit4eb701dfc618491c9b97377df6e61de36dfc39ce (patch)
treeb49f31ebecda19d071d3ae3777be2a6a8c9e5c34 /net/sctp/socket.c
parent594ccc14dfe4d61b476491758425a1c2ca4ec71b (diff)
[SCTP] Fix SCTP sendbuffer accouting.
- Include chunk and skb sizes in sendbuffer accounting. - 2 policies are supported. 0: per socket accouting, 1: per association accounting DaveM: I've made the default per-socket. Signed-off-by: Neil Horman <nhorman@redhat.com> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r--net/sctp/socket.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 32f2249411fa..0b338eca6dc0 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -115,9 +115,17 @@ static inline int sctp_wspace(struct sctp_association *asoc)
115 struct sock *sk = asoc->base.sk; 115 struct sock *sk = asoc->base.sk;
116 int amt = 0; 116 int amt = 0;
117 117
118 amt = sk->sk_sndbuf - asoc->sndbuf_used; 118 if (asoc->ep->sndbuf_policy) {
119 /* make sure that no association uses more than sk_sndbuf */
120 amt = sk->sk_sndbuf - asoc->sndbuf_used;
121 } else {
122 /* do socket level accounting */
123 amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
124 }
125
119 if (amt < 0) 126 if (amt < 0)
120 amt = 0; 127 amt = 0;
128
121 return amt; 129 return amt;
122} 130}
123 131
@@ -138,12 +146,21 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
138 /* The sndbuf space is tracked per association. */ 146 /* The sndbuf space is tracked per association. */
139 sctp_association_hold(asoc); 147 sctp_association_hold(asoc);
140 148
149 skb_set_owner_w(chunk->skb, sk);
150
141 chunk->skb->destructor = sctp_wfree; 151 chunk->skb->destructor = sctp_wfree;
142 /* Save the chunk pointer in skb for sctp_wfree to use later. */ 152 /* Save the chunk pointer in skb for sctp_wfree to use later. */
143 *((struct sctp_chunk **)(chunk->skb->cb)) = chunk; 153 *((struct sctp_chunk **)(chunk->skb->cb)) = chunk;
144 154
145 asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk); 155 asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk) +
146 sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk); 156 sizeof(struct sk_buff) +
157 sizeof(struct sctp_chunk);
158
159 sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk) +
160 sizeof(struct sk_buff) +
161 sizeof(struct sctp_chunk);
162
163 atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
147} 164}
148 165
149/* Verify that this is a valid address. */ 166/* Verify that this is a valid address. */
@@ -4422,8 +4439,17 @@ static void sctp_wfree(struct sk_buff *skb)
4422 chunk = *((struct sctp_chunk **)(skb->cb)); 4439 chunk = *((struct sctp_chunk **)(skb->cb));
4423 asoc = chunk->asoc; 4440 asoc = chunk->asoc;
4424 sk = asoc->base.sk; 4441 sk = asoc->base.sk;
4425 asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk); 4442 asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk) +
4426 sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk); 4443 sizeof(struct sk_buff) +
4444 sizeof(struct sctp_chunk);
4445
4446 sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk) +
4447 sizeof(struct sk_buff) +
4448 sizeof(struct sctp_chunk);
4449
4450 atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
4451
4452 sock_wfree(skb);
4427 __sctp_write_space(asoc); 4453 __sctp_write_space(asoc);
4428 4454
4429 sctp_association_put(asoc); 4455 sctp_association_put(asoc);