* [PATCH net-next-2.6] xfrm6_tunnel: RCU conversion
@ 2009-10-24 4:19 Eric Dumazet
2009-10-24 13:09 ` David Miller
0 siblings, 1 reply; 3+ messages in thread
From: Eric Dumazet @ 2009-10-24 4:19 UTC (permalink / raw)
To: David S. Miller; +Cc: Linux Netdev List, Yoshifuji Hideaki
xfrm6_tunnels use one rwlock to protect their hash tables.
Plain and straightforward conversion to RCU locking to permit better SMP
performance.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/ipv6/xfrm6_tunnel.c | 47 ++++++++++++++++++++++----------------
1 files changed, 28 insertions(+), 19 deletions(-)
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 81a95c0..438831d 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -23,7 +23,7 @@
*/
#include <linux/module.h>
#include <linux/xfrm.h>
-#include <linux/list.h>
+#include <linux/rculist.h>
#include <net/ip.h>
#include <net/xfrm.h>
#include <net/ipv6.h>
@@ -36,14 +36,15 @@
* per xfrm_address_t.
*/
struct xfrm6_tunnel_spi {
- struct hlist_node list_byaddr;
- struct hlist_node list_byspi;
- xfrm_address_t addr;
- u32 spi;
- atomic_t refcnt;
+ struct hlist_node list_byaddr;
+ struct hlist_node list_byspi;
+ xfrm_address_t addr;
+ u32 spi;
+ atomic_t refcnt;
+ struct rcu_head rcu_head;
};
-static DEFINE_RWLOCK(xfrm6_tunnel_spi_lock);
+static DEFINE_SPINLOCK(xfrm6_tunnel_spi_lock);
static u32 xfrm6_tunnel_spi;
@@ -107,6 +108,7 @@ static void xfrm6_tunnel_spi_fini(void)
if (!hlist_empty(&xfrm6_tunnel_spi_byspi[i]))
return;
}
+ rcu_barrier();
kmem_cache_destroy(xfrm6_tunnel_spi_kmem);
xfrm6_tunnel_spi_kmem = NULL;
}
@@ -116,7 +118,7 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
struct xfrm6_tunnel_spi *x6spi;
struct hlist_node *pos;
- hlist_for_each_entry(x6spi, pos,
+ hlist_for_each_entry_rcu(x6spi, pos,
&xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
list_byaddr) {
if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0)
@@ -131,10 +133,10 @@ __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
struct xfrm6_tunnel_spi *x6spi;
u32 spi;
- read_lock_bh(&xfrm6_tunnel_spi_lock);
+ rcu_read_lock_bh();
x6spi = __xfrm6_tunnel_spi_lookup(saddr);
spi = x6spi ? x6spi->spi : 0;
- read_unlock_bh(&xfrm6_tunnel_spi_lock);
+ rcu_read_unlock_bh();
return htonl(spi);
}
@@ -185,14 +187,15 @@ alloc_spi:
if (!x6spi)
goto out;
+ INIT_RCU_HEAD(&x6spi->rcu_head);
memcpy(&x6spi->addr, saddr, sizeof(x6spi->addr));
x6spi->spi = spi;
atomic_set(&x6spi->refcnt, 1);
- hlist_add_head(&x6spi->list_byspi, &xfrm6_tunnel_spi_byspi[index]);
+ hlist_add_head_rcu(&x6spi->list_byspi, &xfrm6_tunnel_spi_byspi[index]);
index = xfrm6_tunnel_spi_hash_byaddr(saddr);
- hlist_add_head(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]);
+ hlist_add_head_rcu(&x6spi->list_byaddr, &xfrm6_tunnel_spi_byaddr[index]);
out:
return spi;
}
@@ -202,26 +205,32 @@ __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
struct xfrm6_tunnel_spi *x6spi;
u32 spi;
- write_lock_bh(&xfrm6_tunnel_spi_lock);
+ spin_lock_bh(&xfrm6_tunnel_spi_lock);
x6spi = __xfrm6_tunnel_spi_lookup(saddr);
if (x6spi) {
atomic_inc(&x6spi->refcnt);
spi = x6spi->spi;
} else
spi = __xfrm6_tunnel_alloc_spi(saddr);
- write_unlock_bh(&xfrm6_tunnel_spi_lock);
+ spin_unlock_bh(&xfrm6_tunnel_spi_lock);
return htonl(spi);
}
EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi);
+static void x6spi_destroy_rcu(struct rcu_head *head)
+{
+ kmem_cache_free(xfrm6_tunnel_spi_kmem,
+ container_of(head, struct xfrm6_tunnel_spi, rcu_head));
+}
+
void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
{
struct xfrm6_tunnel_spi *x6spi;
struct hlist_node *pos, *n;
- write_lock_bh(&xfrm6_tunnel_spi_lock);
+ spin_lock_bh(&xfrm6_tunnel_spi_lock);
hlist_for_each_entry_safe(x6spi, pos, n,
&xfrm6_tunnel_spi_byaddr[xfrm6_tunnel_spi_hash_byaddr(saddr)],
@@ -229,14 +238,14 @@ void xfrm6_tunnel_free_spi(xfrm_address_t *saddr)
{
if (memcmp(&x6spi->addr, saddr, sizeof(x6spi->addr)) == 0) {
if (atomic_dec_and_test(&x6spi->refcnt)) {
- hlist_del(&x6spi->list_byaddr);
- hlist_del(&x6spi->list_byspi);
- kmem_cache_free(xfrm6_tunnel_spi_kmem, x6spi);
+ hlist_del_rcu(&x6spi->list_byaddr);
+ hlist_del_rcu(&x6spi->list_byspi);
+ call_rcu(&x6spi->rcu_head, x6spi_destroy_rcu);
break;
}
}
}
- write_unlock_bh(&xfrm6_tunnel_spi_lock);
+ spin_unlock_bh(&xfrm6_tunnel_spi_lock);
}
EXPORT_SYMBOL(xfrm6_tunnel_free_spi);
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH net-next-2.6] xfrm6_tunnel: RCU conversion
2009-10-24 4:19 [PATCH net-next-2.6] xfrm6_tunnel: RCU conversion Eric Dumazet
@ 2009-10-24 13:09 ` David Miller
2009-10-24 13:34 ` Eric Dumazet
0 siblings, 1 reply; 3+ messages in thread
From: David Miller @ 2009-10-24 13:09 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, yoshfuji
Nice work Eric, I applied all of your RCU conversions to
net-next-2.6, thanks!
Applying: ipv6 sit: RCU conversion phase I
Applying: ipv6 sit: RCU conversion phase II
Applying: xfrm6_tunnel: RCU conversion
Applying: ipip: convert hash tables locking to RCU
Applying: ip6tnl: convert hash tables locking to RCU
Applying: gre: convert hash tables locking to RCU
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH net-next-2.6] xfrm6_tunnel: RCU conversion
2009-10-24 13:09 ` David Miller
@ 2009-10-24 13:34 ` Eric Dumazet
0 siblings, 0 replies; 3+ messages in thread
From: Eric Dumazet @ 2009-10-24 13:34 UTC (permalink / raw)
To: David Miller; +Cc: netdev, yoshfuji
David Miller a écrit :
> Nice work Eric, I applied all of your RCU conversions to
> net-next-2.6, thanks!
>
> Applying: ipv6 sit: RCU conversion phase I
> Applying: ipv6 sit: RCU conversion phase II
> Applying: xfrm6_tunnel: RCU conversion
> Applying: ipip: convert hash tables locking to RCU
> Applying: ip6tnl: convert hash tables locking to RCU
> Applying: gre: convert hash tables locking to RCU
Thanks a lot !
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-10-24 13:34 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-10-24 4:19 [PATCH net-next-2.6] xfrm6_tunnel: RCU conversion Eric Dumazet
2009-10-24 13:09 ` David Miller
2009-10-24 13:34 ` Eric Dumazet
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).