All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
@ 2010-09-08 22:56 Eric Dumazet
  2010-09-08 23:49 ` Jesse Gross
  2010-09-09  4:31 ` David Miller
  0 siblings, 2 replies; 15+ messages in thread
From: Eric Dumazet @ 2010-09-08 22:56 UTC (permalink / raw)
  To: David Miller; +Cc: netdev

Use cmpxchg() to get rid of spinlocks in inet_add_protocol() and
friends.

inet_protos[] & inet6_protos[] are moved to read_mostly section

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
 net/ipv4/protocol.c |   31 +++++--------------------------
 net/ipv6/protocol.c |   32 ++++----------------------------
 2 files changed, 9 insertions(+), 54 deletions(-)

diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index f2d2973..65699c2 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -28,8 +28,7 @@
 #include <linux/spinlock.h>
 #include <net/protocol.h>
 
-const struct net_protocol *inet_protos[MAX_INET_PROTOS] ____cacheline_aligned_in_smp;
-static DEFINE_SPINLOCK(inet_proto_lock);
+const struct net_protocol *inet_protos[MAX_INET_PROTOS] __read_mostly;
 
 /*
  *	Add a protocol handler to the hash tables
@@ -37,20 +36,9 @@ static DEFINE_SPINLOCK(inet_proto_lock);
 
 int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
-	int hash, ret;
+	int hash = protocol & (MAX_INET_PROTOS - 1);
 
-	hash = protocol & (MAX_INET_PROTOS - 1);
-
-	spin_lock_bh(&inet_proto_lock);
-	if (inet_protos[hash]) {
-		ret = -1;
-	} else {
-		inet_protos[hash] = prot;
-		ret = 0;
-	}
-	spin_unlock_bh(&inet_proto_lock);
-
-	return ret;
+	return !cmpxchg(&inet_protos[hash], NULL, prot) ? 0 : -1;
 }
 EXPORT_SYMBOL(inet_add_protocol);
 
@@ -60,18 +48,9 @@ EXPORT_SYMBOL(inet_add_protocol);
 
 int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
 {
-	int hash, ret;
-
-	hash = protocol & (MAX_INET_PROTOS - 1);
+	int ret, hash = protocol & (MAX_INET_PROTOS - 1);
 
-	spin_lock_bh(&inet_proto_lock);
-	if (inet_protos[hash] == prot) {
-		inet_protos[hash] = NULL;
-		ret = 0;
-	} else {
-		ret = -1;
-	}
-	spin_unlock_bh(&inet_proto_lock);
+	ret = (cmpxchg(&inet_protos[hash], prot, NULL) == prot) ? 0 : -1;
 
 	synchronize_net();
 
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c
index 1fa3468..9bb936a 100644
--- a/net/ipv6/protocol.c
+++ b/net/ipv6/protocol.c
@@ -25,28 +25,14 @@
 #include <linux/spinlock.h>
 #include <net/protocol.h>
 
-const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS];
-static DEFINE_SPINLOCK(inet6_proto_lock);
-
+const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS] __read_mostly;
 
 int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol)
 {
-	int ret, hash = protocol & (MAX_INET_PROTOS - 1);
-
-	spin_lock_bh(&inet6_proto_lock);
-
-	if (inet6_protos[hash]) {
-		ret = -1;
-	} else {
-		inet6_protos[hash] = prot;
-		ret = 0;
-	}
-
-	spin_unlock_bh(&inet6_proto_lock);
+	int hash = protocol & (MAX_INET_PROTOS - 1);
 
-	return ret;
+	return !cmpxchg(&inet6_protos[hash], NULL, prot) ? 0 : -1;
 }
-
 EXPORT_SYMBOL(inet6_add_protocol);
 
 /*
@@ -57,20 +43,10 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol
 {
 	int ret, hash = protocol & (MAX_INET_PROTOS - 1);
 
-	spin_lock_bh(&inet6_proto_lock);
-
-	if (inet6_protos[hash] != prot) {
-		ret = -1;
-	} else {
-		inet6_protos[hash] = NULL;
-		ret = 0;
-	}
-
-	spin_unlock_bh(&inet6_proto_lock);
+	ret = (cmpxchg(&inet6_protos[hash], prot, NULL) == prot) ? 0 : -1;
 
 	synchronize_net();
 
 	return ret;
 }
-
 EXPORT_SYMBOL(inet6_del_protocol);



^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-08 22:56 [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg() Eric Dumazet
@ 2010-09-08 23:49 ` Jesse Gross
  2010-09-09  4:30   ` David Miller
  2010-09-09  5:23   ` Eric Dumazet
  2010-09-09  4:31 ` David Miller
  1 sibling, 2 replies; 15+ messages in thread
From: Jesse Gross @ 2010-09-08 23:49 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev

On Wed, Sep 8, 2010 at 3:56 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> Use cmpxchg() to get rid of spinlocks in inet_add_protocol() and
> friends.
>
> inet_protos[] & inet6_protos[] are moved to read_mostly section
>
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

What's the benefit to this?  It's hard to imagine that add/deleting
protocols is highly contended.  On the other hand, a simple spinlock
is very easy to look at and verify correct, while this takes a little
more thought.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-08 23:49 ` Jesse Gross
@ 2010-09-09  4:30   ` David Miller
  2010-09-09  6:42     ` Jarek Poplawski
  2010-09-09  5:23   ` Eric Dumazet
  1 sibling, 1 reply; 15+ messages in thread
From: David Miller @ 2010-09-09  4:30 UTC (permalink / raw)
  To: jesse; +Cc: eric.dumazet, netdev

From: Jesse Gross <jesse@nicira.com>
Date: Wed, 8 Sep 2010 16:49:27 -0700

> On Wed, Sep 8, 2010 at 3:56 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>> Use cmpxchg() to get rid of spinlocks in inet_add_protocol() and
>> friends.
>>
>> inet_protos[] & inet6_protos[] are moved to read_mostly section
>>
>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> 
> What's the benefit to this?  It's hard to imagine that add/deleting
> protocols is highly contended.  On the other hand, a simple spinlock
> is very easy to look at and verify correct, while this takes a little
> more thought.

Smaller data section is the benefit, thus less cache pressure there.

It's not about contention at all.

We've already applied other similar changes from Eric doing exactly
this kind of transformation and it's not all that non-trivial to me,
frankly.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-08 22:56 [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg() Eric Dumazet
  2010-09-08 23:49 ` Jesse Gross
@ 2010-09-09  4:31 ` David Miller
  1 sibling, 0 replies; 15+ messages in thread
From: David Miller @ 2010-09-09  4:31 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 09 Sep 2010 00:56:16 +0200

> Use cmpxchg() to get rid of spinlocks in inet_add_protocol() and
> friends.
> 
> inet_protos[] & inet6_protos[] are moved to read_mostly section
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Applied, thanks Eric.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-08 23:49 ` Jesse Gross
  2010-09-09  4:30   ` David Miller
@ 2010-09-09  5:23   ` Eric Dumazet
  1 sibling, 0 replies; 15+ messages in thread
From: Eric Dumazet @ 2010-09-09  5:23 UTC (permalink / raw)
  To: Jesse Gross; +Cc: David Miller, netdev

Le mercredi 08 septembre 2010 à 16:49 -0700, Jesse Gross a écrit :
> On Wed, Sep 8, 2010 at 3:56 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> > Use cmpxchg() to get rid of spinlocks in inet_add_protocol() and
> > friends.
> >
> > inet_protos[] & inet6_protos[] are moved to read_mostly section
> >
> > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> 
> What's the benefit to this?  It's hard to imagine that add/deleting
> protocols is highly contended.  On the other hand, a simple spinlock
> is very easy to look at and verify correct, while this takes a little
> more thought.

Good question.

Did you know that _bh() was not necessary for example at this point ?

Its a leftover of an RCU conversion, done many years ago. It _was_
working of course, but it really hurts my mind. We could use
stop_machine or other brute force thing too ;)


Before patch :

# size net/ipv4/protocol.o net/ipv6/protocol.o
   text	   data	    bss	    dec	    hex	filename
    340	      0	   2052	   2392	    958	net/ipv4/protocol.o
    342	      0	   2052	   2394	    95a	net/ipv6/protocol.o

After patch :

# size net/ipv4/protocol.o net/ipv6/protocol.o
   text	   data	    bss	    dec	    hex	filename
    220	   2048	      0	   2268	    8dc	net/ipv4/protocol.o
    222	   2048	      0	   2270	    8de	net/ipv6/protocol.o

45 lines removed, 240 bytes of text removed, I found this interesting.

Removing the ____cacheline_aligned_in_smp is also good, because
the .data alignement, is reduced and linker is not force to propagate
this alignement to upper .o files, with many holes.

If you take a look at most patches flying around, this one at least took
me to think a bit ;)

Thanks



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09  4:30   ` David Miller
@ 2010-09-09  6:42     ` Jarek Poplawski
  2010-09-09  6:55       ` Eric Dumazet
  0 siblings, 1 reply; 15+ messages in thread
From: Jarek Poplawski @ 2010-09-09  6:42 UTC (permalink / raw)
  To: David Miller; +Cc: jesse, eric.dumazet, netdev

On 2010-09-09 06:30, David Miller wrote:
> From: Jesse Gross <jesse@nicira.com>
> Date: Wed, 8 Sep 2010 16:49:27 -0700
> 
>> On Wed, Sep 8, 2010 at 3:56 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>>> Use cmpxchg() to get rid of spinlocks in inet_add_protocol() and
>>> friends.
>>>
>>> inet_protos[] & inet6_protos[] are moved to read_mostly section
>>>
>>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>>
>> What's the benefit to this?  It's hard to imagine that add/deleting
>> protocols is highly contended.  On the other hand, a simple spinlock
>> is very easy to look at and verify correct, while this takes a little
>> more thought.
> 
> Smaller data section is the benefit, thus less cache pressure there.
> 
Of course, each case is different, but generally I understand Jesse's
concern. Smaller data section argument shouldn't be enough. There is
some reason we do it in C not asm, and there is some cost of
unreadable code too.

Jarek P.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09  6:42     ` Jarek Poplawski
@ 2010-09-09  6:55       ` Eric Dumazet
  2010-09-09  7:09         ` Jarek Poplawski
  0 siblings, 1 reply; 15+ messages in thread
From: Eric Dumazet @ 2010-09-09  6:55 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: David Miller, jesse, netdev

Le jeudi 09 septembre 2010 à 06:42 +0000, Jarek Poplawski a écrit :
> Of course, each case is different, but generally I understand Jesse's
> concern. Smaller data section argument shouldn't be enough. There is
> some reason we do it in C not asm, and there is some cost of
> unreadable code too.

Sure, but is cmpxchg() really not readable for you ? ;)

Now it is available for all arches, you can bet it is going to be
adopted.




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09  6:55       ` Eric Dumazet
@ 2010-09-09  7:09         ` Jarek Poplawski
  2010-09-09  7:24           ` Jarek Poplawski
  0 siblings, 1 reply; 15+ messages in thread
From: Jarek Poplawski @ 2010-09-09  7:09 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, jesse, netdev

On Thu, Sep 09, 2010 at 08:55:45AM +0200, Eric Dumazet wrote:
> Le jeudi 09 septembre 2010 ?? 06:42 +0000, Jarek Poplawski a écrit :
> > Of course, each case is different, but generally I understand Jesse's
> > concern. Smaller data section argument shouldn't be enough. There is
> > some reason we do it in C not asm, and there is some cost of
> > unreadable code too.
> 
> Sure, but is cmpxchg() really not readable for you ? ;)

Just like for Jesse: "this takes a little more thought". ;-)

Jarek P.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09  7:09         ` Jarek Poplawski
@ 2010-09-09  7:24           ` Jarek Poplawski
  2010-09-09  9:08             ` Jarek Poplawski
  0 siblings, 1 reply; 15+ messages in thread
From: Jarek Poplawski @ 2010-09-09  7:24 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, jesse, netdev

On Thu, Sep 09, 2010 at 07:09:26AM +0000, Jarek Poplawski wrote:
> On Thu, Sep 09, 2010 at 08:55:45AM +0200, Eric Dumazet wrote:
> > Le jeudi 09 septembre 2010 ?? 06:42 +0000, Jarek Poplawski a écrit :
> > > Of course, each case is different, but generally I understand Jesse's
> > > concern. Smaller data section argument shouldn't be enough. There is
> > > some reason we do it in C not asm, and there is some cost of
> > > unreadable code too.
> > 
> > Sure, but is cmpxchg() really not readable for you ? ;)
> 
> Just like for Jesse: "this takes a little more thought". ;-)

But more exactly, it's not about this one line, but the time you need
when reading this after some time to tell: yes, this place is properly
locked for sure.

Jarek P.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09  7:24           ` Jarek Poplawski
@ 2010-09-09  9:08             ` Jarek Poplawski
  2010-09-09  9:23               ` Eric Dumazet
  0 siblings, 1 reply; 15+ messages in thread
From: Jarek Poplawski @ 2010-09-09  9:08 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, jesse, netdev

On Thu, Sep 09, 2010 at 07:24:53AM +0000, Jarek Poplawski wrote:
> On Thu, Sep 09, 2010 at 07:09:26AM +0000, Jarek Poplawski wrote:
> > On Thu, Sep 09, 2010 at 08:55:45AM +0200, Eric Dumazet wrote:
> > > Le jeudi 09 septembre 2010 ?? 06:42 +0000, Jarek Poplawski a écrit :
> > > > Of course, each case is different, but generally I understand Jesse's
> > > > concern. Smaller data section argument shouldn't be enough. There is
> > > > some reason we do it in C not asm, and there is some cost of
> > > > unreadable code too.
> > > 
> > > Sure, but is cmpxchg() really not readable for you ? ;)
> > 
> > Just like for Jesse: "this takes a little more thought". ;-)
> 
> But more exactly, it's not about this one line, but the time you need
> when reading this after some time to tell: yes, this place is properly
> locked for sure.

And most exactly, without "after some time" I couldn't tell this
either. Is seems some barriers might have been changed, but I might
be wrong. Anyway, it would be nice to have some comment on that in
the changelog.

Jarek P.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09  9:08             ` Jarek Poplawski
@ 2010-09-09  9:23               ` Eric Dumazet
  2010-09-09  9:42                 ` Jarek Poplawski
  2010-09-09  9:59                 ` Jarek Poplawski
  0 siblings, 2 replies; 15+ messages in thread
From: Eric Dumazet @ 2010-09-09  9:23 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: David Miller, jesse, netdev

Le jeudi 09 septembre 2010 à 09:08 +0000, Jarek Poplawski a écrit :
> xactly, without "after some time" I couldn't tell this
> either. Is seems some barriers might have been changed, but I might
> be wrong. Anyway, it would be nice to have some comment on that in
> the changelog.

Jarek, cmpxchg() is a very strong primitive, as documented
in Documentation/memory-barriers.txt :

<begin of quote>

Any atomic operation that modifies some state in memory and returns information
about the state (old or new) implies an SMP-conditional general memory barrier
(smp_mb()) on each side of the actual operation (with the exception of
explicit lock operations, described later).  These include:

        xchg();
        cmpxchg();
...
These are used for such things as implementing LOCK-class and UNLOCK-class
operations and adjusting reference counters towards object destruction, and as
such the implicit memory barrier effects are necessary.

<end of quote>

Its not needed to document each cmpxchg() use, because of these
strong requirements.




^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09  9:23               ` Eric Dumazet
@ 2010-09-09  9:42                 ` Jarek Poplawski
  2010-09-09  9:59                 ` Jarek Poplawski
  1 sibling, 0 replies; 15+ messages in thread
From: Jarek Poplawski @ 2010-09-09  9:42 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, jesse, netdev

On Thu, Sep 09, 2010 at 11:23:57AM +0200, Eric Dumazet wrote:
> Le jeudi 09 septembre 2010 ?? 09:08 +0000, Jarek Poplawski a écrit :
> > xactly, without "after some time" I couldn't tell this
> > either. Is seems some barriers might have been changed, but I might
> > be wrong. Anyway, it would be nice to have some comment on that in
> > the changelog.
> 
> Jarek, cmpxchg() is a very strong primitive, as documented
> in Documentation/memory-barriers.txt :
> 
> <begin of quote>
> 
> Any atomic operation that modifies some state in memory and returns information
> about the state (old or new) implies an SMP-conditional general memory barrier
> (smp_mb()) on each side of the actual operation (with the exception of
> explicit lock operations, described later).  These include:
> 
>         xchg();
>         cmpxchg();
> ...
> These are used for such things as implementing LOCK-class and UNLOCK-class
> operations and adjusting reference counters towards object destruction, and as
> such the implicit memory barrier effects are necessary.
> 
> <end of quote>
> 
> Its not needed to document each cmpxchg() use, because of these
> strong requirements.

OK! I should remember this until "after some time". ;-)

Thanks for the explanation,
Jarek P.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09  9:23               ` Eric Dumazet
  2010-09-09  9:42                 ` Jarek Poplawski
@ 2010-09-09  9:59                 ` Jarek Poplawski
  2010-09-09 12:57                   ` Eric Dumazet
  1 sibling, 1 reply; 15+ messages in thread
From: Jarek Poplawski @ 2010-09-09  9:59 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, jesse, netdev

On Thu, Sep 09, 2010 at 11:23:57AM +0200, Eric Dumazet wrote:
> Le jeudi 09 septembre 2010 ?? 09:08 +0000, Jarek Poplawski a écrit :
> > xactly, without "after some time" I couldn't tell this
> > either. Is seems some barriers might have been changed, but I might
> > be wrong. Anyway, it would be nice to have some comment on that in
> > the changelog.
> 
> Jarek, cmpxchg() is a very strong primitive, as documented
> in Documentation/memory-barriers.txt :
...
> Its not needed to document each cmpxchg() use, because of these
> strong requirements.
> 

Btw, I wonder if for readability and debuging it shouldn't be made
generic as rcu_cmpxchg_pointer() etc.?

Jarek P.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09  9:59                 ` Jarek Poplawski
@ 2010-09-09 12:57                   ` Eric Dumazet
  2010-09-09 15:38                     ` Jarek Poplawski
  0 siblings, 1 reply; 15+ messages in thread
From: Eric Dumazet @ 2010-09-09 12:57 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: David Miller, jesse, netdev

Le jeudi 09 septembre 2010 à 09:59 +0000, Jarek Poplawski a écrit :

> Btw, I wonder if for readability and debuging it shouldn't be made
> generic as rcu_cmpxchg_pointer() etc.?

There are a lot of things to do in this area (with proper __rcu sparse
annotations, this can be not very readable ...)


/**
 * rcu_cmpxchg - atomic compare and exchange, SMP & rcu safe
 * @p: pointer to value
 * @old: old value
 * @new: new value
 *
 * Equivalent to :
 *    ATOMIC_BEGIN
 *     ret = *p;
 *     if (ret == old)
 *             rcu_assign_pointer(*p, new);
 *    ATOMIC_END
 *    return ret;
 *
 * cmpxpchg() contains full memory barriers, so can be used
 * in rcu write side without additional smp_wmb() barrier
 */
