summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2006-10-09 21:34:04 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2006-10-11 23:59:44 -0700
commit331c4ee7faa4ee1e1404c872a139784753100498 (patch)
treec5bbae21fd17f7948ab2506cad4d6f2ecba911ee /include
parent6e8c751e07b34d73069e9333f67fbe5ffe31ec3a (diff)
downloadlinux-3.10-331c4ee7faa4ee1e1404c872a139784753100498.tar.gz
linux-3.10-331c4ee7faa4ee1e1404c872a139784753100498.tar.bz2
linux-3.10-331c4ee7faa4ee1e1404c872a139784753100498.zip
[SCTP]: Fix receive buffer accounting.
When doing receiver buffer accounting, we always used skb->truesize. This is problematic when processing bundled DATA chunks because for every DATA chunk that could be small part of one large skb, we would charge the size of the entire skb. The new approach is to store the size of the DATA chunk we are accounting for in the sctp_ulpevent structure and use that stored value for accounting. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/sctp/sctp.h14
-rw-r--r--include/net/sctp/ulpevent.h1
2 files changed, 15 insertions, 0 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index ee68a312407..764e3af5be9 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -139,6 +139,7 @@ int sctp_inet_listen(struct socket *sock, int backlog);
void sctp_write_space(struct sock *sk);
unsigned int sctp_poll(struct file *file, struct socket *sock,
poll_table *wait);
+void sctp_sock_rfree(struct sk_buff *skb);
/*
* sctp/primitive.c
@@ -444,6 +445,19 @@ static inline struct list_head *sctp_list_dequeue(struct list_head *list)
return result;
}
+/* SCTP version of skb_set_owner_r. We need this one because
+ * of the way we have to do receive buffer accounting on bundled
+ * chunks.
+ */
+static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
+{
+ struct sctp_ulpevent *event = sctp_skb2event(skb);
+
+ skb->sk = sk;
+ skb->destructor = sctp_sock_rfree;
+ atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
+}
+
/* Tests if the list has one and only one entry. */
static inline int sctp_list_single_entry(struct list_head *head)
{
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index 6c40cfc4832..1a4ddc1ec7d 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -63,6 +63,7 @@ struct sctp_ulpevent {
__u32 cumtsn;
int msg_flags;
int iif;
+ unsigned int rmem_len;
};
/* Retrieve the skb this event sits inside of. */