It turns out that net_alive is unnecessary, and the original problem
that led to it being added was simply that the icmp code thought
it was a network device and wound up being unable to handle packets
while there were still packets in the network namespace.

Now that icmp and tcp have been fixed to properly register themselves
this problem is no longer present and we have a stronger guarantee
that packets will not arrive in a network namespace then that provided
by net_alive in netif_receive_skb.  So remove net_alive allowing
packet reception run a little faster.

Additionally document the strong reason why network namespace cleanup
is safe so that if something happens again someone else will have
a chance of figuring it out.

Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Eric W. Biederman 2009-02-22 00:11:09 -08:00 коммит произвёл David S. Miller
Родитель 2f20d2e667
Коммит 17edde5209
3 изменённых файлов: 17 добавлений и 19 удалений

Просмотреть файл

@ -109,11 +109,6 @@ extern struct list_head net_namespace_list;
#ifdef CONFIG_NET_NS
extern void __put_net(struct net *net);
static inline int net_alive(struct net *net)
{
return net && atomic_read(&net->count);
}
static inline struct net *get_net(struct net *net)
{
atomic_inc(&net->count);
@ -145,11 +140,6 @@ int net_eq(const struct net *net1, const struct net *net2)
}
#else
static inline int net_alive(struct net *net)
{
return 1;
}
static inline struct net *get_net(struct net *net)
{
return net;
@ -234,6 +224,23 @@ struct pernet_operations {
void (*exit)(struct net *net);
};
/*
* Use these carefully. If you implement a network device and it
* needs per network namespace operations use device pernet operations,
* otherwise use pernet subsys operations.
*
* This is critically important. Most of the network code cleanup
* runs with the assumption that dev_remove_pack has been called so no
* new packets will arrive during and after the cleanup functions have
* been called. dev_remove_pack is not per namespace so instead the
* guarantee of no more packets arriving in a network namespace is
* provided by ensuring that all network devices and all sockets have
* left the network namespace before the cleanup methods are called.
*
* For the longest time the ipv4 icmp code was registered as a pernet
* device which caused kernel oops, and panics during network
* namespace cleanup. So please don't get this wrong.
*/
extern int register_pernet_subsys(struct pernet_operations *);
extern void unregister_pernet_subsys(struct pernet_operations *);
extern int register_pernet_gen_subsys(int *id, struct pernet_operations *);

Просмотреть файл

@ -2267,12 +2267,6 @@ int netif_receive_skb(struct sk_buff *skb)
rcu_read_lock();
/* Don't receive packets in an exiting network namespace */
if (!net_alive(dev_net(skb->dev))) {
kfree_skb(skb);
goto out;
}
#ifdef CONFIG_NET_CLS_ACT
if (skb->tc_verd & TC_NCLS) {
skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);

Просмотреть файл

@ -157,9 +157,6 @@ static void cleanup_net(struct work_struct *work)
struct pernet_operations *ops;
struct net *net;
/* Be very certain incoming network packets will not find us */
rcu_barrier();
net = container_of(work, struct net, work);
mutex_lock(&net_mutex);