diff options
| author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-09-08 21:31:35 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-09-08 21:31:35 -0700 | 
| commit | e0386005ff2a729998735e10769d99e1acbc2dd1 (patch) | |
| tree | c04134571b728581d9692fb16dffcdd38d52dbda /net/ipv6/protocol.c | |
| parent | 92e32eaee288ee2e838fe76680cbaeaea25643c6 (diff) | |
| download | olio-linux-3.10-e0386005ff2a729998735e10769d99e1acbc2dd1.tar.xz olio-linux-3.10-e0386005ff2a729998735e10769d99e1acbc2dd1.zip  | |
net: inet_add_protocol() can use cmpxchg()
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>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/protocol.c')
| -rw-r--r-- | net/ipv6/protocol.c | 32 | 
1 files changed, 4 insertions, 28 deletions
diff --git a/net/ipv6/protocol.c b/net/ipv6/protocol.c index 1fa3468f0f3..9bb936ae245 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);  |