From 5d1e4468a7705db7c1415a65fd16f07113afc1b2 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Wed, 16 Apr 2008 01:58:04 -0700 Subject: [PATCH] [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 --- include/net/net_namespace.h | 48 +++++++++++++++++++++---------------- net/core/net_namespace.c | 4 ++++ 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index f880b0f9f107..aa540e6be502 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,15 +134,6 @@ static inline void put_net(struct net *net) { } -static inline struct net *hold_net(struct net *net) -{ - return net; -} - -static inline void release_net(struct net *net) -{ -} - static inline struct net *maybe_get_net(struct net *net) { return net; @@ -164,6 +146,32 @@ int net_eq(const struct net *net1, const struct net *net2) } #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); +} +#else +static inline struct net *hold_net(struct net *net) +{ + return net; +} + +static inline void release_net(struct net *net) +{ +} +#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 763674e1e593..72b4c184dd84 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); }