aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/core/dev.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 6591440cc03d..13e6447f0398 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3313,6 +3313,7 @@ int netdev_rx_handler_register(struct net_device *dev,
3313 if (dev->rx_handler) 3313 if (dev->rx_handler)
3314 return -EBUSY; 3314 return -EBUSY;
3315 3315
3316 /* Note: rx_handler_data must be set before rx_handler */
3316 rcu_assign_pointer(dev->rx_handler_data, rx_handler_data); 3317 rcu_assign_pointer(dev->rx_handler_data, rx_handler_data);
3317 rcu_assign_pointer(dev->rx_handler, rx_handler); 3318 rcu_assign_pointer(dev->rx_handler, rx_handler);
3318 3319
@@ -3333,6 +3334,11 @@ void netdev_rx_handler_unregister(struct net_device *dev)
3333 3334
3334 ASSERT_RTNL(); 3335 ASSERT_RTNL();
3335 RCU_INIT_POINTER(dev->rx_handler, NULL); 3336 RCU_INIT_POINTER(dev->rx_handler, NULL);
3337 /* a reader seeing a non NULL rx_handler in a rcu_read_lock()
3338 * section has a guarantee to see a non NULL rx_handler_data
3339 * as well.
3340 */
3341 synchronize_net();
3336 RCU_INIT_POINTER(dev->rx_handler_data, NULL); 3342 RCU_INIT_POINTER(dev->rx_handler_data, NULL);
3337} 3343}
3338EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); 3344EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);