forked from mirrors/linux
		
	net: partially revert dynamic lockdep key changes
This patch reverts the folowing commits: commit064ff66e2b"bonding: add missing netdev_update_lockdep_key()" commit53d374979e"net: avoid updating qdisc_xmit_lock_key in netdev_update_lockdep_key()" commit1f26c0d3d2"net: fix kernel-doc warning in <linux/netdevice.h>" commitab92d68fc2"net: core: add generic lockdep keys" but keeps the addr_list_lock_key because we still lock addr_list_lock nestedly on stack devices, unlikely xmit_lock this is safe because we don't take addr_list_lock on any fast path. Reported-and-tested-by: syzbot+aaa6fa4949cc5d9b7b25@syzkaller.appspotmail.com Cc: Dmitry Vyukov <dvyukov@google.com> Cc: Taehee Yoo <ap420073@gmail.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Acked-by: Taehee Yoo <ap420073@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									ea84c84290
								
							
						
					
					
						commit
						1a33e10e4a
					
				
					 22 changed files with 294 additions and 33 deletions
				
			
		| 
						 | 
				
			
			@ -4898,6 +4898,7 @@ static int bond_init(struct net_device *bond_dev)
 | 
			
		|||
	spin_lock_init(&bond->stats_lock);
 | 
			
		||||
	lockdep_register_key(&bond->stats_lock_key);
 | 
			
		||||
	lockdep_set_class(&bond->stats_lock, &bond->stats_lock_key);
 | 
			
		||||
	netdev_lockdep_set_classes(bond_dev);
 | 
			
		||||
 | 
			
		||||
	list_add_tail(&bond->bond_list, &bn->dev_list);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -299,6 +299,20 @@ static void nfp_repr_clean(struct nfp_repr *repr)
 | 
			
		|||
	nfp_port_free(repr->port);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct lock_class_key nfp_repr_netdev_xmit_lock_key;
 | 
			
		||||
 | 
			
		||||
