netdev_lock.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. #ifndef _NET_NETDEV_LOCK_H
  3. #define _NET_NETDEV_LOCK_H
  4. #include <linux/lockdep.h>
  5. #include <linux/netdevice.h>
  6. #include <linux/rtnetlink.h>
  7. static inline bool netdev_trylock(struct net_device *dev)
  8. {
  9. return mutex_trylock(&dev->lock);
  10. }
  11. static inline void netdev_assert_locked(const struct net_device *dev)
  12. {
  13. lockdep_assert_held(&dev->lock);
  14. }
  15. static inline void
  16. netdev_assert_locked_or_invisible(const struct net_device *dev)
  17. {
  18. if (dev->reg_state == NETREG_REGISTERED ||
  19. dev->reg_state == NETREG_UNREGISTERING)
  20. netdev_assert_locked(dev);
  21. }
  22. static inline bool netdev_need_ops_lock(const struct net_device *dev)
  23. {
  24. bool ret = dev->request_ops_lock || !!dev->queue_mgmt_ops;
  25. #if IS_ENABLED(CONFIG_NET_SHAPER)
  26. ret |= !!dev->netdev_ops->net_shaper_ops;
  27. #endif
  28. return ret;
  29. }
  30. static inline void netdev_lock_ops(struct net_device *dev)
  31. {
  32. if (netdev_need_ops_lock(dev))
  33. netdev_lock(dev);
  34. }
  35. static inline void netdev_unlock_ops(struct net_device *dev)
  36. {
  37. if (netdev_need_ops_lock(dev))
  38. netdev_unlock(dev);
  39. }
  40. static inline void netdev_lock_ops_to_full(struct net_device *dev)
  41. {
  42. if (netdev_need_ops_lock(dev))
  43. netdev_assert_locked(dev);
  44. else
  45. netdev_lock(dev);
  46. }
  47. static inline void netdev_unlock_full_to_ops(struct net_device *dev)
  48. {
  49. if (netdev_need_ops_lock(dev))
  50. netdev_assert_locked(dev);
  51. else
  52. netdev_unlock(dev);
  53. }
  54. static inline void netdev_ops_assert_locked(const struct net_device *dev)
  55. {
  56. if (netdev_need_ops_lock(dev))
  57. lockdep_assert_held(&dev->lock);
  58. else
  59. ASSERT_RTNL();
  60. }
  61. static inline void
  62. netdev_ops_assert_locked_or_invisible(const struct net_device *dev)
  63. {
  64. if (dev->reg_state == NETREG_REGISTERED ||
  65. dev->reg_state == NETREG_UNREGISTERING)
  66. netdev_ops_assert_locked(dev);
  67. }
  68. static inline void netdev_lock_ops_compat(struct net_device *dev)
  69. {
  70. if (netdev_need_ops_lock(dev))
  71. netdev_lock(dev);
  72. else
  73. rtnl_lock();
  74. }
  75. static inline void netdev_unlock_ops_compat(struct net_device *dev)
  76. {
  77. if (netdev_need_ops_lock(dev))
  78. netdev_unlock(dev);
  79. else
  80. rtnl_unlock();
  81. }
  82. static inline int netdev_lock_cmp_fn(const struct lockdep_map *a,
  83. const struct lockdep_map *b)
  84. {
  85. if (a == b)
  86. return 0;
  87. /* Allow locking multiple devices only under rtnl_lock,
  88. * the exact order doesn't matter.
  89. * Note that upper devices don't lock their ops, so nesting
  90. * mostly happens in batched device removal for now.
  91. */
  92. return lockdep_rtnl_is_held() ? -1 : 1;
  93. }
  94. #define netdev_lockdep_set_classes(dev) \
  95. { \
  96. static struct lock_class_key qdisc_tx_busylock_key; \
  97. static struct lock_class_key qdisc_xmit_lock_key; \
  98. static struct lock_class_key dev_addr_list_lock_key; \
  99. static struct lock_class_key dev_instance_lock_key; \
  100. unsigned int i; \
  101. \
  102. (dev)->qdisc_tx_busylock = &qdisc_tx_busylock_key; \
  103. lockdep_set_class(&(dev)->addr_list_lock, \
  104. &dev_addr_list_lock_key); \
  105. lockdep_set_class(&(dev)->lock, \
  106. &dev_instance_lock_key); \
  107. lock_set_cmp_fn(&dev->lock, netdev_lock_cmp_fn, NULL); \
  108. for (i = 0; i < (dev)->num_tx_queues; i++) \
  109. lockdep_set_class(&(dev)->_tx[i]._xmit_lock, \
  110. &qdisc_xmit_lock_key); \
  111. }
  112. #define netdev_lock_dereference(p, dev) \
  113. rcu_dereference_protected(p, lockdep_is_held(&(dev)->lock))
  114. int netdev_debug_event(struct notifier_block *nb, unsigned long event,
  115. void *ptr);
  116. #endif