forked from mirrors/linux
		
	net: skip genenerating uevents for network namespaces that are exiting
No one can see these events, because a network namespace can not be
destroyed, if it has sockets.
Unlike other devices, uevent-s for network devices are generated
only inside their network namespaces. They are filtered in
kobj_bcast_filter()
My experiments shows that net namespaces are destroyed more 30% faster
with this optimization.
Here is a perf output for destroying network namespaces without this
patch.
-   94.76%     0.02%  kworker/u48:1  [kernel.kallsyms]     [k] cleanup_net
   - 94.74% cleanup_net
      - 94.64% ops_exit_list.isra.4
         - 41.61% default_device_exit_batch
            - 41.47% unregister_netdevice_many
               - rollback_registered_many
                  - 40.36% netdev_unregister_kobject
                     - 14.55% device_del
                        + 13.71% kobject_uevent
                     - 13.04% netdev_queue_update_kobjects
                        + 12.96% kobject_put
                     - 12.72% net_rx_queue_update_kobjects
                          kobject_put
                        - kobject_release
                           + 12.69% kobject_uevent
                  + 0.80% call_netdevice_notifiers_info
         + 19.57% nfsd_exit_net
         + 11.15% tcp_net_metrics_exit
         + 8.25% rpcsec_gss_exit_net
It's very critical to optimize the exit path for network namespaces,
because they are destroyed under net_mutex and many namespaces can be
destroyed for one iteration.
v2: use dev_set_uevent_suppress()
Cc: Cong Wang <xiyou.wangcong@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Andrei Vagin <avagin@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									110447f826
								
							
						
					
					
						commit
						002d8a1a6c
					
				
					 1 changed files with 11 additions and 3 deletions
				
			
		|  | @ -950,10 +950,13 @@ net_rx_queue_update_kobjects(struct net_device *dev, int old_num, int new_num) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	while (--i >= new_num) { | 	while (--i >= new_num) { | ||||||
|  | 		struct kobject *kobj = &dev->_rx[i].kobj; | ||||||
|  | 
 | ||||||
|  | 		if (!list_empty(&dev_net(dev)->exit_list)) | ||||||
|  | 			kobj->uevent_suppress = 1; | ||||||
| 		if (dev->sysfs_rx_queue_group) | 		if (dev->sysfs_rx_queue_group) | ||||||
| 			sysfs_remove_group(&dev->_rx[i].kobj, | 			sysfs_remove_group(kobj, dev->sysfs_rx_queue_group); | ||||||
| 					   dev->sysfs_rx_queue_group); | 		kobject_put(kobj); | ||||||
| 		kobject_put(&dev->_rx[i].kobj); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return error; | 	return error; | ||||||
|  | @ -1340,6 +1343,8 @@ netdev_queue_update_kobjects(struct net_device *dev, int old_num, int new_num) | ||||||
| 	while (--i >= new_num) { | 	while (--i >= new_num) { | ||||||
| 		struct netdev_queue *queue = dev->_tx + i; | 		struct netdev_queue *queue = dev->_tx + i; | ||||||
| 
 | 
 | ||||||
|  | 		if (!list_empty(&dev_net(dev)->exit_list)) | ||||||
|  | 			queue->kobj.uevent_suppress = 1; | ||||||
| #ifdef CONFIG_BQL | #ifdef CONFIG_BQL | ||||||
| 		sysfs_remove_group(&queue->kobj, &dql_group); | 		sysfs_remove_group(&queue->kobj, &dql_group); | ||||||
| #endif | #endif | ||||||
|  | @ -1525,6 +1530,9 @@ void netdev_unregister_kobject(struct net_device *ndev) | ||||||
| { | { | ||||||
| 	struct device *dev = &(ndev->dev); | 	struct device *dev = &(ndev->dev); | ||||||
| 
 | 
 | ||||||
|  | 	if (!list_empty(&dev_net(ndev)->exit_list)) | ||||||
|  | 		dev_set_uevent_suppress(dev, 1); | ||||||
|  | 
 | ||||||
| 	kobject_get(&dev->kobj); | 	kobject_get(&dev->kobj); | ||||||
| 
 | 
 | ||||||
| 	remove_queue_kobjects(ndev); | 	remove_queue_kobjects(ndev); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Andrey Vagin
						Andrey Vagin