Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'dsa-cross-chip-notifiers'

Vladimir Oltean says:

====================
Improvements to the DSA tag_8021q cross-chip notifiers

This series improves cross-chip notifier error messages and addresses a
benign error message seen during reboot on a system with disjoint DSA
trees.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+38 -22
+3
net/dsa/dsa2.c
··· 49 49 * Can be used to notify the switching fabric of events such as cross-chip 50 50 * bridging between disjoint trees (such as islands of tagger-compatible 51 51 * switches bridged by an incompatible middle switch). 52 + * 53 + * WARNING: this function is not reliable during probe time, because probing 54 + * between trees is asynchronous and not all DSA trees might have probed. 52 55 */ 53 56 int dsa_broadcast(unsigned long e, void *v) 54 57 {
+2 -2
net/dsa/dsa_priv.h
··· 261 261 void dsa_port_link_unregister_of(struct dsa_port *dp); 262 262 int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr); 263 263 void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr); 264 - int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid); 265 - void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid); 264 + int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast); 265 + void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast); 266 266 extern const struct phylink_mac_ops dsa_port_phylink_mac_ops; 267 267 268 268 static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp,
+22 -10
net/dsa/port.c
··· 426 426 427 427 err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info); 428 428 if (err) 429 - pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n"); 429 + dev_err(dp->ds->dev, 430 + "port %d failed to notify DSA_NOTIFIER_BRIDGE_LEAVE: %pe\n", 431 + dp->index, ERR_PTR(err)); 430 432 431 433 dsa_port_switchdev_unsync_attrs(dp); 432 434 } ··· 527 525 528 526 err = dsa_port_notify(dp, DSA_NOTIFIER_LAG_LEAVE, &info); 529 527 if (err) 530 - pr_err("DSA: failed to notify DSA_NOTIFIER_LAG_LEAVE: %d\n", 531 - err); 528 + dev_err(dp->ds->dev, 529 + "port %d failed to notify DSA_NOTIFIER_LAG_LEAVE: %pe\n", 530 + dp->index, ERR_PTR(err)); 532 531 533 532 dsa_lag_unmap(dp->ds->dst, lag); 534 533 } ··· 1309 1306 1310 1307 err = dsa_port_notify(dp, DSA_NOTIFIER_HSR_LEAVE, &info); 1311 1308 if (err) 1312 - pr_err("DSA: failed to notify DSA_NOTIFIER_HSR_LEAVE\n"); 1309 + dev_err(dp->ds->dev, 1310 + "port %d failed to notify DSA_NOTIFIER_HSR_LEAVE: %pe\n", 1311 + dp->index, ERR_PTR(err)); 1313 1312 } 1314 1313 1315 - int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid) 1314 + int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast) 1316 1315 { 1317 1316 struct dsa_notifier_tag_8021q_vlan_info info = { 1318 1317 .tree_index = dp->ds->dst->index, ··· 1323 1318 .vid = vid, 1324 1319 }; 1325 1320 1326 - return dsa_broadcast(DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info); 1321 + if (broadcast) 1322 + return dsa_broadcast(DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info); 1323 + 1324 + return dsa_port_notify(dp, DSA_NOTIFIER_TAG_8021Q_VLAN_ADD, &info); 1327 1325 } 1328 1326 1329 - void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid) 1327 + void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast) 1330 1328 { 1331 1329 struct dsa_notifier_tag_8021q_vlan_info info = { 1332 1330 .tree_index = dp->ds->dst->index, ··· 1339 1331 }; 1340 1332 int err; 1341 1333 1342 - err = dsa_broadcast(DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info); 1334 + if (broadcast) 1335 + err = dsa_broadcast(DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info); 1336 + else 1337 + err = dsa_port_notify(dp, DSA_NOTIFIER_TAG_8021Q_VLAN_DEL, &info); 1343 1338 if (err) 1344 - pr_err("DSA: failed to notify tag_8021q VLAN deletion: %pe\n", 1345 - ERR_PTR(err)); 1339 + dev_err(dp->ds->dev, 1340 + "port %d failed to notify tag_8021q VLAN %d deletion: %pe\n", 1341 + dp->index, vid, ERR_PTR(err)); 1346 1342 }
+11 -10
net/dsa/tag_8021q.c
··· 362 362 continue; 363 363 364 364 /* Install the RX VID of the targeted port in our VLAN table */ 365 - err = dsa_port_tag_8021q_vlan_add(dp, targeted_rx_vid); 365 + err = dsa_port_tag_8021q_vlan_add(dp, targeted_rx_vid, false); 366 366 if (err) 367 367 return err; 368 368 369 369 /* Install our RX VID into the targeted port's VLAN table */ 370 - err = dsa_port_tag_8021q_vlan_add(targeted_dp, rx_vid); 370 + err = dsa_port_tag_8021q_vlan_add(targeted_dp, rx_vid, false); 371 371 if (err) 372 372 return err; 373 373 } ··· 398 398 continue; 399 399 400 400 /* Remove the RX VID of the targeted port from our VLAN table */ 401 - dsa_port_tag_8021q_vlan_del(dp, targeted_rx_vid); 401 + dsa_port_tag_8021q_vlan_del(dp, targeted_rx_vid, true); 402 402 403 403 /* Remove our RX VID from the targeted port's VLAN table */ 404 - dsa_port_tag_8021q_vlan_del(targeted_dp, rx_vid); 404 + dsa_port_tag_8021q_vlan_del(targeted_dp, rx_vid, true); 405 405 } 406 406 407 407 return 0; ··· 413 413 { 414 414 u16 tx_vid = dsa_8021q_bridge_tx_fwd_offload_vid(bridge_num); 415 415 416 - return dsa_port_tag_8021q_vlan_add(dsa_to_port(ds, port), tx_vid); 416 + return dsa_port_tag_8021q_vlan_add(dsa_to_port(ds, port), tx_vid, 417 + true); 417 418 } 418 419 EXPORT_SYMBOL_GPL(dsa_tag_8021q_bridge_tx_fwd_offload); 419 420 ··· 424 423 { 425 424 u16 tx_vid = dsa_8021q_bridge_tx_fwd_offload_vid(bridge_num); 426 425 427 - dsa_port_tag_8021q_vlan_del(dsa_to_port(ds, port), tx_vid); 426 + dsa_port_tag_8021q_vlan_del(dsa_to_port(ds, port), tx_vid, true); 428 427 } 429 428 EXPORT_SYMBOL_GPL(dsa_tag_8021q_bridge_tx_fwd_unoffload); 430 429 ··· 451 450 * L2 forwarding rules still take precedence when there are no VLAN 452 451 * restrictions, so there are no concerns about leaking traffic. 453 452 */ 454 - err = dsa_port_tag_8021q_vlan_add(dp, rx_vid); 453 + err = dsa_port_tag_8021q_vlan_add(dp, rx_vid, true); 455 454 if (err) { 456 455 dev_err(ds->dev, 457 456 "Failed to apply RX VID %d to port %d: %pe\n", ··· 463 462 vlan_vid_add(master, ctx->proto, rx_vid); 464 463 465 464 /* Finally apply the TX VID on this port and on the CPU port */ 466 - err = dsa_port_tag_8021q_vlan_add(dp, tx_vid); 465 + err = dsa_port_tag_8021q_vlan_add(dp, tx_vid, true); 467 466 if (err) { 468 467 dev_err(ds->dev, 469 468 "Failed to apply TX VID %d on port %d: %pe\n", ··· 490 489 491 490 master = dp->cpu_dp->master; 492 491 493 - dsa_port_tag_8021q_vlan_del(dp, rx_vid); 492 + dsa_port_tag_8021q_vlan_del(dp, rx_vid, false); 494 493 495 494 vlan_vid_del(master, ctx->proto, rx_vid); 496 495 497 - dsa_port_tag_8021q_vlan_del(dp, tx_vid); 496 + dsa_port_tag_8021q_vlan_del(dp, tx_vid, false); 498 497 } 499 498 500 499 static int dsa_tag_8021q_setup(struct dsa_switch *ds)