From: Patrick McHardy Date: Mon, 12 Feb 2007 19:10:14 +0000 (-0800) Subject: [NETFILTER]: Switch nf_register_hook/nf_unregister_hook to mutex X-Git-Tag: v2.6.21-rc1~274^2~1^2~21 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fd706d6957b3c66ae70b4bbdb9e13993213697f7;p=linux-2.6 [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 Signed-off-by: David S. Miller --- diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 716603f05c..f61e0c2eec 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(); }