Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Something went wrong. Try again.
C
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _NET_NETDEV_LOCK_H#define _NET_NETDEV_LOCK_H
#include <linux/lockdep.h>#include <linux/netdevice.h>#include <linux/rtnetlink.h>
static inline bool netdev_trylock(struct net_device *dev){ return mutex_trylock(&dev->lock);}
static inline void netdev_assert_locked(const struct net_device *dev){ lockdep_assert_held(&dev->lock);}
static inline voidnetdev_assert_locked_or_invisible(const struct net_device *dev){ if (dev->reg_state == NETREG_REGISTERED || dev->reg_state == NETREG_UNREGISTERING) netdev_assert_locked(dev);}
static inline bool netdev_need_ops_lock(const struct net_device *dev){ bool ret = dev->request_ops_lock || !!dev->queue_mgmt_ops;
#if IS_ENABLED(CONFIG_NET_SHAPER) ret |= !!dev->netdev_ops->net_shaper_ops;#endif
return ret;}
static inline void netdev_lock_ops(struct net_device *dev){ if (netdev_need_ops_lock(dev)) netdev_lock(dev);}
static inline void netdev_unlock_ops(struct net_device *dev){ if (netdev_need_ops_lock(dev)) netdev_unlock(dev);}
static inline void netdev_lock_ops_to_full(struct net_device *dev){ if (netdev_need_ops_lock(dev)) netdev_assert_locked(dev); else netdev_lock(dev);}
static inline void netdev_unlock_full_to_ops(struct net_device *dev){ if (netdev_need_ops_lock(dev)) netdev_assert_locked(dev); else netdev_unlock(dev);}
static inline void netdev_assert_locked_ops_compat(const struct net_device *dev){ if (netdev_need_ops_lock(dev)) lockdep_assert_held(&dev->lock); else ASSERT_RTNL();}
static inline voidnetdev_assert_locked_ops_compat_or_invisible(const struct net_device *dev){ if (dev->reg_state == NETREG_REGISTERED || dev->reg_state == NETREG_UNREGISTERING) netdev_assert_locked_ops_compat(dev);}
static inline void netdev_assert_locked_ops(const struct net_device *dev){ if (netdev_need_ops_lock(dev)) netdev_assert_locked(dev);}
static inline void netdev_lock_ops_compat(struct net_device *dev){ if (netdev_need_ops_lock(dev)) netdev_lock(dev); else rtnl_lock();}
static inline void netdev_unlock_ops_compat(struct net_device *dev){ if (netdev_need_ops_lock(dev)) netdev_unlock(dev); else rtnl_unlock();}
/* Matching "ops protected" category from netdevice.h */static inline int netdev_is_locked_ops_compat(const struct net_device *dev){ if (netdev_need_ops_lock(dev)) return lockdep_is_held(&dev->lock); return lockdep_rtnl_is_held();}
static inline int netdev_lock_cmp_fn(const struct lockdep_map *a, const struct lockdep_map *b){ if (a == b) return 0;
/* Allow locking multiple devices only under rtnl_lock, * the exact order doesn't matter. * Note that upper devices don't lock their ops, so nesting * mostly happens in batched device removal for now. */ return lockdep_rtnl_is_held() ? -1 : 1;}
#define netdev_lockdep_set_classes(dev) \{ \ static struct lock_class_key qdisc_tx_busylock_key; \ static struct lock_class_key qdisc_xmit_lock_key; \ static struct lock_class_key dev_addr_list_lock_key; \ static struct lock_class_key dev_instance_lock_key; \ unsigned int i; \ \ (dev)->qdisc_tx_busylock = &qdisc_tx_busylock_key; \ lockdep_set_class(&(dev)->addr_list_lock, \ &dev_addr_list_lock_key); \ lockdep_set_class(&(dev)->lock, \ &dev_instance_lock_key); \ lock_set_cmp_fn(&dev->lock, netdev_lock_cmp_fn, NULL); \ for (i = 0; i < (dev)->num_tx_queues; i++) \ lockdep_set_class(&(dev)->_tx[i]._xmit_lock, \ &qdisc_xmit_lock_key); \}
#define netdev_lock_dereference(p, dev) \ rcu_dereference_protected(p, lockdep_is_held(&(dev)->lock))
#define netdev_ops_lock_dereference(p, dev) \ rcu_dereference_protected(p, netdev_is_locked_ops_compat(dev))
int netdev_debug_event(struct notifier_block *nb, unsigned long event, void *ptr);
#endif