diff options
-rw-r--r-- | include/net/net_namespace.h | 40 | ||||
-rw-r--r-- | net/core/net_namespace.c | 4 |
2 files changed, 28 insertions, 16 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 { | |||
26 | atomic_t count; /* To decided when the network | 26 | atomic_t count; /* To decided when the network |
27 | * namespace should be freed. | 27 | * namespace should be freed. |
28 | */ | 28 | */ |
29 | #ifdef NETNS_REFCNT_DEBUG | ||
29 | atomic_t use_count; /* To track references we | 30 | atomic_t use_count; /* To track references we |
30 | * destroy on demand | 31 | * destroy on demand |
31 | */ | 32 | */ |
33 | #endif | ||
32 | struct list_head list; /* list of network namespaces */ | 34 | struct list_head list; /* list of network namespaces */ |
33 | struct work_struct work; /* work struct for freeing */ | 35 | struct work_struct work; /* work struct for freeing */ |
34 | 36 | ||
@@ -117,17 +119,6 @@ static inline void put_net(struct net *net) | |||
117 | __put_net(net); | 119 | __put_net(net); |
118 | } | 120 | } |
119 | 121 | ||
120 | static inline struct net *hold_net(struct net *net) | ||
121 | { | ||
122 | atomic_inc(&net->use_count); | ||
123 | return net; | ||
124 | } | ||
125 | |||
126 | static inline void release_net(struct net *net) | ||
127 | { | ||
128 | atomic_dec(&net->use_count); | ||
129 | } | ||
130 | |||
131 | static inline | 122 | static inline |
132 | int net_eq(const struct net *net1, const struct net *net2) | 123 | int net_eq(const struct net *net1, const struct net *net2) |
133 | { | 124 | { |
@@ -143,27 +134,44 @@ static inline void put_net(struct net *net) | |||
143 | { | 134 | { |
144 | } | 135 | } |
145 | 136 | ||
137 | static inline struct net *maybe_get_net(struct net *net) | ||
138 | { | ||
139 | return net; | ||
140 | } | ||
141 | |||
142 | static inline | ||
143 | int net_eq(const struct net *net1, const struct net *net2) | ||
144 | { | ||
145 | return 1; | ||
146 | } | ||
147 | #endif | ||
148 | |||
149 | |||
150 | #ifdef NETNS_REFCNT_DEBUG | ||
146 | static inline struct net *hold_net(struct net *net) | 151 | static inline struct net *hold_net(struct net *net) |
147 | { | 152 | { |
153 | if (net) | ||
154 | atomic_inc(&net->use_count); | ||
148 | return net; | 155 | return net; |
149 | } | 156 | } |
150 | 157 | ||
151 | static inline void release_net(struct net *net) | 158 | static inline void release_net(struct net *net) |
152 | { | 159 | { |
160 | if (net) | ||
161 | atomic_dec(&net->use_count); | ||
153 | } | 162 | } |
154 | 163 | #else | |
155 | static inline struct net *maybe_get_net(struct net *net) | 164 | static inline struct net *hold_net(struct net *net) |
156 | { | 165 | { |
157 | return net; | 166 | return net; |
158 | } | 167 | } |
159 | 168 | ||
160 | static inline | 169 | static inline void release_net(struct net *net) |
161 | int net_eq(const struct net *net1, const struct net *net2) | ||
162 | { | 170 | { |
163 | return 1; | ||
164 | } | 171 | } |
165 | #endif | 172 | #endif |
166 | 173 | ||
174 | |||
167 | #define for_each_net(VAR) \ | 175 | #define for_each_net(VAR) \ |
168 | list_for_each_entry(VAR, &net_namespace_list, list) | 176 | list_for_each_entry(VAR, &net_namespace_list, list) |
169 | 177 | ||
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) | |||
35 | struct net_generic *ng; | 35 | struct net_generic *ng; |
36 | 36 | ||
37 | atomic_set(&net->count, 1); | 37 | atomic_set(&net->count, 1); |
38 | #ifdef NETNS_REFCNT_DEBUG | ||
38 | atomic_set(&net->use_count, 0); | 39 | atomic_set(&net->use_count, 0); |
40 | #endif | ||
39 | 41 | ||
40 | error = -ENOMEM; | 42 | error = -ENOMEM; |
41 | ng = kzalloc(sizeof(struct net_generic) + | 43 | ng = kzalloc(sizeof(struct net_generic) + |
@@ -86,11 +88,13 @@ static void net_free(struct net *net) | |||
86 | if (!net) | 88 | if (!net) |
87 | return; | 89 | return; |
88 | 90 | ||
91 | #ifdef NETNS_REFCNT_DEBUG | ||
89 | if (unlikely(atomic_read(&net->use_count) != 0)) { | 92 | if (unlikely(atomic_read(&net->use_count) != 0)) { |
90 | printk(KERN_EMERG "network namespace not free! Usage: %d\n", | 93 | printk(KERN_EMERG "network namespace not free! Usage: %d\n", |
91 | atomic_read(&net->use_count)); | 94 | atomic_read(&net->use_count)); |
92 | return; | 95 | return; |
93 | } | 96 | } |
97 | #endif | ||
94 | 98 | ||
95 | kmem_cache_free(net_cachep, net); | 99 | kmem_cache_free(net_cachep, net); |
96 | } | 100 | } |