developer | 7e32f7e | 2022-05-18 21:10:08 +0800 | [diff] [blame] | 1 | From 845e0ebb4408d4473cf60d21224a897037e9a77a Mon Sep 17 00:00:00 2001 |
| 2 | From: Cong Wang <xiyou.wangcong@gmail.com> |
| 3 | Date: Mon, 8 Jun 2020 14:53:01 -0700 |
| 4 | Subject: net: change addr_list_lock back to static key |
| 5 | |
| 6 | The dynamic key update for addr_list_lock still causes troubles, |
| 7 | for example the following race condition still exists: |
| 8 | |
| 9 | CPU 0: CPU 1: |
| 10 | (RCU read lock) (RTNL lock) |
| 11 | dev_mc_seq_show() netdev_update_lockdep_key() |
| 12 | -> lockdep_unregister_key() |
| 13 | -> netif_addr_lock_bh() |
| 14 | |
| 15 | because lockdep doesn't provide an API to update it atomically. |
| 16 | Therefore, we have to move it back to static keys and use subclass |
| 17 | for nest locking like before. |
| 18 | |
| 19 | In commit 1a33e10e4a95 ("net: partially revert dynamic lockdep key |
| 20 | changes"), I already reverted most parts of commit ab92d68fc22f |
| 21 | ("net: core: add generic lockdep keys"). |
| 22 | |
| 23 | This patch reverts the rest and also part of commit f3b0a18bb6cb |
| 24 | ("net: remove unnecessary variables and callback"). After this |
| 25 | patch, addr_list_lock changes back to using static keys and |
| 26 | subclasses to satisfy lockdep. Thanks to dev->lower_level, we do |
| 27 | not have to change back to ->ndo_get_lock_subclass(). |
| 28 | |
| 29 | And hopefully this reduces some syzbot lockdep noises too. |
| 30 | |
| 31 | Reported-by: syzbot+f3a0e80c34b3fc28ac5e@syzkaller.appspotmail.com |
| 32 | Cc: Taehee Yoo <ap420073@gmail.com> |
| 33 | Cc: Dmitry Vyukov <dvyukov@google.com> |
| 34 | Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> |
| 35 | Signed-off-by: David S. Miller <davem@davemloft.net> |
| 36 | --- |
| 37 | drivers/net/bonding/bond_main.c | 2 -- |
| 38 | drivers/net/bonding/bond_options.c | 2 -- |
| 39 | drivers/net/hamradio/bpqether.c | 2 ++ |
| 40 | drivers/net/macsec.c | 5 ++++ |
| 41 | drivers/net/macvlan.c | 13 ++++++++-- |
| 42 | drivers/net/vxlan.c | 4 +--- |
| 43 | drivers/net/wireless/intersil/hostap/hostap_hw.c | 3 +++ |
| 44 | include/linux/netdevice.h | 12 ++++++---- |
| 45 | net/8021q/vlan_dev.c | 8 +++++-- |
| 46 | net/batman-adv/soft-interface.c | 2 ++ |
| 47 | net/bridge/br_device.c | 8 +++++++ |
| 48 | net/core/dev.c | 30 +++++++++++++----------- |
| 49 | net/core/dev_addr_lists.c | 12 +++++----- |
| 50 | net/core/rtnetlink.c | 1 - |
| 51 | net/dsa/master.c | 4 ++++ |
| 52 | net/netrom/af_netrom.c | 2 ++ |
| 53 | net/rose/af_rose.c | 2 ++ |
| 54 | 17 files changed, 76 insertions(+), 36 deletions(-) |
| 55 | |
| 56 | diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c |
| 57 | index a25c65d4af716..004919aea5fbf 100644 |
| 58 | --- a/drivers/net/bonding/bond_main.c |
| 59 | +++ b/drivers/net/bonding/bond_main.c |
| 60 | @@ -3687,8 +3687,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd |
| 61 | case BOND_RELEASE_OLD: |
| 62 | case SIOCBONDRELEASE: |
| 63 | res = bond_release(bond_dev, slave_dev); |
| 64 | - if (!res) |
| 65 | - netdev_update_lockdep_key(slave_dev); |
| 66 | break; |
| 67 | case BOND_SETHWADDR_OLD: |
| 68 | case SIOCBONDSETHWADDR: |
| 69 | diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c |
| 70 | index 215c109232893..ddb3916d3506b 100644 |
| 71 | --- a/drivers/net/bonding/bond_options.c |
| 72 | +++ b/drivers/net/bonding/bond_options.c |
| 73 | @@ -1398,8 +1398,6 @@ static int bond_option_slaves_set(struct bonding *bond, |
| 74 | case '-': |
| 75 | slave_dbg(bond->dev, dev, "Releasing interface\n"); |
| 76 | ret = bond_release(bond->dev, dev); |
| 77 | - if (!ret) |
| 78 | - netdev_update_lockdep_key(dev); |
| 79 | break; |
| 80 | |
| 81 | default: |
| 82 | diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c |
| 83 | index 60dcaf2a04a91..1ad6085994b1c 100644 |
| 84 | --- a/drivers/net/hamradio/bpqether.c |
| 85 | +++ b/drivers/net/hamradio/bpqether.c |
| 86 | @@ -113,6 +113,7 @@ static LIST_HEAD(bpq_devices); |
| 87 | * off into a separate class since they always nest. |
| 88 | */ |
| 89 | static struct lock_class_key bpq_netdev_xmit_lock_key; |
| 90 | +static struct lock_class_key bpq_netdev_addr_lock_key; |
| 91 | |
| 92 | static void bpq_set_lockdep_class_one(struct net_device *dev, |
| 93 | struct netdev_queue *txq, |
| 94 | @@ -123,6 +124,7 @@ static void bpq_set_lockdep_class_one(struct net_device *dev, |
| 95 | |
| 96 | static void bpq_set_lockdep_class(struct net_device *dev) |
| 97 | { |
| 98 | + lockdep_set_class(&dev->addr_list_lock, &bpq_netdev_addr_lock_key); |
| 99 | netdev_for_each_tx_queue(dev, bpq_set_lockdep_class_one, NULL); |
| 100 | } |
| 101 | |
| 102 | diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c |
| 103 | index 20b53e255f68a..e56547bfdac9a 100644 |
| 104 | --- a/drivers/net/macsec.c |
| 105 | +++ b/drivers/net/macsec.c |
| 106 | @@ -3999,6 +3999,8 @@ static int macsec_add_dev(struct net_device *dev, sci_t sci, u8 icv_len) |
| 107 | return 0; |
| 108 | } |
| 109 | |
| 110 | +static struct lock_class_key macsec_netdev_addr_lock_key; |
| 111 | + |
| 112 | static int macsec_newlink(struct net *net, struct net_device *dev, |
| 113 | struct nlattr *tb[], struct nlattr *data[], |
| 114 | struct netlink_ext_ack *extack) |
| 115 | @@ -4050,6 +4052,9 @@ static int macsec_newlink(struct net *net, struct net_device *dev, |
| 116 | return err; |
| 117 | |
| 118 | netdev_lockdep_set_classes(dev); |
| 119 | + lockdep_set_class_and_subclass(&dev->addr_list_lock, |
| 120 | + &macsec_netdev_addr_lock_key, |
| 121 | + dev->lower_level); |
| 122 | |
| 123 | err = netdev_upper_dev_link(real_dev, dev, extack); |
| 124 | if (err < 0) |
| 125 | diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c |
| 126 | index 563aed5b3d9fe..6a6cc9f753075 100644 |
| 127 | --- a/drivers/net/macvlan.c |
| 128 | +++ b/drivers/net/macvlan.c |
| 129 | @@ -860,6 +860,8 @@ static int macvlan_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
| 130 | * "super class" of normal network devices; split their locks off into a |
| 131 | * separate class since they always nest. |
| 132 | */ |
| 133 | +static struct lock_class_key macvlan_netdev_addr_lock_key; |
| 134 | + |
| 135 | #define ALWAYS_ON_OFFLOADS \ |
| 136 | (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | \ |
| 137 | NETIF_F_GSO_ROBUST | NETIF_F_GSO_ENCAP_ALL) |
| 138 | @@ -875,6 +877,14 @@ static int macvlan_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
| 139 | #define MACVLAN_STATE_MASK \ |
| 140 | ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT)) |
| 141 | |
| 142 | +static void macvlan_set_lockdep_class(struct net_device *dev) |
| 143 | +{ |
| 144 | + netdev_lockdep_set_classes(dev); |
| 145 | + lockdep_set_class_and_subclass(&dev->addr_list_lock, |
| 146 | + &macvlan_netdev_addr_lock_key, |
| 147 | + dev->lower_level); |
| 148 | +} |
| 149 | + |
| 150 | static int macvlan_init(struct net_device *dev) |
| 151 | { |
| 152 | struct macvlan_dev *vlan = netdev_priv(dev); |
| 153 | @@ -892,8 +902,7 @@ static int macvlan_init(struct net_device *dev) |
| 154 | dev->gso_max_size = lowerdev->gso_max_size; |
| 155 | dev->gso_max_segs = lowerdev->gso_max_segs; |
| 156 | dev->hard_header_len = lowerdev->hard_header_len; |
| 157 | - |
| 158 | - netdev_lockdep_set_classes(dev); |
| 159 | + macvlan_set_lockdep_class(dev); |
| 160 | |
| 161 | vlan->pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); |
| 162 | if (!vlan->pcpu_stats) |
| 163 | diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c |
| 164 | index 5bb448ae6c9c4..47424b2da6437 100644 |
| 165 | --- a/drivers/net/vxlan.c |
| 166 | +++ b/drivers/net/vxlan.c |
| 167 | @@ -4245,10 +4245,8 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[], |
| 168 | mod_timer(&vxlan->age_timer, jiffies); |
| 169 | |
| 170 | netdev_adjacent_change_commit(dst->remote_dev, lowerdev, dev); |
| 171 | - if (lowerdev && lowerdev != dst->remote_dev) { |
| 172 | + if (lowerdev && lowerdev != dst->remote_dev) |
| 173 | dst->remote_dev = lowerdev; |
| 174 | - netdev_update_lockdep_key(lowerdev); |
| 175 | - } |
| 176 | vxlan_config_apply(dev, &conf, lowerdev, vxlan->net, true); |
| 177 | return 0; |
| 178 | } |
| 179 | diff --git a/drivers/net/wireless/intersil/hostap/hostap_hw.c b/drivers/net/wireless/intersil/hostap/hostap_hw.c |
| 180 | index aadf3dec5bf32..2ab34cf74ecc3 100644 |
| 181 | --- a/drivers/net/wireless/intersil/hostap/hostap_hw.c |
| 182 | +++ b/drivers/net/wireless/intersil/hostap/hostap_hw.c |
| 183 | @@ -3048,6 +3048,7 @@ static void prism2_clear_set_tim_queue(local_info_t *local) |
| 184 | * This is a natural nesting, which needs a split lock type. |
| 185 | */ |
| 186 | static struct lock_class_key hostap_netdev_xmit_lock_key; |
| 187 | +static struct lock_class_key hostap_netdev_addr_lock_key; |
| 188 | |
| 189 | static void prism2_set_lockdep_class_one(struct net_device *dev, |
| 190 | struct netdev_queue *txq, |
| 191 | @@ -3059,6 +3060,8 @@ static void prism2_set_lockdep_class_one(struct net_device *dev, |
| 192 | |
| 193 | static void prism2_set_lockdep_class(struct net_device *dev) |
| 194 | { |
| 195 | + lockdep_set_class(&dev->addr_list_lock, |
| 196 | + &hostap_netdev_addr_lock_key); |
| 197 | netdev_for_each_tx_queue(dev, prism2_set_lockdep_class_one, NULL); |
| 198 | } |
| 199 | |
| 200 | diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h |
| 201 | index 1a96e9c4ec36f..e2825e27ef89d 100644 |
| 202 | --- a/include/linux/netdevice.h |
| 203 | +++ b/include/linux/netdevice.h |
| 204 | @@ -1821,8 +1821,6 @@ enum netdev_priv_flags { |
| 205 | * for hardware timestamping |
| 206 | * @sfp_bus: attached &struct sfp_bus structure. |
| 207 | * |
| 208 | - * @addr_list_lock_key: lockdep class annotating |
| 209 | - * net_device->addr_list_lock spinlock |
| 210 | * @qdisc_tx_busylock: lockdep class annotating Qdisc->busylock spinlock |
| 211 | * @qdisc_running_key: lockdep class annotating Qdisc->running seqcount |
| 212 | * |
| 213 | @@ -2125,7 +2123,6 @@ struct net_device { |
| 214 | #endif |
| 215 | struct phy_device *phydev; |
| 216 | struct sfp_bus *sfp_bus; |
| 217 | - struct lock_class_key addr_list_lock_key; |
| 218 | struct lock_class_key *qdisc_tx_busylock; |
| 219 | struct lock_class_key *qdisc_running_key; |
| 220 | bool proto_down; |
| 221 | @@ -2217,10 +2214,13 @@ static inline void netdev_for_each_tx_queue(struct net_device *dev, |
| 222 | static struct lock_class_key qdisc_tx_busylock_key; \ |
| 223 | static struct lock_class_key qdisc_running_key; \ |
| 224 | static struct lock_class_key qdisc_xmit_lock_key; \ |
| 225 | + static struct lock_class_key dev_addr_list_lock_key; \ |
| 226 | unsigned int i; \ |
| 227 | \ |
| 228 | (dev)->qdisc_tx_busylock = &qdisc_tx_busylock_key; \ |
| 229 | (dev)->qdisc_running_key = &qdisc_running_key; \ |
| 230 | + lockdep_set_class(&(dev)->addr_list_lock, \ |
| 231 | + &dev_addr_list_lock_key); \ |
| 232 | for (i = 0; i < (dev)->num_tx_queues; i++) \ |
| 233 | lockdep_set_class(&(dev)->_tx[i]._xmit_lock, \ |
| 234 | &qdisc_xmit_lock_key); \ |
| 235 | @@ -3253,7 +3253,6 @@ static inline void netif_stop_queue(struct net_device *dev) |
| 236 | } |
| 237 | |
| 238 | void netif_tx_stop_all_queues(struct net_device *dev); |
| 239 | -void netdev_update_lockdep_key(struct net_device *dev); |
| 240 | |
| 241 | static inline bool netif_tx_queue_stopped(const struct netdev_queue *dev_queue) |
| 242 | { |
| 243 | @@ -4239,6 +4238,11 @@ static inline void netif_addr_lock(struct net_device *dev) |
| 244 | spin_lock(&dev->addr_list_lock); |
| 245 | } |
| 246 | |
| 247 | +static inline void netif_addr_lock_nested(struct net_device *dev) |
| 248 | +{ |
| 249 | + spin_lock_nested(&dev->addr_list_lock, dev->lower_level); |
| 250 | +} |
| 251 | + |
| 252 | static inline void netif_addr_lock_bh(struct net_device *dev) |
| 253 | { |
| 254 | spin_lock_bh(&dev->addr_list_lock); |
| 255 | diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c |
| 256 | index f00bb57f0f600..c8d6a07e23c57 100644 |
| 257 | --- a/net/8021q/vlan_dev.c |
| 258 | +++ b/net/8021q/vlan_dev.c |
| 259 | @@ -494,6 +494,7 @@ static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) |
| 260 | * separate class since they always nest. |
| 261 | */ |
| 262 | static struct lock_class_key vlan_netdev_xmit_lock_key; |
| 263 | +static struct lock_class_key vlan_netdev_addr_lock_key; |
| 264 | |
| 265 | static void vlan_dev_set_lockdep_one(struct net_device *dev, |
| 266 | struct netdev_queue *txq, |
| 267 | @@ -502,8 +503,11 @@ static void vlan_dev_set_lockdep_one(struct net_device *dev, |
| 268 | lockdep_set_class(&txq->_xmit_lock, &vlan_netdev_xmit_lock_key); |
| 269 | } |
| 270 | |
| 271 | -static void vlan_dev_set_lockdep_class(struct net_device *dev) |
| 272 | +static void vlan_dev_set_lockdep_class(struct net_device *dev, int subclass) |
| 273 | { |
| 274 | + lockdep_set_class_and_subclass(&dev->addr_list_lock, |
| 275 | + &vlan_netdev_addr_lock_key, |
| 276 | + subclass); |
| 277 | netdev_for_each_tx_queue(dev, vlan_dev_set_lockdep_one, NULL); |
| 278 | } |
| 279 | |
| 280 | @@ -597,7 +601,7 @@ static int vlan_dev_init(struct net_device *dev) |
| 281 | |
| 282 | SET_NETDEV_DEVTYPE(dev, &vlan_type); |
| 283 | |
| 284 | - vlan_dev_set_lockdep_class(dev); |
| 285 | + vlan_dev_set_lockdep_class(dev, dev->lower_level); |
| 286 | |
| 287 | vlan->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); |
| 288 | if (!vlan->vlan_pcpu_stats) |
| 289 | diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c |
| 290 | index 0ddd80130ea36..f1f1c86f34193 100644 |
| 291 | --- a/net/batman-adv/soft-interface.c |
| 292 | +++ b/net/batman-adv/soft-interface.c |
| 293 | @@ -745,6 +745,7 @@ static int batadv_interface_kill_vid(struct net_device *dev, __be16 proto, |
| 294 | * separate class since they always nest. |
| 295 | */ |
| 296 | static struct lock_class_key batadv_netdev_xmit_lock_key; |
| 297 | +static struct lock_class_key batadv_netdev_addr_lock_key; |
| 298 | |
| 299 | /** |
| 300 | * batadv_set_lockdep_class_one() - Set lockdep class for a single tx queue |
| 301 | @@ -765,6 +766,7 @@ static void batadv_set_lockdep_class_one(struct net_device *dev, |
| 302 | */ |
| 303 | static void batadv_set_lockdep_class(struct net_device *dev) |
| 304 | { |
| 305 | + lockdep_set_class(&dev->addr_list_lock, &batadv_netdev_addr_lock_key); |
| 306 | netdev_for_each_tx_queue(dev, batadv_set_lockdep_class_one, NULL); |
| 307 | } |
| 308 | |
| 309 | diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c |
| 310 | index 8ec1362588af1..8c7b78f8bc230 100644 |
| 311 | --- a/net/bridge/br_device.c |
| 312 | +++ b/net/bridge/br_device.c |
| 313 | @@ -105,6 +105,13 @@ out: |
| 314 | return NETDEV_TX_OK; |
| 315 | } |
| 316 | |
| 317 | +static struct lock_class_key bridge_netdev_addr_lock_key; |
| 318 | + |
| 319 | +static void br_set_lockdep_class(struct net_device *dev) |
| 320 | +{ |
| 321 | + lockdep_set_class(&dev->addr_list_lock, &bridge_netdev_addr_lock_key); |
| 322 | +} |
| 323 | + |
| 324 | static int br_dev_init(struct net_device *dev) |
| 325 | { |
| 326 | struct net_bridge *br = netdev_priv(dev); |
| 327 | @@ -143,6 +150,7 @@ static int br_dev_init(struct net_device *dev) |
| 328 | br_fdb_hash_fini(br); |
| 329 | } |
| 330 | |
| 331 | + br_set_lockdep_class(dev); |
| 332 | return err; |
| 333 | } |
| 334 | |
| 335 | diff --git a/net/core/dev.c b/net/core/dev.c |
| 336 | index 061496a1f640f..6bc2388141f6f 100644 |
| 337 | --- a/net/core/dev.c |
| 338 | +++ b/net/core/dev.c |
| 339 | @@ -439,6 +439,7 @@ static const char *const netdev_lock_name[] = { |
| 340 | "_xmit_IEEE802154", "_xmit_VOID", "_xmit_NONE"}; |
| 341 | |
| 342 | static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)]; |
| 343 | +static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)]; |
| 344 | |
| 345 | static inline unsigned short netdev_lock_pos(unsigned short dev_type) |
| 346 | { |
| 347 | @@ -460,11 +461,25 @@ static inline void netdev_set_xmit_lockdep_class(spinlock_t *lock, |
| 348 | lockdep_set_class_and_name(lock, &netdev_xmit_lock_key[i], |
| 349 | netdev_lock_name[i]); |
| 350 | } |
| 351 | + |
| 352 | +static inline void netdev_set_addr_lockdep_class(struct net_device *dev) |
| 353 | +{ |
| 354 | + int i; |
| 355 | + |
| 356 | + i = netdev_lock_pos(dev->type); |
| 357 | + lockdep_set_class_and_name(&dev->addr_list_lock, |
| 358 | + &netdev_addr_lock_key[i], |
| 359 | + netdev_lock_name[i]); |
| 360 | +} |
| 361 | #else |
| 362 | static inline void netdev_set_xmit_lockdep_class(spinlock_t *lock, |
| 363 | unsigned short dev_type) |
| 364 | { |
| 365 | } |
| 366 | + |
| 367 | +static inline void netdev_set_addr_lockdep_class(struct net_device *dev) |
| 368 | +{ |
| 369 | +} |
| 370 | #endif |
| 371 | |
| 372 | /******************************************************************************* |
| 373 | @@ -9373,15 +9388,6 @@ void netif_tx_stop_all_queues(struct net_device *dev) |
| 374 | } |
| 375 | EXPORT_SYMBOL(netif_tx_stop_all_queues); |
| 376 | |
| 377 | -void netdev_update_lockdep_key(struct net_device *dev) |
| 378 | -{ |
| 379 | - lockdep_unregister_key(&dev->addr_list_lock_key); |
| 380 | - lockdep_register_key(&dev->addr_list_lock_key); |
| 381 | - |
| 382 | - lockdep_set_class(&dev->addr_list_lock, &dev->addr_list_lock_key); |
| 383 | -} |
| 384 | -EXPORT_SYMBOL(netdev_update_lockdep_key); |
| 385 | - |
| 386 | /** |
| 387 | * register_netdevice - register a network device |
| 388 | * @dev: device to register |
| 389 | @@ -9420,7 +9426,7 @@ int register_netdevice(struct net_device *dev) |
| 390 | return ret; |
| 391 | |
| 392 | spin_lock_init(&dev->addr_list_lock); |
| 393 | - lockdep_set_class(&dev->addr_list_lock, &dev->addr_list_lock_key); |
| 394 | + netdev_set_addr_lockdep_class(dev); |
| 395 | |
| 396 | ret = dev_get_valid_name(net, dev, dev->name); |
| 397 | if (ret < 0) |
| 398 | @@ -9939,8 +9945,6 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, |
| 399 | |
| 400 | dev_net_set(dev, &init_net); |
| 401 | |
| 402 | - lockdep_register_key(&dev->addr_list_lock_key); |
| 403 | - |
| 404 | dev->gso_max_size = GSO_MAX_SIZE; |
| 405 | dev->gso_max_segs = GSO_MAX_SEGS; |
| 406 | dev->upper_level = 1; |
| 407 | @@ -10028,8 +10032,6 @@ void free_netdev(struct net_device *dev) |
| 408 | free_percpu(dev->xdp_bulkq); |
| 409 | dev->xdp_bulkq = NULL; |
| 410 | |
| 411 | - lockdep_unregister_key(&dev->addr_list_lock_key); |
| 412 | - |
| 413 | /* Compatibility with error handling in drivers */ |
| 414 | if (dev->reg_state == NETREG_UNINITIALIZED) { |
| 415 | netdev_freemem(dev); |
| 416 | diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c |
| 417 | index 2f949b5a1eb9c..6393ba930097b 100644 |
| 418 | --- a/net/core/dev_addr_lists.c |
| 419 | +++ b/net/core/dev_addr_lists.c |
| 420 | @@ -637,7 +637,7 @@ int dev_uc_sync(struct net_device *to, struct net_device *from) |
| 421 | if (to->addr_len != from->addr_len) |
| 422 | return -EINVAL; |
| 423 | |
| 424 | - netif_addr_lock(to); |
| 425 | + netif_addr_lock_nested(to); |
| 426 | err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); |
| 427 | if (!err) |
| 428 | __dev_set_rx_mode(to); |
| 429 | @@ -667,7 +667,7 @@ int dev_uc_sync_multiple(struct net_device *to, struct net_device *from) |
| 430 | if (to->addr_len != from->addr_len) |
| 431 | return -EINVAL; |
| 432 | |
| 433 | - netif_addr_lock(to); |
| 434 | + netif_addr_lock_nested(to); |
| 435 | err = __hw_addr_sync_multiple(&to->uc, &from->uc, to->addr_len); |
| 436 | if (!err) |
| 437 | __dev_set_rx_mode(to); |
| 438 | @@ -691,7 +691,7 @@ void dev_uc_unsync(struct net_device *to, struct net_device *from) |
| 439 | return; |
| 440 | |
| 441 | netif_addr_lock_bh(from); |
| 442 | - netif_addr_lock(to); |
| 443 | + netif_addr_lock_nested(to); |
| 444 | __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); |
| 445 | __dev_set_rx_mode(to); |
| 446 | netif_addr_unlock(to); |
| 447 | @@ -858,7 +858,7 @@ int dev_mc_sync(struct net_device *to, struct net_device *from) |
| 448 | if (to->addr_len != from->addr_len) |
| 449 | return -EINVAL; |
| 450 | |
| 451 | - netif_addr_lock(to); |
| 452 | + netif_addr_lock_nested(to); |
| 453 | err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); |
| 454 | if (!err) |
| 455 | __dev_set_rx_mode(to); |
| 456 | @@ -888,7 +888,7 @@ int dev_mc_sync_multiple(struct net_device *to, struct net_device *from) |
| 457 | if (to->addr_len != from->addr_len) |
| 458 | return -EINVAL; |
| 459 | |
| 460 | - netif_addr_lock(to); |
| 461 | + netif_addr_lock_nested(to); |
| 462 | err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len); |
| 463 | if (!err) |
| 464 | __dev_set_rx_mode(to); |
| 465 | @@ -912,7 +912,7 @@ void dev_mc_unsync(struct net_device *to, struct net_device *from) |
| 466 | return; |
| 467 | |
| 468 | netif_addr_lock_bh(from); |
| 469 | - netif_addr_lock(to); |
| 470 | + netif_addr_lock_nested(to); |
| 471 | __hw_addr_unsync(&to->mc, &from->mc, to->addr_len); |
| 472 | __dev_set_rx_mode(to); |
| 473 | netif_addr_unlock(to); |
| 474 | diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c |
| 475 | index 2269199c58910..9aedc15736adf 100644 |
| 476 | --- a/net/core/rtnetlink.c |
| 477 | +++ b/net/core/rtnetlink.c |
| 478 | @@ -2462,7 +2462,6 @@ static int do_set_master(struct net_device *dev, int ifindex, |
| 479 | err = ops->ndo_del_slave(upper_dev, dev); |
| 480 | if (err) |
| 481 | return err; |
| 482 | - netdev_update_lockdep_key(dev); |
| 483 | } else { |
| 484 | return -EOPNOTSUPP; |
| 485 | } |
| 486 | diff --git a/net/dsa/master.c b/net/dsa/master.c |
| 487 | index a621367c6e8c2..480a61460c239 100644 |
| 488 | --- a/net/dsa/master.c |
| 489 | +++ b/net/dsa/master.c |
| 490 | @@ -327,6 +327,8 @@ static void dsa_master_reset_mtu(struct net_device *dev) |
| 491 | rtnl_unlock(); |
| 492 | } |
| 493 | |
| 494 | +static struct lock_class_key dsa_master_addr_list_lock_key; |
| 495 | + |
| 496 | int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp) |
| 497 | { |
| 498 | int ret; |
| 499 | @@ -345,6 +347,8 @@ int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp) |
| 500 | wmb(); |
| 501 | |
| 502 | dev->dsa_ptr = cpu_dp; |
| 503 | + lockdep_set_class(&dev->addr_list_lock, |
| 504 | + &dsa_master_addr_list_lock_key); |
| 505 | ret = dsa_master_ethtool_setup(dev); |
| 506 | if (ret) |
| 507 | return ret; |
| 508 | diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c |
| 509 | index eccc7d366e17f..f90ef6934b8f4 100644 |
| 510 | --- a/net/netrom/af_netrom.c |
| 511 | +++ b/net/netrom/af_netrom.c |
| 512 | @@ -70,6 +70,7 @@ static const struct proto_ops nr_proto_ops; |
| 513 | * separate class since they always nest. |
| 514 | */ |
| 515 | static struct lock_class_key nr_netdev_xmit_lock_key; |
| 516 | +static struct lock_class_key nr_netdev_addr_lock_key; |
| 517 | |
| 518 | static void nr_set_lockdep_one(struct net_device *dev, |
| 519 | struct netdev_queue *txq, |
| 520 | @@ -80,6 +81,7 @@ static void nr_set_lockdep_one(struct net_device *dev, |
| 521 | |
| 522 | static void nr_set_lockdep_key(struct net_device *dev) |
| 523 | { |
| 524 | + lockdep_set_class(&dev->addr_list_lock, &nr_netdev_addr_lock_key); |
| 525 | netdev_for_each_tx_queue(dev, nr_set_lockdep_one, NULL); |
| 526 | } |
| 527 | |
| 528 | diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c |
| 529 | index e7a872207b464..ce85656ac9c15 100644 |
| 530 | --- a/net/rose/af_rose.c |
| 531 | +++ b/net/rose/af_rose.c |
| 532 | @@ -71,6 +71,7 @@ ax25_address rose_callsign; |
| 533 | * separate class since they always nest. |
| 534 | */ |
| 535 | static struct lock_class_key rose_netdev_xmit_lock_key; |
| 536 | +static struct lock_class_key rose_netdev_addr_lock_key; |
| 537 | |
| 538 | static void rose_set_lockdep_one(struct net_device *dev, |
| 539 | struct netdev_queue *txq, |
| 540 | @@ -81,6 +82,7 @@ static void rose_set_lockdep_one(struct net_device *dev, |
| 541 | |
| 542 | static void rose_set_lockdep_key(struct net_device *dev) |
| 543 | { |
| 544 | + lockdep_set_class(&dev->addr_list_lock, &rose_netdev_addr_lock_key); |
| 545 | netdev_for_each_tx_queue(dev, rose_set_lockdep_one, NULL); |
| 546 | } |
| 547 | |
| 548 | -- |
| 549 | cgit 1.2.3-1.el7 |
| 550 | |