diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2010-12-09 12:17:25 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2010-12-09 12:17:25 -0500 |
commit | d834a9dcecae834cd6b2bc5e50e1907738d9cf6a (patch) | |
tree | 0589d753465d3fe359ba451ba6cb7798df03aaa2 /net/ipv6/protocol.c | |
parent | a38c5380ef9f088be9f49b6e4c5d80af8b1b5cd4 (diff) | |
parent | f658bcfb2607bf0808966a69cf74135ce98e5c2d (diff) |
Merge branch 'x86/amd-nb' into x86/apic-cleanups
Reason: apic cleanup series depends on x86/apic, x86/amd-nb x86/platform
Conflicts:
arch/x86/include/asm/io_apic.h
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'net/ipv6/protocol.c')
-rw-r--r-- | net/ipv6/protocol.c | 34 |
1 files changed, 6 insertions, 28 deletions
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c index 1fa3468f0f32..9a7978fdc02a 100644 --- a/net/ipv6/protocol.c +++ b/net/ipv6/protocol.c | |||
@@ -25,28 +25,15 @@ | |||
25 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
26 | #include <net/protocol.h> | 26 | #include <net/protocol.h> |
27 | 27 | ||
28 | const struct inet6_protocol *inet6_protos[MAX_INET_PROTOS]; | 28 | const struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly; |
29 | static DEFINE_SPINLOCK(inet6_proto_lock); | ||
30 | |||
31 | 29 | ||
32 | int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) | 30 | int inet6_add_protocol(const struct inet6_protocol *prot, unsigned char protocol) |
33 | { | 31 | { |
34 | int ret, hash = protocol & (MAX_INET_PROTOS - 1); | 32 | int hash = protocol & (MAX_INET_PROTOS - 1); |
35 | |||
36 | spin_lock_bh(&inet6_proto_lock); | ||
37 | |||
38 | if (inet6_protos[hash]) { | ||
39 | ret = -1; | ||
40 | } else { | ||
41 | inet6_protos[hash] = prot; | ||
42 | ret = 0; | ||
43 | } | ||
44 | |||
45 | spin_unlock_bh(&inet6_proto_lock); | ||
46 | 33 | ||
47 | return ret; | 34 | return !cmpxchg((const struct inet6_protocol **)&inet6_protos[hash], |
35 | NULL, prot) ? 0 : -1; | ||
48 | } | 36 | } |
49 | |||
50 | EXPORT_SYMBOL(inet6_add_protocol); | 37 | EXPORT_SYMBOL(inet6_add_protocol); |
51 | 38 | ||
52 | /* | 39 | /* |
@@ -57,20 +44,11 @@ int inet6_del_protocol(const struct inet6_protocol *prot, unsigned char protocol | |||
57 | { | 44 | { |
58 | int ret, hash = protocol & (MAX_INET_PROTOS - 1); | 45 | int ret, hash = protocol & (MAX_INET_PROTOS - 1); |
59 | 46 | ||
60 | spin_lock_bh(&inet6_proto_lock); | 47 | ret = (cmpxchg((const struct inet6_protocol **)&inet6_protos[hash], |
61 | 48 | prot, NULL) == prot) ? 0 : -1; | |
62 | if (inet6_protos[hash] != prot) { | ||
63 | ret = -1; | ||
64 | } else { | ||
65 | inet6_protos[hash] = NULL; | ||
66 | ret = 0; | ||
67 | } | ||
68 | |||
69 | spin_unlock_bh(&inet6_proto_lock); | ||
70 | 49 | ||
71 | synchronize_net(); | 50 | synchronize_net(); |
72 | 51 | ||
73 | return ret; | 52 | return ret; |
74 | } | 53 | } |
75 | |||
76 | EXPORT_SYMBOL(inet6_del_protocol); | 54 | EXPORT_SYMBOL(inet6_del_protocol); |