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

net: dsa: mv88e6xxx: remove bridge work

Now that the bridge code defers the switchdev port state setting, there
is no need to defer the port STP state change within the mv88e6xxx code.
Thus get rid of the driver's bridge work code.

This also fixes a race condition where the DSA layer assumes that the
bridge code already set the unbridged port's STP state to Disabled
before restoring the Forwarding state.

As a consequence, this also fixes the FDB flush for the unbridged port
which now correctly occurs during the Forwarding to Disabled transition.

Fixes: 0bc05d585d38 ("switchdev: allow caller to explicitly request attr_set as deferred")
Reported-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Vivien Didelot and committed by
David S. Miller
553eb544 b0e95ccd

+8 -34
+8 -29
drivers/net/dsa/mv88e6xxx.c
··· 1373 1373 { 1374 1374 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 1375 1375 int stp_state; 1376 + int err; 1376 1377 1377 1378 if (!mv88e6xxx_has(ps, MV88E6XXX_FLAG_PORTSTATE)) 1378 1379 return; ··· 1395 1394 break; 1396 1395 } 1397 1396 1398 - /* mv88e6xxx_port_stp_state_set may be called with softirqs disabled, 1399 - * so we can not update the port state directly but need to schedule it. 1400 - */ 1401 - ps->ports[port].state = stp_state; 1402 - set_bit(port, ps->port_state_update_mask); 1403 - schedule_work(&ps->bridge_work); 1397 + mutex_lock(&ps->smi_mutex); 1398 + err = _mv88e6xxx_port_state(ps, port, stp_state); 1399 + mutex_unlock(&ps->smi_mutex); 1400 + 1401 + if (err) 1402 + netdev_err(ds->ports[port], "failed to update state to %s\n", 1403 + mv88e6xxx_port_state_names[stp_state]); 1404 1404 } 1405 1405 1406 1406 static int _mv88e6xxx_port_pvid(struct mv88e6xxx_priv_state *ps, int port, ··· 2537 2535 mutex_unlock(&ps->smi_mutex); 2538 2536 } 2539 2537 2540 - static void mv88e6xxx_bridge_work(struct work_struct *work) 2541 - { 2542 - struct mv88e6xxx_priv_state *ps; 2543 - struct dsa_switch *ds; 2544 - int port; 2545 - 2546 - ps = container_of(work, struct mv88e6xxx_priv_state, bridge_work); 2547 - ds = ps->ds; 2548 - 2549 - mutex_lock(&ps->smi_mutex); 2550 - 2551 - for (port = 0; port < ps->info->num_ports; ++port) 2552 - if (test_and_clear_bit(port, ps->port_state_update_mask) && 2553 - _mv88e6xxx_port_state(ps, port, ps->ports[port].state)) 2554 - netdev_warn(ds->ports[port], 2555 - "failed to update state to %s\n", 2556 - mv88e6xxx_port_state_names[ps->ports[port].state]); 2557 - 2558 - mutex_unlock(&ps->smi_mutex); 2559 - } 2560 - 2561 2538 static int _mv88e6xxx_phy_page_write(struct mv88e6xxx_priv_state *ps, 2562 2539 int port, int page, int reg, int val) 2563 2540 { ··· 3125 3144 int i; 3126 3145 3127 3146 ps->ds = ds; 3128 - 3129 - INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); 3130 3147 3131 3148 if (mv88e6xxx_has(ps, MV88E6XXX_FLAG_EEPROM)) 3132 3149 mutex_init(&ps->eeprom_mutex);
-5
drivers/net/dsa/mv88e6xxx.h
··· 543 543 544 544 struct mv88e6xxx_priv_port { 545 545 struct net_device *bridge_dev; 546 - u8 state; 547 546 }; 548 547 549 548 struct mv88e6xxx_priv_state { ··· 591 592 struct mutex eeprom_mutex; 592 593 593 594 struct mv88e6xxx_priv_port ports[DSA_MAX_PORTS]; 594 - 595 - DECLARE_BITMAP(port_state_update_mask, DSA_MAX_PORTS); 596 - 597 - struct work_struct bridge_work; 598 595 599 596 /* A switch may have a GPIO line tied to its reset pin. Parse 600 597 * this from the device tree, and use it before performing