Skip to content

Commit d38569a

Browse files
Vlad Yasevichdavem330
authored andcommitted
vlan: Fix lockdep warning with stacked vlan devices.
This reverts commit dc8eaaa. vlan: Fix lockdep warning when vlan dev handle notification Instead we use the new new API to find the lock subclass of our vlan device. This way we can support configurations where vlans are interspersed with other devices: bond -> vlan -> macvlan -> vlan Signed-off-by: Vlad Yasevich <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 25175ba commit d38569a

File tree

4 files changed

+12
-45
lines changed

4 files changed

+12
-45
lines changed

include/linux/if_vlan.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ static inline struct vlan_ethhdr *vlan_eth_hdr(const struct sk_buff *skb)
7373
/* found in socket.c */
7474
extern void vlan_ioctl_set(int (*hook)(struct net *, void __user *));
7575

76-
static inline int is_vlan_dev(struct net_device *dev)
76+
static inline bool is_vlan_dev(struct net_device *dev)
7777
{
7878
return dev->priv_flags & IFF_802_1Q_VLAN;
7979
}
@@ -159,6 +159,7 @@ struct vlan_dev_priv {
159159
#ifdef CONFIG_NET_POLL_CONTROLLER
160160
struct netpoll *netpoll;
161161
#endif
162+
unsigned int nest_level;
162163
};
163164

164165
static inline struct vlan_dev_priv *vlan_dev_priv(const struct net_device *dev)

net/8021q/vlan.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ int register_vlan_dev(struct net_device *dev)
169169
if (err < 0)
170170
goto out_uninit_mvrp;
171171

172+
vlan->nest_level = dev_get_nest_level(real_dev, is_vlan_dev) + 1;
172173
err = register_netdevice(dev);
173174
if (err < 0)
174175
goto out_uninit_mvrp;

net/8021q/vlan_dev.c

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -493,48 +493,10 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
493493
}
494494
}
495495

496-
static int vlan_calculate_locking_subclass(struct net_device *real_dev)
497-
{
498-
int subclass = 0;
499-
500-
while (is_vlan_dev(real_dev)) {
501-
subclass++;
502-
real_dev = vlan_dev_priv(real_dev)->real_dev;
503-
}
504-
505-
return subclass;
506-
}
507-
508-
static void vlan_dev_mc_sync(struct net_device *to, struct net_device *from)
509-
{
510-
int err = 0, subclass;
511-
512-
subclass = vlan_calculate_locking_subclass(to);
513-
514-
spin_lock_nested(&to->addr_list_lock, subclass);
515-
err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
516-
if (!err)
517-
__dev_set_rx_mode(to);
518-
spin_unlock(&to->addr_list_lock);
519-
}
520-
521-
static void vlan_dev_uc_sync(struct net_device *to, struct net_device *from)
522-
{
523-
int err = 0, subclass;
524-
525-
subclass = vlan_calculate_locking_subclass(to);
526-
527-
spin_lock_nested(&to->addr_list_lock, subclass);
528-
err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len);
529-
if (!err)
530-
__dev_set_rx_mode(to);
531-
spin_unlock(&to->addr_list_lock);
532-
}
533-
534496
static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
535497
{
536-
vlan_dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
537-
vlan_dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
498+
dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
499+
dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
538500
}
539501

540502
/*
@@ -562,6 +524,11 @@ static void vlan_dev_set_lockdep_class(struct net_device *dev, int subclass)
562524
netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, &subclass);
563525
}
564526

527+
static int vlan_dev_get_lock_subclass(struct net_device *dev)
528+
{
529+
return vlan_dev_priv(dev)->nest_level;
530+
}
531+
565532
static const struct header_ops vlan_header_ops = {
566533
.create = vlan_dev_hard_header,
567534
.rebuild = vlan_dev_rebuild_header,
@@ -597,7 +564,6 @@ static const struct net_device_ops vlan_netdev_ops;
597564
static int vlan_dev_init(struct net_device *dev)
598565
{
599566
struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
600-
int subclass = 0;
601567

602568
netif_carrier_off(dev);
603569

@@ -646,8 +612,7 @@ static int vlan_dev_init(struct net_device *dev)
646612

647613
SET_NETDEV_DEVTYPE(dev, &vlan_type);
648614

649-
subclass = vlan_calculate_locking_subclass(dev);
650-
vlan_dev_set_lockdep_class(dev, subclass);
615+
vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev));
651616

652617
vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
653618
if (!vlan_dev_priv(dev)->vlan_pcpu_stats)
@@ -819,6 +784,7 @@ static const struct net_device_ops vlan_netdev_ops = {
819784
.ndo_netpoll_cleanup = vlan_dev_netpoll_cleanup,
820785
#endif
821786
.ndo_fix_features = vlan_dev_fix_features,
787+
.ndo_get_lock_subclass = vlan_dev_get_lock_subclass,
822788
};
823789

824790
void vlan_setup(struct net_device *dev)

net/core/dev.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5287,7 +5287,6 @@ void __dev_set_rx_mode(struct net_device *dev)
52875287
if (ops->ndo_set_rx_mode)
52885288
ops->ndo_set_rx_mode(dev);
52895289
}
5290-
EXPORT_SYMBOL(__dev_set_rx_mode);
52915290

52925291
void dev_set_rx_mode(struct net_device *dev)
52935292
{

0 commit comments

Comments
 (0)