From: Denis V. Lunev Date: Wed, 16 Apr 2008 08:58:04 +0000 (-0700) Subject: [NETNS]: Make netns refconting debug like a socket one. X-Git-Tag: v2.6.26-rc1~1138^2~22 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5d1e4468a7705db7c1415a65fd16f07113afc1b2;p=linux-2.6 [NETNS]: Make netns refconting debug like a socket one. Make release_net/hold_net noop for performance-hungry people. This is a debug staff and should be used in the debug mode only. Add check for net != NULL in hold/release calls. This will be required later on. [ Added minor simplifications suggested by Brian Haley. -DaveM ] Signed-off-by: Denis V. Lunev Signed-off-by: David S. Miller --- diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index f880b0f9f1..aa540e6be5 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -26,9 +26,11 @@ struct net { atomic_t count; /* To decided when the network * namespace should be freed. */ +#ifdef NETNS_REFCNT_DEBUG atomic_t use_count; /* To track references we * destroy on demand */ +#endif struct list_head list; /* list of network namespaces */ struct work_struct work; /* work struct for freeing */ @@ -117,17 +119,6 @@ static inline void put_net(struct net *net) __put_net(net); } -static inline struct net *hold_net(struct net *net) -{ - atomic_inc(&net->use_count); - return net; -} - -static inline void release_net(struct net *net) -{ - atomic_dec(&net->use_count); -} - static inline int net_eq(const struct net *net1, const struct net *net2) { @@ -143,27 +134,44 @@ static inline void put_net(struct net *net) { } +static inline struct net *maybe_get_net(struct net *net) +{ + return net; +} + +static inline +int net_eq(const struct net *net1, const struct net *net2) +{ + return 1; +} +#endif + + +#ifdef NETNS_REFCNT_DEBUG static inline struct net *hold_net(struct net *net) { + if (net) + atomic_inc(&net->use_count); return net; } static inline void release_net(struct net *net) { + if (net) + atomic_dec(&net->use_count); } - -static inline struct net *maybe_get_net(struct net *net) +#else +static inline struct net *hold_net(struct net *net) { return net; } -static inline -int net_eq(const struct net *net1, const struct net *net2) +static inline void release_net(struct net *net) { - return 1; } #endif + #define for_each_net(VAR) \ list_for_each_entry(VAR, &net_namespace_list, list) diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index 763674e1e5..72b4c184dd 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c @@ -35,7 +35,9 @@ static __net_init int setup_net(struct net *net) struct net_generic *ng; atomic_set(&net->count, 1); +#ifdef NETNS_REFCNT_DEBUG atomic_set(&net->use_count, 0); +#endif error = -ENOMEM; ng = kzalloc(sizeof(struct net_generic) + @@ -86,11 +88,13 @@ static void net_free(struct net *net) if (!net) return; +#ifdef NETNS_REFCNT_DEBUG if (unlikely(atomic_read(&net->use_count) != 0)) { printk(KERN_EMERG "network namespace not free! Usage: %d\n", atomic_read(&net->use_count)); return; } +#endif kmem_cache_free(net_cachep, net); }