#define rcu_cmpxchg(p, old, new) cmpxchg(p, old, new)


const struct net_protocol __rcu *
        inet_protos[MAX_INET_PROTOS] __read_mostly;

...

return !rcu_cmpxchg(&inet_protos[hash], 
                    NULL,
                    (const struct net_protocol __force __rcu *)prot) ?
		0 : -1;

...



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg()
  2010-09-09 12:57                   ` Eric Dumazet
@ 2010-09-09 15:38                     ` Jarek Poplawski
  0 siblings, 0 replies; 15+ messages in thread
From: Jarek Poplawski @ 2010-09-09 15:38 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, jesse, netdev

On Thu, Sep 09, 2010 at 02:57:38PM +0200, Eric Dumazet wrote:
> Le jeudi 09 septembre 2010 ?? 09:59 +0000, Jarek Poplawski a écrit :
> 
> > Btw, I wonder if for readability and debuging it shouldn't be made
> > generic as rcu_cmpxchg_pointer() etc.?
> 
> There are a lot of things to do in this area (with proper __rcu sparse
> annotations, this can be not very readable ...)

Well, this is more than I could dream ;-) The main point to me was
autodocumentation in use, similarly to rcu_assign_pointer(). But, of
course, with the description below it's much better.

Thanks,
Jarek P.

