Subject: Re: [PATCH/RFC] make unregister_netdev() delete more than 4 interfaces per second

From: Eric Dumazet <[email-masked]>
Date: Sun, 18 Oct 2009 06:26:22 +0200

Benjamin LaHaise a écrit :
> Hi folks,
> 
> Below is a patch that changes the interaction between netdev_wait_allrefs() 
> and dev_put() to replace an msleep(250) with a wait_event() on the final 
> dev_put().  This change reduces the time spent sleeping during an 
> unregister_netdev(), causing the system to go from <1% CPU time to something 
> more CPU bound (50+% in a test vm).  This increases the speed of a bulk 
> unregister_netdev() from 4 interfaces per second to over 500 per second on 
> my test system.  The requirement comes from handling thousands of L2TP 
> sessions where a tunnel flap results in all interfaces being torn down at 
> one time.
> 
> Note that there is still more work to be done in this area.
> 
> 		-ben
>  

> +DECLARE_WAIT_QUEUE_HEAD(netdev_refcnt_wait);
> +
> +void dev_put(struct net_device *dev)
> +{
> +        if (atomic_dec_and_test(&dev->refcnt))
> +		wake_up(&netdev_refcnt_wait);
> +}
> +EXPORT_SYMBOL(dev_put);
> +

Unfortunatly this slow down fast path by an order of magnitude.

atomic_dec() is pretty cheap (and eventually could use a per_cpu thing,
now we have a new and sexy per_cpu allocator), but atomic_dec_and_test()
is not that cheap and more important forbids a per_cpu conversion.