return false;
}
+/**
+ * dev_deactivate_many - deactivate transmissions on several devices
+ * @head: list of devices to deactivate
+ *
+ * This function returns only when all outstanding transmissions
+ * have completed, unless all devices are in dismantle phase.
+ */
void dev_deactivate_many(struct list_head *head)
{
struct net_device *dev;
+ bool sync_needed = false;
list_for_each_entry(dev, head, unreg_list) {
netdev_for_each_tx_queue(dev, dev_deactivate_queue,
&noop_qdisc);
dev_watchdog_down(dev);
+ sync_needed |= !dev->dismantle;
}
- /* Wait for outstanding qdisc-less dev_queue_xmit calls. */
- synchronize_rcu();
+ /* Wait for outstanding qdisc-less dev_queue_xmit calls.
+ * This is avoided if all devices are in dismantle phase :
+ * Caller will call synchronize_net() for us
+ */
+ if (sync_needed)
+ synchronize_net();
/* Wait for outstanding qdisc_run calls. */
list_for_each_entry(dev, head, unreg_list)