diff options
author | Patrick McHardy <kaber@trash.net> | 2007-02-12 11:10:14 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-02-12 11:10:14 -0800 |
commit | fd706d6957b3c66ae70b4bbdb9e13993213697f7 (patch) | |
tree | 7b035f737c93b8d913c999c9a64eb52488c1f6ca /net | |
parent | d486dd1fb8573fad5b8dab61a7d1406116fd4baf (diff) | |
download | linux-fd706d6957b3c66ae70b4bbdb9e13993213697f7.tar.bz2 |
[NETFILTER]: Switch nf_register_hook/nf_unregister_hook to mutex
The spinlock is only used in process context (register/unregister)
since RCU is used for the nf_hook lists, switch to a mutex.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/core.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 716603f05c02..f61e0c2eece9 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -61,28 +61,31 @@ EXPORT_SYMBOL_GPL(nf_unregister_afinfo); * packets come back: if the hook is gone, the packet is discarded. */ struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly; EXPORT_SYMBOL(nf_hooks); -static DEFINE_SPINLOCK(nf_hook_lock); +static DEFINE_MUTEX(nf_hook_mutex); int nf_register_hook(struct nf_hook_ops *reg) { struct list_head *i; + int err; - spin_lock_bh(&nf_hook_lock); + err = mutex_lock_interruptible(&nf_hook_mutex); + if (err < 0) + return err; list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) { if (reg->priority < ((struct nf_hook_ops *)i)->priority) break; } list_add_rcu(®->list, i->prev); - spin_unlock_bh(&nf_hook_lock); + mutex_unlock(&nf_hook_mutex); return 0; } EXPORT_SYMBOL(nf_register_hook); void nf_unregister_hook(struct nf_hook_ops *reg) { - spin_lock_bh(&nf_hook_lock); + mutex_lock(&nf_hook_mutex); list_del_rcu(®->list); - spin_unlock_bh(&nf_hook_lock); + mutex_unlock(&nf_hook_mutex); synchronize_net(); } |