static void nfp_repr_set_lockdep_class_one(struct net_device *dev,
 | 
			
		||||
					   struct netdev_queue *txq,
 | 
			
		||||
					   void *_unused)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_set_class(&txq->_xmit_lock, &nfp_repr_netdev_xmit_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void nfp_repr_set_lockdep_class(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	netdev_for_each_tx_queue(dev, nfp_repr_set_lockdep_class_one, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
 | 
			
		||||
		  u32 cmsg_port_id, struct nfp_port *port,
 | 
			
		||||
		  struct net_device *pf_netdev)
 | 
			
		||||
| 
						 | 
				
			
			@ -308,6 +322,8 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
 | 
			
		|||
	u32 repr_cap = nn->tlv_caps.repr_cap;
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	nfp_repr_set_lockdep_class(netdev);
 | 
			
		||||
 | 
			
		||||
	repr->port = port;
 | 
			
		||||
	repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL);
 | 
			
		||||
	if (!repr->dst)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,6 +107,25 @@ struct bpqdev {
 | 
			
		|||
 | 
			
		||||
static LIST_HEAD(bpq_devices);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * bpqether network devices are paired with ethernet devices below them, so
 | 
			
		||||
 * form a special "super class" of normal ethernet devices; split their locks
 | 
			
		||||
 * off into a separate class since they always nest.
 | 
			
		||||
 */
 | 
			
		||||
static struct lock_class_key bpq_netdev_xmit_lock_key;
 | 
			
		||||
 | 
			
		||||
static void bpq_set_lockdep_class_one(struct net_device *dev,
 | 
			
		||||
				      struct netdev_queue *txq,
 | 
			
		||||
				      void *_unused)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_set_class(&txq->_xmit_lock, &bpq_netdev_xmit_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void bpq_set_lockdep_class(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	netdev_for_each_tx_queue(dev, bpq_set_lockdep_class_one, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -477,6 +496,7 @@ static int bpq_new_device(struct net_device *edev)
 | 
			
		|||
	err = register_netdevice(ndev);
 | 
			
		||||
	if (err)
 | 
			
		||||
		goto error;
 | 
			
		||||
	bpq_set_lockdep_class(ndev);
 | 
			
		||||
 | 
			
		||||
	/* List protected by RTNL */
 | 
			
		||||
	list_add_rcu(&bpq->bpq_list, &bpq_devices);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2456,6 +2456,8 @@ static int netvsc_probe(struct hv_device *dev,
 | 
			
		|||
		NETIF_F_HW_VLAN_CTAG_RX;
 | 
			
		||||
	net->vlan_features = net->features;
 | 
			
		||||
 | 
			
		||||
	netdev_lockdep_set_classes(net);
 | 
			
		||||
 | 
			
		||||
	/* MTU range: 68 - 1500 or 65521 */
 | 
			
		||||
	net->min_mtu = NETVSC_MTU_MIN;
 | 
			
		||||
	if (nvdev->nvsp_version >= NVSP_PROTOCOL_VERSION_2)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,6 +131,8 @@ static int ipvlan_init(struct net_device *dev)
 | 
			
		|||
	dev->gso_max_segs = phy_dev->gso_max_segs;
 | 
			
		||||
	dev->hard_header_len = phy_dev->hard_header_len;
 | 
			
		||||
 | 
			
		||||
	netdev_lockdep_set_classes(dev);
 | 
			
		||||
 | 
			
		||||
	ipvlan->pcpu_stats = netdev_alloc_pcpu_stats(struct ipvl_pcpu_stats);
 | 
			
		||||
	if (!ipvlan->pcpu_stats)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4047,6 +4047,8 @@ static int macsec_newlink(struct net *net, struct net_device *dev,
 | 
			
		|||
	if (err < 0)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
	netdev_lockdep_set_classes(dev);
 | 
			
		||||
 | 
			
		||||
	err = netdev_upper_dev_link(real_dev, dev, extack);
 | 
			
		||||
	if (err < 0)
 | 
			
		||||
		goto unregister;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -890,6 +890,8 @@ static int macvlan_init(struct net_device *dev)
 | 
			
		|||
	dev->gso_max_segs	= lowerdev->gso_max_segs;
 | 
			
		||||
	dev->hard_header_len	= lowerdev->hard_header_len;
 | 
			
		||||
 | 
			
		||||
	netdev_lockdep_set_classes(dev);
 | 
			
		||||
 | 
			
		||||
	vlan->pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
 | 
			
		||||
	if (!vlan->pcpu_stats)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1410,6 +1410,8 @@ static int ppp_dev_init(struct net_device *dev)
 | 
			
		|||
{
 | 
			
		||||
	struct ppp *ppp;
 | 
			
		||||
 | 
			
		||||
	netdev_lockdep_set_classes(dev);
 | 
			
		||||
 | 
			
		||||
	ppp = netdev_priv(dev);
 | 
			
		||||
	/* Let the netdevice take a reference on the ppp file. This ensures
 | 
			
		||||
	 * that ppp_destroy_interface() won't run before the device gets
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1647,6 +1647,7 @@ static int team_init(struct net_device *dev)
 | 
			
		|||
 | 
			
		||||
	lockdep_register_key(&team->team_lock_key);
 | 
			
		||||
	__mutex_init(&team->lock, "team->team_lock_key", &team->team_lock_key);
 | 
			
		||||
	netdev_lockdep_set_classes(dev);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -867,6 +867,7 @@ static int vrf_dev_init(struct net_device *dev)
 | 
			
		|||
 | 
			
		||||
	/* similarly, oper state is irrelevant; set to up to avoid confusion */
 | 
			
		||||
	dev->operstate = IF_OPER_UP;
 | 
			
		||||
	netdev_lockdep_set_classes(dev);
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
out_rth:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3041,6 +3041,27 @@ static void prism2_clear_set_tim_queue(local_info_t *local)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * HostAP uses two layers of net devices, where the inner
 | 
			
		||||
 * layer gets called all the time from the outer layer.
 | 
			
		||||
 * This is a natural nesting, which needs a split lock type.
 | 
			
		||||
 */
 | 
			
		||||
static struct lock_class_key hostap_netdev_xmit_lock_key;
 | 
			
		||||
 | 
			
		||||
static void prism2_set_lockdep_class_one(struct net_device *dev,
 | 
			
		||||
					 struct netdev_queue *txq,
 | 
			
		||||
					 void *_unused)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_set_class(&txq->_xmit_lock,
 | 
			
		||||
			  &hostap_netdev_xmit_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void prism2_set_lockdep_class(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	netdev_for_each_tx_queue(dev, prism2_set_lockdep_class_one, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct net_device *
 | 
			
		||||
prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
 | 
			
		||||
		       struct device *sdev)
 | 
			
		||||
| 
						 | 
				
			
			@ -3199,6 +3220,7 @@ while (0)
 | 
			
		|||
	if (ret >= 0)
 | 
			
		||||
		ret = register_netdevice(dev);
 | 
			
		||||
 | 
			
		||||
	prism2_set_lockdep_class(dev);
 | 
			
		||||
	rtnl_unlock();
 | 
			
		||||
	if (ret < 0) {
 | 
			
		||||
		printk(KERN_WARNING "%s: register netdevice failed!\n",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1805,13 +1805,11 @@ enum netdev_priv_flags {
 | 
			
		|||
 *	@phydev:	Physical device may attach itself
 | 
			
		||||
 *			for hardware timestamping
 | 
			
		||||
 *	@sfp_bus:	attached &struct sfp_bus structure.
 | 
			
		||||
 *	@qdisc_tx_busylock_key: lockdep class annotating Qdisc->busylock
 | 
			
		||||
 *				spinlock
 | 
			
		||||
 *	@qdisc_running_key:	lockdep class annotating Qdisc->running seqcount
 | 
			
		||||
 *	@qdisc_xmit_lock_key:	lockdep class annotating
 | 
			
		||||
 *				netdev_queue->_xmit_lock spinlock
 | 
			
		||||
 *
 | 
			
		||||
 *	@addr_list_lock_key:	lockdep class annotating
 | 
			
		||||
 *				net_device->addr_list_lock spinlock
 | 
			
		||||
 *	@qdisc_tx_busylock: lockdep class annotating Qdisc->busylock spinlock
 | 
			
		||||
 *	@qdisc_running_key: lockdep class annotating Qdisc->running seqcount
 | 
			
		||||
 *
 | 
			
		||||
 *	@proto_down:	protocol port state information can be sent to the
 | 
			
		||||
 *			switch driver and used to set the phys state of the
 | 
			
		||||
| 
						 | 
				
			
			@ -2112,10 +2110,9 @@ struct net_device {
 | 
			
		|||
#endif
 | 
			
		||||
	struct phy_device	*phydev;
 | 
			
		||||
	struct sfp_bus		*sfp_bus;
 | 
			
		||||
	struct lock_class_key	qdisc_tx_busylock_key;
 | 
			
		||||
	struct lock_class_key	qdisc_running_key;
 | 
			
		||||
	struct lock_class_key	qdisc_xmit_lock_key;
 | 
			
		||||
	struct lock_class_key	addr_list_lock_key;
 | 
			
		||||
	struct lock_class_key	*qdisc_tx_busylock;
 | 
			
		||||
	struct lock_class_key	*qdisc_running_key;
 | 
			
		||||
	bool			proto_down;
 | 
			
		||||
	unsigned		wol_enabled:1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -2200,6 +2197,20 @@ static inline void netdev_for_each_tx_queue(struct net_device *dev,
 | 
			
		|||
		f(dev, &dev->_tx[i], arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define netdev_lockdep_set_classes(dev)				\
 | 
			
		||||
{								\
 | 
			
		||||
	static struct lock_class_key qdisc_tx_busylock_key;	\
 | 
			
		||||
	static struct lock_class_key qdisc_running_key;		\
 | 
			
		||||
	static struct lock_class_key qdisc_xmit_lock_key;	\
 | 
			
		||||
	unsigned int i;						\
 | 
			
		||||
								\
 | 
			
		||||
	(dev)->qdisc_tx_busylock = &qdisc_tx_busylock_key;	\
 | 
			
		||||
	(dev)->qdisc_running_key = &qdisc_running_key;		\
 | 
			
		||||
	for (i = 0; i < (dev)->num_tx_queues; i++)		\
 | 
			
		||||
		lockdep_set_class(&(dev)->_tx[i]._xmit_lock,	\
 | 
			
		||||
				  &qdisc_xmit_lock_key);	\
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u16 netdev_pick_tx(struct net_device *dev, struct sk_buff *skb,
 | 
			
		||||
		     struct net_device *sb_dev);
 | 
			
		||||
struct netdev_queue *netdev_core_pick_tx(struct net_device *dev,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -489,6 +489,25 @@ static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
 | 
			
		|||
	dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * vlan network devices have devices nesting below it, and are a special
 | 
			
		||||
 * "super class" of normal network devices; split their locks off into a
 | 
			
		||||
 * separate class since they always nest.
 | 
			
		||||
 */
 | 
			
		||||
static struct lock_class_key vlan_netdev_xmit_lock_key;
 | 
			
		||||
 | 
			
		||||
static void vlan_dev_set_lockdep_one(struct net_device *dev,
 | 
			
		||||
				     struct netdev_queue *txq,
 | 
			
		||||
				     void *unused)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_set_class(&txq->_xmit_lock, &vlan_netdev_xmit_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void vlan_dev_set_lockdep_class(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct header_ops vlan_header_ops = {
 | 
			
		||||
	.create	 = vlan_dev_hard_header,
 | 
			
		||||
	.parse	 = eth_header_parse,
 | 
			
		||||
| 
						 | 
				
			
			@ -579,6 +598,8 @@ static int vlan_dev_init(struct net_device *dev)
 | 
			
		|||
 | 
			
		||||
	SET_NETDEV_DEVTYPE(dev, &vlan_type);
 | 
			
		||||
 | 
			
		||||
	vlan_dev_set_lockdep_class(dev);
 | 
			
		||||
 | 
			
		||||
	vlan->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
 | 
			
		||||
	if (!vlan->vlan_pcpu_stats)
 | 
			
		||||
		return -ENOMEM;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -739,6 +739,34 @@ static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto,
 | 
			
		|||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* batman-adv network devices have devices nesting below it and are a special
 | 
			
		||||
 * "super class" of normal network devices; split their locks off into a
 | 
			
		||||
 * separate class since they always nest.
 | 
			
		||||
 */
 | 
			
		||||
static struct lock_class_key batadv_netdev_xmit_lock_key;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * batadv_set_lockdep_class_one() - Set lockdep class for a single tx queue
 | 
			
		||||
 * @dev: device which owns the tx queue
 | 
			
		||||
 * @txq: tx queue to modify
 | 
			
		||||
 * @_unused: always NULL
 | 
			
		||||
 */
 | 
			
		||||
static void batadv_set_lockdep_class_one(struct net_device *dev,
 | 
			
		||||
					 struct netdev_queue *txq,
 | 
			
		||||
					 void *_unused)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_set_class(&txq->_xmit_lock, &batadv_netdev_xmit_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * batadv_set_lockdep_class() - Set txq and addr_list lockdep class
 | 
			
		||||
 * @dev: network device to modify
 | 
			
		||||
 */
 | 
			
		||||
static void batadv_set_lockdep_class(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * batadv_softif_init_late() - late stage initialization of soft interface
 | 
			
		||||
 * @dev: registered network device to modify
 | 
			
		||||
| 
						 | 
				
			
			@ -752,6 +780,8 @@ static int batadv_softif_init_late(struct net_device *dev)
 | 
			
		|||
	int ret;
 | 
			
		||||
	size_t cnt_len = sizeof(u64) * BATADV_CNT_NUM;
 | 
			
		||||
 | 
			
		||||
	batadv_set_lockdep_class(dev);
 | 
			
		||||
 | 
			
		||||
	bat_priv = netdev_priv(dev);
 | 
			
		||||
	bat_priv->soft_iface = dev;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -571,7 +571,15 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev)
 | 
			
		|||
	return err < 0 ? NET_XMIT_DROP : err;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int bt_dev_init(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	netdev_lockdep_set_classes(dev);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct net_device_ops netdev_ops = {
 | 
			
		||||
	.ndo_init		= bt_dev_init,
 | 
			
		||||
	.ndo_start_xmit		= bt_xmit,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -398,6 +398,74 @@ static RAW_NOTIFIER_HEAD(netdev_chain);
 | 
			
		|||
DEFINE_PER_CPU_ALIGNED(struct softnet_data, softnet_data);
 | 
			
		||||
EXPORT_PER_CPU_SYMBOL(softnet_data);
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_LOCKDEP
 | 
			
		||||
/*
 | 
			
		||||
 * register_netdevice() inits txq->_xmit_lock and sets lockdep class
 | 
			
		||||
 * according to dev->type
 | 
			
		||||
 */
 | 
			
		||||
static const unsigned short netdev_lock_type[] = {
 | 
			
		||||
	 ARPHRD_NETROM, ARPHRD_ETHER, ARPHRD_EETHER, ARPHRD_AX25,
 | 
			
		||||
	 ARPHRD_PRONET, ARPHRD_CHAOS, ARPHRD_IEEE802, ARPHRD_ARCNET,
 | 
			
		||||
	 ARPHRD_APPLETLK, ARPHRD_DLCI, ARPHRD_ATM, ARPHRD_METRICOM,
 | 
			
		||||
	 ARPHRD_IEEE1394, ARPHRD_EUI64, ARPHRD_INFINIBAND, ARPHRD_SLIP,
 | 
			
		||||
	 ARPHRD_CSLIP, ARPHRD_SLIP6, ARPHRD_CSLIP6, ARPHRD_RSRVD,
 | 
			
		||||
	 ARPHRD_ADAPT, ARPHRD_ROSE, ARPHRD_X25, ARPHRD_HWX25,
 | 
			
		||||
	 ARPHRD_PPP, ARPHRD_CISCO, ARPHRD_LAPB, ARPHRD_DDCMP,
 | 
			
		||||
	 ARPHRD_RAWHDLC, ARPHRD_TUNNEL, ARPHRD_TUNNEL6, ARPHRD_FRAD,
 | 
			
		||||
	 ARPHRD_SKIP, ARPHRD_LOOPBACK, ARPHRD_LOCALTLK, ARPHRD_FDDI,
 | 
			
		||||
	 ARPHRD_BIF, ARPHRD_SIT, ARPHRD_IPDDP, ARPHRD_IPGRE,
 | 
			
		||||
	 ARPHRD_PIMREG, ARPHRD_HIPPI, ARPHRD_ASH, ARPHRD_ECONET,
 | 
			
		||||
	 ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL,
 | 
			
		||||
	 ARPHRD_FCFABRIC, ARPHRD_IEEE80211, ARPHRD_IEEE80211_PRISM,
 | 
			
		||||
	 ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET, ARPHRD_PHONET_PIPE,
 | 
			
		||||
	 ARPHRD_IEEE802154, ARPHRD_VOID, ARPHRD_NONE};
 | 
			
		||||
 | 
			
		||||
static const char *const netdev_lock_name[] = {
 | 
			
		||||
	"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25",
 | 
			
		||||
	"_xmit_PRONET", "_xmit_CHAOS", "_xmit_IEEE802", "_xmit_ARCNET",
 | 
			
		||||
	"_xmit_APPLETLK", "_xmit_DLCI", "_xmit_ATM", "_xmit_METRICOM",
 | 
			
		||||
	"_xmit_IEEE1394", "_xmit_EUI64", "_xmit_INFINIBAND", "_xmit_SLIP",
 | 
			
		||||
	"_xmit_CSLIP", "_xmit_SLIP6", "_xmit_CSLIP6", "_xmit_RSRVD",
 | 
			
		||||
	"_xmit_ADAPT", "_xmit_ROSE", "_xmit_X25", "_xmit_HWX25",
 | 
			
		||||
	"_xmit_PPP", "_xmit_CISCO", "_xmit_LAPB", "_xmit_DDCMP",
 | 
			
		||||
	"_xmit_RAWHDLC", "_xmit_TUNNEL", "_xmit_TUNNEL6", "_xmit_FRAD",
 | 
			
		||||
	"_xmit_SKIP", "_xmit_LOOPBACK", "_xmit_LOCALTLK", "_xmit_FDDI",
 | 
			
		||||
	"_xmit_BIF", "_xmit_SIT", "_xmit_IPDDP", "_xmit_IPGRE",
 | 
			
		||||
	"_xmit_PIMREG", "_xmit_HIPPI", "_xmit_ASH", "_xmit_ECONET",
 | 
			
		||||
	"_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL",
 | 
			
		||||
	"_xmit_FCFABRIC", "_xmit_IEEE80211", "_xmit_IEEE80211_PRISM",
 | 
			
		||||
	"_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET", "_xmit_PHONET_PIPE",
 | 
			
		||||
	"_xmit_IEEE802154", "_xmit_VOID", "_xmit_NONE"};
 | 
			
		||||
 | 
			
		||||
static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)];
 | 
			
		||||
 | 
			
		||||
static inline unsigned short netdev_lock_pos(unsigned short dev_type)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < ARRAY_SIZE(netdev_lock_type); i++)
 | 
			
		||||
		if (netdev_lock_type[i] == dev_type)
 | 
			
		||||
			return i;
 | 
			
		||||
	/* the last key is used by default */
 | 
			
		||||
	return ARRAY_SIZE(netdev_lock_type) - 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline void netdev_set_xmit_lockdep_class(spinlock_t *lock,
 | 
			
		||||
						 unsigned short dev_type)
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	i = netdev_lock_pos(dev_type);
 | 
			
		||||
	lockdep_set_class_and_name(lock, &netdev_xmit_lock_key[i],
 | 
			
		||||
				   netdev_lock_name[i]);
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
static inline void netdev_set_xmit_lockdep_class(spinlock_t *lock,
 | 
			
		||||
						 unsigned short dev_type)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 *		Protocol management and registration routines
 | 
			
		||||
| 
						 | 
				
			
			@ -9208,7 +9276,7 @@ static void netdev_init_one_queue(struct net_device *dev,
 | 
			
		|||
{
 | 
			
		||||
	/* Initialize queue lock */
 | 
			
		||||
	spin_lock_init(&queue->_xmit_lock);
 | 
			
		||||
	lockdep_set_class(&queue->_xmit_lock, &dev->qdisc_xmit_lock_key);
 | 
			
		||||
	netdev_set_xmit_lockdep_class(&queue->_xmit_lock, dev->type);
 | 
			
		||||
	queue->xmit_lock_owner = -1;
 | 
			
		||||
	netdev_queue_numa_node_write(queue, NUMA_NO_NODE);
 | 
			
		||||
	queue->dev = dev;
 | 
			
		||||
| 
						 | 
				
			
			@ -9255,22 +9323,6 @@ void netif_tx_stop_all_queues(struct net_device *dev)
 | 
			
		|||
}
 | 
			
		||||
EXPORT_SYMBOL(netif_tx_stop_all_queues);
 | 
			
		||||
 | 
			
		||||
static void netdev_register_lockdep_key(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_register_key(&dev->qdisc_tx_busylock_key);
 | 
			
		||||
	lockdep_register_key(&dev->qdisc_running_key);
 | 
			
		||||
	lockdep_register_key(&dev->qdisc_xmit_lock_key);
 | 
			
		||||
	lockdep_register_key(&dev->addr_list_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void netdev_unregister_lockdep_key(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_unregister_key(&dev->qdisc_tx_busylock_key);
 | 
			
		||||
	lockdep_unregister_key(&dev->qdisc_running_key);
 | 
			
		||||
	lockdep_unregister_key(&dev->qdisc_xmit_lock_key);
 | 
			
		||||
	lockdep_unregister_key(&dev->addr_list_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void netdev_update_lockdep_key(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_unregister_key(&dev->addr_list_lock_key);
 | 
			
		||||
| 
						 | 
				
			
			@ -9837,7 +9889,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
 | 
			
		|||
 | 
			
		||||
	dev_net_set(dev, &init_net);
 | 
			
		||||
 | 
			
		||||
	netdev_register_lockdep_key(dev);
 | 
			
		||||
	lockdep_register_key(&dev->addr_list_lock_key);
 | 
			
		||||
 | 
			
		||||
	dev->gso_max_size = GSO_MAX_SIZE;
 | 
			
		||||
	dev->gso_max_segs = GSO_MAX_SEGS;
 | 
			
		||||
| 
						 | 
				
			
			@ -9926,7 +9978,7 @@ void free_netdev(struct net_device *dev)
 | 
			
		|||
	free_percpu(dev->xdp_bulkq);
 | 
			
		||||
	dev->xdp_bulkq = NULL;
 | 
			
		||||
 | 
			
		||||
	netdev_unregister_lockdep_key(dev);
 | 
			
		||||
	lockdep_unregister_key(&dev->addr_list_lock_key);
 | 
			
		||||
 | 
			
		||||
	/*  Compatibility with error handling in drivers */
 | 
			
		||||
	if (dev->reg_state == NETREG_UNINITIALIZED) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1671,6 +1671,15 @@ static int dsa_slave_phy_setup(struct net_device *slave_dev)
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct lock_class_key dsa_slave_netdev_xmit_lock_key;
 | 
			
		||||
static void dsa_slave_set_lockdep_class_one(struct net_device *dev,
 | 
			
		||||
					    struct netdev_queue *txq,
 | 
			
		||||
					    void *_unused)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_set_class(&txq->_xmit_lock,
 | 
			
		||||
			  &dsa_slave_netdev_xmit_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dsa_slave_suspend(struct net_device *slave_dev)
 | 
			
		||||
{
 | 
			
		||||
	struct dsa_port *dp = dsa_slave_to_port(slave_dev);
 | 
			
		||||
| 
						 | 
				
			
			@ -1754,6 +1763,9 @@ int dsa_slave_create(struct dsa_port *port)
 | 
			
		|||
		slave_dev->max_mtu = ETH_MAX_MTU;
 | 
			
		||||
	SET_NETDEV_DEVTYPE(slave_dev, &dsa_type);
 | 
			
		||||
 | 
			
		||||
	netdev_for_each_tx_queue(slave_dev, dsa_slave_set_lockdep_class_one,
 | 
			
		||||
				 NULL);
 | 
			
		||||
 | 
			
		||||
	SET_NETDEV_DEV(slave_dev, port->ds->dev);
 | 
			
		||||
	slave_dev->dev.of_node = port->dn;
 | 
			
		||||
	slave_dev->vlan_features = master->vlan_features;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,6 +58,13 @@ static const struct header_ops lowpan_header_ops = {
 | 
			
		|||
	.create	= lowpan_header_create,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int lowpan_dev_init(struct net_device *ldev)
 | 
			
		||||
{
 | 
			
		||||
	netdev_lockdep_set_classes(ldev);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int lowpan_open(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	if (!open_count)
 | 
			
		||||
| 
						 | 
				
			
			@ -89,6 +96,7 @@ static int lowpan_get_iflink(const struct net_device *dev)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static const struct net_device_ops lowpan_netdev_ops = {
 | 
			
		||||
	.ndo_init		= lowpan_dev_init,
 | 
			
		||||
	.ndo_start_xmit		= lowpan_xmit,
 | 
			
		||||
	.ndo_open		= lowpan_open,
 | 
			
		||||
	.ndo_stop		= lowpan_stop,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,6 +56,7 @@ static int l2tp_eth_dev_init(struct net_device *dev)
 | 
			
		|||
{
 | 
			
		||||
	eth_hw_addr_random(dev);
 | 
			
		||||
	eth_broadcast_addr(dev->broadcast);
 | 
			
		||||
	netdev_lockdep_set_classes(dev);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,6 +63,26 @@ static DEFINE_SPINLOCK(nr_list_lock);
 | 
			
		|||
 | 
			
		||||
static const struct proto_ops nr_proto_ops;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * NETROM network devices are virtual network devices encapsulating NETROM
 | 
			
		||||
 * frames into AX.25 which will be sent through an AX.25 device, so form a
 | 
			
		||||
 * special "super class" of normal net devices; split their locks off into a
 | 
			
		||||
 * separate class since they always nest.
 | 
			
		||||
 */
 | 
			
		||||
static struct lock_class_key nr_netdev_xmit_lock_key;
 | 
			
		||||
 | 
			
		||||
static void nr_set_lockdep_one(struct net_device *dev,
 | 
			
		||||
			       struct netdev_queue *txq,
 | 
			
		||||
			       void *_unused)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_set_class(&txq->_xmit_lock, &nr_netdev_xmit_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void nr_set_lockdep_key(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	netdev_for_each_tx_queue(dev, nr_set_lockdep_one, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *	Socket removal during an interrupt is now safe.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1394,6 +1414,7 @@ static int __init nr_proto_init(void)
 | 
			
		|||
			free_netdev(dev);
 | 
			
		||||
			goto fail;
 | 
			
		||||
		}
 | 
			
		||||
		nr_set_lockdep_key(dev);
 | 
			
		||||
		dev_nr[i] = dev;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,6 +64,26 @@ static const struct proto_ops rose_proto_ops;
 | 
			
		|||
 | 
			
		||||
ax25_address rose_callsign;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * ROSE network devices are virtual network devices encapsulating ROSE
 | 
			
		||||
 * frames into AX.25 which will be sent through an AX.25 device, so form a
 | 
			
		||||
 * special "super class" of normal net devices; split their locks off into a
 | 
			
		||||
 * separate class since they always nest.
 | 
			
		||||
 */
 | 
			
		||||
static struct lock_class_key rose_netdev_xmit_lock_key;
 | 
			
		||||
 | 
			
		||||
static void rose_set_lockdep_one(struct net_device *dev,
 | 
			
		||||
				 struct netdev_queue *txq,
 | 
			
		||||
				 void *_unused)
 | 
			
		||||
{
 | 
			
		||||
	lockdep_set_class(&txq->_xmit_lock, &rose_netdev_xmit_lock_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void rose_set_lockdep_key(struct net_device *dev)
 | 
			
		||||
{
 | 
			
		||||
	netdev_for_each_tx_queue(dev, rose_set_lockdep_one, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 *	Convert a ROSE address into text.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1511,6 +1531,7 @@ static int __init rose_proto_init(void)
 | 
			
		|||
			free_netdev(dev);
 | 
			
		||||
			goto fail;
 | 
			
		||||
		}
 | 
			
		||||
		rose_set_lockdep_key(dev);
 | 
			
		||||
		dev_rose[i] = dev;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -794,6 +794,9 @@ struct Qdisc_ops pfifo_fast_ops __read_mostly = {
 | 
			
		|||
};
 | 
			
		||||
EXPORT_SYMBOL(pfifo_fast_ops);
 | 
			
		||||
 | 
			
		||||
static struct lock_class_key qdisc_tx_busylock;
 | 
			
		||||
static struct lock_class_key qdisc_running_key;
 | 
			
		||||
 | 
			
		||||
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 | 
			
		||||
			  const struct Qdisc_ops *ops,
 | 
			
		||||
			  struct netlink_ext_ack *extack)
 | 
			
		||||
| 
						 | 
				
			
			@ -846,9 +849,17 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	spin_lock_init(&sch->busylock);
 | 
			
		||||
	lockdep_set_class(&sch->busylock,
 | 
			
		||||
			  dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
 | 
			
		||||
 | 
			
		||||
	/* seqlock has the same scope of busylock, for NOLOCK qdisc */
 | 
			
		||||
	spin_lock_init(&sch->seqlock);
 | 
			
		||||
	lockdep_set_class(&sch->busylock,
 | 
			
		||||
			  dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
 | 
			
		||||
 | 
			
		||||
	seqcount_init(&sch->running);
 | 
			
		||||
	lockdep_set_class(&sch->running,
 | 
			
		||||
			  dev->qdisc_running_key ?: &qdisc_running_key);
 | 
			
		||||
 | 
			
		||||
	sch->ops = ops;
 | 
			
		||||
	sch->flags = ops->static_flags;
 | 
			
		||||
| 
						 | 
				
			
			@ -859,12 +870,6 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
 | 
			
		|||
	dev_hold(dev);
 | 
			
		||||
	refcount_set(&sch->refcnt, 1);
 | 
			
		||||
 | 
			
		||||
	if (sch != &noop_qdisc) {
 | 
			
		||||
		lockdep_set_class(&sch->busylock, &dev->qdisc_tx_busylock_key);
 | 
			
		||||
		lockdep_set_class(&sch->seqlock, &dev->qdisc_tx_busylock_key);
 | 
			
		||||
		lockdep_set_class(&sch->running, &dev->qdisc_running_key);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sch;
 | 
			
		||||
errout1:
 | 
			
		||||
	kfree(p);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue