From b19caa0ca071dce76b0e81e957e7eb7c03d72cf5 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Wed, 14 Mar 2007 16:37:52 -0700 Subject: [PATCH] [NETFILTER]: nf_conntrack: switch protocol registration/unregistration to mutex The protocol lookups done by nf_conntrack are already protected by RCU, there is no need to keep taking nf_conntrack_lock for registration and unregistration. Switch to a mutex. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nf_conntrack_proto.c | 52 +++++++++++++----------------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 456155f05c75..e2c4a58603a8 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -32,9 +32,9 @@ struct nf_conntrack_l4proto **nf_ct_protos[PF_MAX] __read_mostly; struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX] __read_mostly; EXPORT_SYMBOL_GPL(nf_ct_l3protos); -#ifdef CONFIG_SYSCTL -static DEFINE_MUTEX(nf_ct_proto_sysctl_mutex); +static DEFINE_MUTEX(nf_ct_proto_mutex); +#ifdef CONFIG_SYSCTL static int nf_ct_register_sysctl(struct ctl_table_header **header, struct ctl_table *path, struct ctl_table *table, unsigned int *users) @@ -164,13 +164,13 @@ static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto) int err = 0; #ifdef CONFIG_SYSCTL - mutex_lock(&nf_ct_proto_sysctl_mutex); + mutex_lock(&nf_ct_proto_mutex); if (l3proto->ctl_table != NULL) { err = nf_ct_register_sysctl(&l3proto->ctl_table_header, l3proto->ctl_table_path, l3proto->ctl_table, NULL); } - mutex_unlock(&nf_ct_proto_sysctl_mutex); + mutex_unlock(&nf_ct_proto_mutex); #endif return err; } @@ -178,11 +178,11 @@ static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto) static void nf_ct_l3proto_unregister_sysctl(struct nf_conntrack_l3proto *l3proto) { #ifdef CONFIG_SYSCTL - mutex_lock(&nf_ct_proto_sysctl_mutex); + mutex_lock(&nf_ct_proto_mutex); if (l3proto->ctl_table_header != NULL) nf_ct_unregister_sysctl(&l3proto->ctl_table_header, l3proto->ctl_table, NULL); - mutex_unlock(&nf_ct_proto_sysctl_mutex); + mutex_unlock(&nf_ct_proto_mutex); #endif } @@ -195,13 +195,13 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) goto out; } - write_lock_bh(&nf_conntrack_lock); + mutex_lock(&nf_ct_proto_mutex); if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) { ret = -EBUSY; goto out_unlock; } rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], proto); - write_unlock_bh(&nf_conntrack_lock); + mutex_unlock(&nf_ct_proto_mutex); ret = nf_ct_l3proto_register_sysctl(proto); if (ret < 0) @@ -209,7 +209,7 @@ int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto) return ret; out_unlock: - write_unlock_bh(&nf_conntrack_lock); + mutex_unlock(&nf_ct_proto_mutex); out: return ret; } @@ -219,11 +219,11 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) { BUG_ON(proto->l3proto >= AF_MAX); - write_lock_bh(&nf_conntrack_lock); + mutex_lock(&nf_ct_proto_mutex); BUG_ON(nf_ct_l3protos[proto->l3proto] != proto); rcu_assign_pointer(nf_ct_l3protos[proto->l3proto], &nf_conntrack_l3proto_generic); - write_unlock_bh(&nf_conntrack_lock); + mutex_unlock(&nf_ct_proto_mutex); synchronize_rcu(); nf_ct_l3proto_unregister_sysctl(proto); @@ -238,7 +238,7 @@ static int nf_ct_l4proto_register_sysctl(struct nf_conntrack_l4proto *l4proto) int err = 0; #ifdef CONFIG_SYSCTL - mutex_lock(&nf_ct_proto_sysctl_mutex); + mutex_lock(&nf_ct_proto_mutex); if (l4proto->ctl_table != NULL) { err = nf_ct_register_sysctl(l4proto->ctl_table_header, nf_net_netfilter_sysctl_path, @@ -260,7 +260,7 @@ static int nf_ct_l4proto_register_sysctl(struct nf_conntrack_l4proto *l4proto) } #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ out: - mutex_unlock(&nf_ct_proto_sysctl_mutex); + mutex_unlock(&nf_ct_proto_mutex); #endif /* CONFIG_SYSCTL */ return err; } @@ -268,7 +268,7 @@ out: static void nf_ct_l4proto_unregister_sysctl(struct nf_conntrack_l4proto *l4proto) { #ifdef CONFIG_SYSCTL - mutex_lock(&nf_ct_proto_sysctl_mutex); + mutex_lock(&nf_ct_proto_mutex); if (l4proto->ctl_table_header != NULL && *l4proto->ctl_table_header != NULL) nf_ct_unregister_sysctl(l4proto->ctl_table_header, @@ -279,7 +279,7 @@ static void nf_ct_l4proto_unregister_sysctl(struct nf_conntrack_l4proto *l4proto nf_ct_unregister_sysctl(&l4proto->ctl_compat_table_header, l4proto->ctl_compat_table, NULL); #endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */ - mutex_unlock(&nf_ct_proto_sysctl_mutex); + mutex_unlock(&nf_ct_proto_mutex); #endif /* CONFIG_SYSCTL */ } @@ -297,8 +297,8 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) if (l4proto == &nf_conntrack_l4proto_generic) return nf_ct_l4proto_register_sysctl(l4proto); + mutex_lock(&nf_ct_proto_mutex); retry: - write_lock_bh(&nf_conntrack_lock); if (nf_ct_protos[l4proto->l3proto]) { if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != &nf_conntrack_l4proto_generic) { @@ -310,28 +310,22 @@ retry: struct nf_conntrack_l4proto **proto_array; int i; - write_unlock_bh(&nf_conntrack_lock); - proto_array = (struct nf_conntrack_l4proto **) kmalloc(MAX_NF_CT_PROTO * sizeof(struct nf_conntrack_l4proto *), GFP_KERNEL); if (proto_array == NULL) { ret = -ENOMEM; - goto out; + goto out_unlock; } for (i = 0; i < MAX_NF_CT_PROTO; i++) proto_array[i] = &nf_conntrack_l4proto_generic; - write_lock_bh(&nf_conntrack_lock); - if (nf_ct_protos[l4proto->l3proto]) { + if (nf_ct_protos[l4proto->l3proto]) /* bad timing, but no problem */ - write_unlock_bh(&nf_conntrack_lock); kfree(proto_array); - } else { + else nf_ct_protos[l4proto->l3proto] = proto_array; - write_unlock_bh(&nf_conntrack_lock); - } /* * Just once because array is never freed until unloading @@ -341,7 +335,7 @@ retry: } rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], l4proto); - write_unlock_bh(&nf_conntrack_lock); + mutex_unlock(&nf_ct_proto_mutex); ret = nf_ct_l4proto_register_sysctl(l4proto); if (ret < 0) @@ -349,7 +343,7 @@ retry: return ret; out_unlock: - write_unlock_bh(&nf_conntrack_lock); + mutex_unlock(&nf_ct_proto_mutex); out: return ret; } @@ -364,11 +358,11 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) return; } - write_lock_bh(&nf_conntrack_lock); + mutex_lock(&nf_ct_proto_mutex); BUG_ON(nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != l4proto); rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], &nf_conntrack_l4proto_generic); - write_unlock_bh(&nf_conntrack_lock); + mutex_unlock(&nf_ct_proto_mutex); synchronize_rcu(); nf_ct_l4proto_unregister_sysctl(l4proto); -- 2.30.2