[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>
This commit is contained in:
Neil Horman 2005-04-28 12:02:04 -07:00 committed by David S. Miller
parent 594ccc14df
commit 4eb701dfc6
6 changed files with 54 additions and 6 deletions

View file

@ -115,9 +115,17 @@ static inline int sctp_wspace(struct sctp_association *asoc)
struct sock *sk = asoc->base.sk;
int amt = 0;
amt = sk->sk_sndbuf - asoc->sndbuf_used;
if (asoc->ep->sndbuf_policy) {
/* make sure that no association uses more than sk_sndbuf */
amt = sk->sk_sndbuf - asoc->sndbuf_used;
} else {
/* do socket level accounting */
amt = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
}
if (amt < 0)
amt = 0;
return amt;
}
@ -138,12 +146,21 @@ static inline void sctp_set_owner_w(struct sctp_chunk *chunk)
/* The sndbuf space is tracked per association. */
sctp_association_hold(asoc);
skb_set_owner_w(chunk->skb, sk);
chunk->skb->destructor = sctp_wfree;
/* Save the chunk pointer in skb for sctp_wfree to use later. */
*((struct sctp_chunk **)(chunk->skb->cb)) = chunk;
asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk);
sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk);
asoc->sndbuf_used += SCTP_DATA_SNDSIZE(chunk) +
sizeof(struct sk_buff) +
sizeof(struct sctp_chunk);
sk->sk_wmem_queued += SCTP_DATA_SNDSIZE(chunk) +
sizeof(struct sk_buff) +
sizeof(struct sctp_chunk);
atomic_add(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
}
/* Verify that this is a valid address. */
@ -4422,8 +4439,17 @@ static void sctp_wfree(struct sk_buff *skb)
chunk = *((struct sctp_chunk **)(skb->cb));
asoc = chunk->asoc;
sk = asoc->base.sk;
asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk);
sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk);
asoc->sndbuf_used -= SCTP_DATA_SNDSIZE(chunk) +
sizeof(struct sk_buff) +
sizeof(struct sctp_chunk);
sk->sk_wmem_queued -= SCTP_DATA_SNDSIZE(chunk) +
sizeof(struct sk_buff) +
sizeof(struct sctp_chunk);
atomic_sub(sizeof(struct sctp_chunk), &sk->sk_wmem_alloc);
sock_wfree(skb);
__sctp_write_space(asoc);
sctp_association_put(asoc);