From: Patrick McHardy Date: Wed, 14 Mar 2007 23:39:07 +0000 (-0700) Subject: [NETFILTER]: nf_conntrack: simplify l4 protocol array allocation X-Git-Tag: v2.6.22-rc1~1128^2~301 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c6a1e615d1ba942b9e783079d53f741e4a8e1c89;p=linux-2.6 [NETFILTER]: nf_conntrack: simplify l4 protocol array allocation The retrying after an allocation failure is not necessary anymore since we're holding the mutex the entire time, for the same reason the double allocation race can't happen anymore. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index 509725412d..e4aad2087f 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -281,47 +281,34 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) return -EBUSY; mutex_lock(&nf_ct_proto_mutex); -retry: - if (nf_ct_protos[l4proto->l3proto]) { - if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] - != &nf_conntrack_l4proto_generic) { - ret = -EBUSY; - goto out_unlock; - } - } else { + if (!nf_ct_protos[l4proto->l3proto]) { /* l3proto may be loaded latter. */ struct nf_conntrack_l4proto **proto_array; int i; - proto_array = (struct nf_conntrack_l4proto **) - kmalloc(MAX_NF_CT_PROTO * - sizeof(struct nf_conntrack_l4proto *), - GFP_KERNEL); + proto_array = kmalloc(MAX_NF_CT_PROTO * + sizeof(struct nf_conntrack_l4proto *), + GFP_KERNEL); if (proto_array == NULL) { ret = -ENOMEM; goto out_unlock; } + for (i = 0; i < MAX_NF_CT_PROTO; i++) proto_array[i] = &nf_conntrack_l4proto_generic; - - if (nf_ct_protos[l4proto->l3proto]) - /* bad timing, but no problem */ - kfree(proto_array); - else - nf_ct_protos[l4proto->l3proto] = proto_array; - - /* - * Just once because array is never freed until unloading - * nf_conntrack.ko - */ - goto retry; + nf_ct_protos[l4proto->l3proto] = proto_array; + } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != + &nf_conntrack_l4proto_generic) { + ret = -EBUSY; + goto out_unlock; } ret = nf_ct_l4proto_register_sysctl(l4proto); if (ret < 0) goto out_unlock; - rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], l4proto); + rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto], + l4proto); out_unlock: mutex_unlock(&nf_ct_proto_mutex);