Commit fd706d6957b3c66ae70b4bbdb9e13993213697f7
Committed by
David S. Miller
1 parent
d486dd1fb8
[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>
Showing 1 changed file with 8 additions and 5 deletions Side-by-side Diff
net/netfilter/core.c
... | ... | @@ -61,28 +61,31 @@ |
61 | 61 | * packets come back: if the hook is gone, the packet is discarded. */ |
62 | 62 | struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly; |
63 | 63 | EXPORT_SYMBOL(nf_hooks); |
64 | -static DEFINE_SPINLOCK(nf_hook_lock); | |
64 | +static DEFINE_MUTEX(nf_hook_mutex); | |
65 | 65 | |
66 | 66 | int nf_register_hook(struct nf_hook_ops *reg) |
67 | 67 | { |
68 | 68 | struct list_head *i; |
69 | + int err; | |
69 | 70 | |
70 | - spin_lock_bh(&nf_hook_lock); | |
71 | + err = mutex_lock_interruptible(&nf_hook_mutex); | |
72 | + if (err < 0) | |
73 | + return err; | |
71 | 74 | list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) { |
72 | 75 | if (reg->priority < ((struct nf_hook_ops *)i)->priority) |
73 | 76 | break; |
74 | 77 | } |
75 | 78 | list_add_rcu(®->list, i->prev); |
76 | - spin_unlock_bh(&nf_hook_lock); | |
79 | + mutex_unlock(&nf_hook_mutex); | |
77 | 80 | return 0; |
78 | 81 | } |
79 | 82 | EXPORT_SYMBOL(nf_register_hook); |
80 | 83 | |
81 | 84 | void nf_unregister_hook(struct nf_hook_ops *reg) |
82 | 85 | { |
83 | - spin_lock_bh(&nf_hook_lock); | |
86 | + mutex_lock(&nf_hook_mutex); | |
84 | 87 | list_del_rcu(®->list); |
85 | - spin_unlock_bh(&nf_hook_lock); | |
88 | + mutex_unlock(&nf_hook_mutex); | |
86 | 89 | |
87 | 90 | synchronize_net(); |
88 | 91 | } |