[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1315070771-18576-6-git-send-email-kaber@trash.net>
Date: Sat, 3 Sep 2011 19:26:05 +0200
From: kaber@...sh.net
To: davem@...emloft.net
Cc: netfilter-devel@...r.kernel.org, netdev@...r.kernel.org
Subject: [PATCH 05/11] netlink: add netlink_skb_set_owner_r()
From: Patrick McHardy <kaber@...sh.net>
For mmap'ed I/O a netlink specific skb destructor needs to be invoked after the
final kfree_skb() to clean up state in the memory mapped frames. This doesn
t work currently since the skb's ownership is transfered to the receiving
socket using skb_set_owner_r(), which orphans the skb, thereby invoking the
destructor prematurely.
Since netlink doesn't account skbs to the originating socket, there's no need
to orphan the skb. Add a netlink specific skb_set_owner_r() variant that does
not orphan the skb and use a netlink specific destructor to call sock_rfree().
Signed-off-by: Patrick McHardy <kaber@...sh.net>
---
net/netlink/af_netlink.c | 18 ++++++++++++++++--
1 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 7b9d7d0..1402acf 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -161,6 +161,20 @@ static void netlink_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
sk->sk_data_ready(sk, len);
}
+static void netlink_skb_destructor(struct sk_buff *skb)
+{
+ sock_rfree(skb);
+}
+
+static void netlink_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
+{
+ WARN_ON(skb->sk != NULL);
+ skb->sk = sk;
+ skb->destructor = netlink_skb_destructor;
+ atomic_add(skb->truesize, &sk->sk_rmem_alloc);
+ sk_mem_charge(sk, skb->truesize);
+}
+
static void netlink_sock_destruct(struct sock *sk)
{
struct netlink_sock *nlk = nlk_sk(sk);
@@ -838,7 +852,7 @@ int netlink_attachskb(struct sock *sk, struct sk_buff *skb,
}
return 1;
}
- skb_set_owner_r(skb, sk);
+ netlink_skb_set_owner_r(skb, sk);
return 0;
}
@@ -900,7 +914,7 @@ static inline int netlink_unicast_kernel(struct sock *sk, struct sk_buff *skb)
ret = -ECONNREFUSED;
if (nlk->netlink_rcv != NULL) {
ret = skb->len;
- skb_set_owner_r(skb, sk);
+ netlink_skb_set_owner_r(skb, sk);
nlk->netlink_rcv(skb);
}
kfree_skb(skb);
--
1.7.4.4
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists