From: Eric Dumazet <eric.dumazet@gmail.com>
To: Stephen Hemminger <shemminger@vyatta.com>
Cc: David Miller <davem@davemloft.net>, netdev@vger.kernel.org
Subject: Re: [PATCH] netlink: convert DIY reader/writer to mutex and RCU (v2)
Date: Tue, 16 Mar 2010 16:00:35 +0100 [thread overview]
Message-ID: <1268751635.3094.43.camel@edumazet-laptop> (raw)
In-Reply-To: <20100308140021.234a120a@nehalam>
Le lundi 08 mars 2010 à 14:00 -0800, Stephen Hemminger a écrit :
> The netlink table locking was open coded version of reader/writer
> sleeping lock. Change to using mutex and RCU which makes
> code clearer, shorter, and simpler.
>
> Could use sk_list nulls but then would have to have kmem_cache
> for netlink handles and that seems like unnecessary bloat.
>
> Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
>
> ---
> v1 -> v2 do RCU correctly...
> * use spinlock not mutex (not safe to sleep in normal RCU)
> * use _rcu variants of add/delete
> kfree(nlk->groups);
> nlk->groups = NULL;
> @@ -533,6 +477,8 @@ static int netlink_release(struct socket
> local_bh_disable();
> sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1);
> local_bh_enable();
> +
> + synchronize_rcu();
> sock_put(sk);
> return 0;
I am a bit scared by synchronize_rcu() proliferation. This can slow down
some workloads (some scripts invoking netlink commands, not using batch
mode)
We could change sk_prot_free() behavior and optionaly call a callback to
free a socket (and the module_put()) after rcu grace period. As the
rcu_head is not inside struct sock, I could not find a generic way to
code this.
For TCP/UDP sockets this was considered not a viable alternative, but
for other sockets its certainly better than synchronize_rcu() ?
diff --git a/include/net/sock.h b/include/net/sock.h
index 092b055..3a2d598 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -693,6 +693,8 @@ struct proto {
int (*backlog_rcv) (struct sock *sk,
struct sk_buff *skb);
+ void (*free_socket)(struct sock *sk);
+
/* Keeping track of sk's, looking them up, and port selection methods. */
void (*hash)(struct sock *sk);
void (*unhash)(struct sock *sk);
diff --git a/net/core/sock.c b/net/core/sock.c
index c5812bb..3060c9b 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1027,18 +1027,20 @@ out_free:
static void sk_prot_free(struct proto *prot, struct sock *sk)
{
- struct kmem_cache *slab;
- struct module *owner;
+ security_sk_free(sk);
+ if (prot->free_socket)
+ prot->free_socket(sk);
+ else {
+ struct kmem_cache *slab;
- owner = prot->owner;
- slab = prot->slab;
+ slab = prot->slab;
- security_sk_free(sk);
- if (slab != NULL)
- kmem_cache_free(slab, sk);
- else
- kfree(sk);
- module_put(owner);
+ if (slab != NULL)
+ kmem_cache_free(slab, sk);
+ else
+ kfree(sk);
+ module_put(prot->owner);
+ }
}
/**
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 320d042..fae2344 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -81,6 +81,7 @@ struct netlink_sock {
struct mutex cb_def_mutex;
void (*netlink_rcv)(struct sk_buff *skb);
struct module *module;
+ struct rcu_head rcu;
};
struct listeners_rcu_head {
@@ -394,10 +395,22 @@ static void netlink_remove(struct sock *sk)
netlink_table_ungrab();
}
+static void rcu_free_socket(struct rcu_head *rcu)
+{
+ kfree(container_of(rcu, struct netlink_sock, rcu));
+ module_put(THIS_MODULE);
+}
+
+static void free_socket(struct sock *sk)
+{
+ call_rcu(&nlk_sk(sk)->rcu, rcu_free_socket);
+}
+
static struct proto netlink_proto = {
.name = "NETLINK",
.owner = THIS_MODULE,
.obj_size = sizeof(struct netlink_sock),
+ .free_socket = free_socket,
};
static int __netlink_create(struct net *net, struct socket *sock,
next prev parent reply other threads:[~2010-03-16 15:00 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-08 21:32 [PATCH] netlink: convert DIY reader/writer to mutex and RCU Stephen Hemminger
2010-03-08 22:00 ` [PATCH] netlink: convert DIY reader/writer to mutex and RCU (v2) Stephen Hemminger
2010-03-16 15:00 ` Eric Dumazet [this message]
2010-03-19 0:44 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1268751635.3094.43.camel@edumazet-laptop \
--to=eric.dumazet@gmail.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=shemminger@vyatta.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox