diff options
| -rw-r--r-- | net/core/dev.c | 6 |
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 | } |
| 3338 | EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); | 3344 | EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister); |
