mirror of
https://github.com/lkl/linux.git
synced 2025-12-19 16:13:19 +09:00
net: make net->dev_unreg_count atomic
Having to acquire rtnl from netdev_run_todo() for every dismantled device is not desirable when/if rtnl is under stress. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
ca2d5f1ff0
commit
ede6c39c4f
@@ -63,7 +63,7 @@ struct net {
|
|||||||
*/
|
*/
|
||||||
spinlock_t rules_mod_lock;
|
spinlock_t rules_mod_lock;
|
||||||
|
|
||||||
unsigned int dev_unreg_count;
|
atomic_t dev_unreg_count;
|
||||||
|
|
||||||
unsigned int dev_base_seq; /* protected by rtnl_mutex */
|
unsigned int dev_base_seq; /* protected by rtnl_mutex */
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
|||||||
@@ -9143,7 +9143,7 @@ DECLARE_WAIT_QUEUE_HEAD(netdev_unregistering_wq);
|
|||||||
static void net_set_todo(struct net_device *dev)
|
static void net_set_todo(struct net_device *dev)
|
||||||
{
|
{
|
||||||
list_add_tail(&dev->todo_list, &net_todo_list);
|
list_add_tail(&dev->todo_list, &net_todo_list);
|
||||||
dev_net(dev)->dev_unreg_count++;
|
atomic_inc(&dev_net(dev)->dev_unreg_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static netdev_features_t netdev_sync_upper_features(struct net_device *lower,
|
static netdev_features_t netdev_sync_upper_features(struct net_device *lower,
|
||||||
@@ -9965,11 +9965,8 @@ void netdev_run_todo(void)
|
|||||||
if (dev->needs_free_netdev)
|
if (dev->needs_free_netdev)
|
||||||
free_netdev(dev);
|
free_netdev(dev);
|
||||||
|
|
||||||
/* Report a network device has been unregistered */
|
if (atomic_dec_and_test(&dev_net(dev)->dev_unreg_count))
|
||||||
rtnl_lock();
|
wake_up(&netdev_unregistering_wq);
|
||||||
dev_net(dev)->dev_unreg_count--;
|
|
||||||
__rtnl_unlock();
|
|
||||||
wake_up(&netdev_unregistering_wq);
|
|
||||||
|
|
||||||
/* Free network device */
|
/* Free network device */
|
||||||
kobject_put(&dev->dev.kobj);
|
kobject_put(&dev->dev.kobj);
|
||||||
@@ -10898,7 +10895,7 @@ static void __net_exit rtnl_lock_unregistering(struct list_head *net_list)
|
|||||||
unregistering = false;
|
unregistering = false;
|
||||||
|
|
||||||
list_for_each_entry(net, net_list, exit_list) {
|
list_for_each_entry(net, net_list, exit_list) {
|
||||||
if (net->dev_unreg_count > 0) {
|
if (atomic_read(&net->dev_unreg_count) > 0) {
|
||||||
unregistering = true;
|
unregistering = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -459,7 +459,7 @@ static void rtnl_lock_unregistering_all(void)
|
|||||||
* setup_net() and cleanup_net() are not possible.
|
* setup_net() and cleanup_net() are not possible.
|
||||||
*/
|
*/
|
||||||
for_each_net(net) {
|
for_each_net(net) {
|
||||||
if (net->dev_unreg_count > 0) {
|
if (atomic_read(&net->dev_unreg_count) > 0) {
|
||||||
unregistering = true;
|
unregistering = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user