> 
> /**
>  * rcu_cmpxchg - atomic compare and exchange, SMP & rcu safe
>  * @p: pointer to value
>  * @old: old value
>  * @new: new value
>  *
>  * Equivalent to :
>  *    ATOMIC_BEGIN
>  *     ret = *p;
>  *     if (ret == old)
>  *             rcu_assign_pointer(*p, new);
>  *    ATOMIC_END
>  *    return ret;
>  *
>  * cmpxpchg() contains full memory barriers, so can be used
>  * in rcu write side without additional smp_wmb() barrier
>  */
> #define rcu_cmpxchg(p, old, new) cmpxchg(p, old, new)
> 
> 
> const struct net_protocol __rcu *
>         inet_protos[MAX_INET_PROTOS] __read_mostly;
> 
> ...
> 
> return !rcu_cmpxchg(&inet_protos[hash], 
>                     NULL,
>                     (const struct net_protocol __force __rcu *)prot) ?
> 		0 : -1;
> 
> ...
> 


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2010-09-09 15:38 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-08 22:56 [PATCH net-next-2.6] net: inet_add_protocol() can use cmpxchg() Eric Dumazet
2010-09-08 23:49 ` Jesse Gross
2010-09-09  4:30   ` David Miller
2010-09-09  6:42     ` Jarek Poplawski
2010-09-09  6:55       ` Eric Dumazet
2010-09-09  7:09         ` Jarek Poplawski
2010-09-09  7:24           ` Jarek Poplawski
2010-09-09  9:08             ` Jarek Poplawski
2010-09-09  9:23               ` Eric Dumazet
2010-09-09  9:42                 ` Jarek Poplawski
2010-09-09  9:59                 ` Jarek Poplawski
2010-09-09 12:57                   ` Eric Dumazet
2010-09-09 15:38                     ` Jarek Poplawski
2010-09-09  5:23   ` Eric Dumazet
2010-09-09  4:31 ` David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.