* [PATCH net 1/2] net: dsa: mv88e6xxx: Fix interrupt masking on removal
2017-12-07 0:05 [PATCH net 0/2] mv88e6xxx error patch fixes Andrew Lunn
@ 2017-12-07 0:05 ` Andrew Lunn
2017-12-07 15:33 ` Vivien Didelot
2017-12-07 0:05 ` [PATCH net 2/2] net: dsa: mv88e6xxx: Unregister MDIO bus on error path Andrew Lunn
2017-12-07 18:53 ` [PATCH net 0/2] mv88e6xxx error patch fixes David Miller
2 siblings, 1 reply; 6+ messages in thread
From: Andrew Lunn @ 2017-12-07 0:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Vivien Didelot, Andrew Lunn
When removing the interrupt handling code, we should mask the
generation of interrupts. The code however unmasked all
interrupts. This can then cause a new interrupt. We then get into a
deadlock where the interrupt thread is waiting to run, and the code
continues, trying to remove the interrupt handler, which means waiting
for the thread to complete. On a UP machine this deadlocks.
Fix so we really mask interrupts in the hardware. The same error is
made in the error path when install the interrupt handling code.
Fixes: 3460a5770ce9 ("net: dsa: mv88e6xxx: Mask g1 interrupts and free interrupt")
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 8171055fde7a..70004264f60d 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -339,7 +339,7 @@ static void mv88e6xxx_g1_irq_free(struct mv88e6xxx_chip *chip)
u16 mask;
mv88e6xxx_g1_read(chip, MV88E6XXX_G1_CTL1, &mask);
- mask |= GENMASK(chip->g1_irq.nirqs, 0);
+ mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
free_irq(chip->irq, chip);
@@ -395,7 +395,7 @@ static int mv88e6xxx_g1_irq_setup(struct mv88e6xxx_chip *chip)
return 0;
out_disable:
- mask |= GENMASK(chip->g1_irq.nirqs, 0);
+ mask &= ~GENMASK(chip->g1_irq.nirqs, 0);
mv88e6xxx_g1_write(chip, MV88E6XXX_G1_CTL1, mask);
out_mapping:
--
2.15.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH net 1/2] net: dsa: mv88e6xxx: Fix interrupt masking on removal
2017-12-07 0:05 ` [PATCH net 1/2] net: dsa: mv88e6xxx: Fix interrupt masking on removal Andrew Lunn
@ 2017-12-07 15:33 ` Vivien Didelot
0 siblings, 0 replies; 6+ messages in thread
From: Vivien Didelot @ 2017-12-07 15:33 UTC (permalink / raw)
To: Andrew Lunn, David Miller; +Cc: netdev, Andrew Lunn
Andrew Lunn <andrew@lunn.ch> writes:
> When removing the interrupt handling code, we should mask the
> generation of interrupts. The code however unmasked all
> interrupts. This can then cause a new interrupt. We then get into a
> deadlock where the interrupt thread is waiting to run, and the code
> continues, trying to remove the interrupt handler, which means waiting
> for the thread to complete. On a UP machine this deadlocks.
>
> Fix so we really mask interrupts in the hardware. The same error is
> made in the error path when install the interrupt handling code.
>
> Fixes: 3460a5770ce9 ("net: dsa: mv88e6xxx: Mask g1 interrupts and free interrupt")
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net 2/2] net: dsa: mv88e6xxx: Unregister MDIO bus on error path
2017-12-07 0:05 [PATCH net 0/2] mv88e6xxx error patch fixes Andrew Lunn
2017-12-07 0:05 ` [PATCH net 1/2] net: dsa: mv88e6xxx: Fix interrupt masking on removal Andrew Lunn
@ 2017-12-07 0:05 ` Andrew Lunn
2017-12-07 15:33 ` Vivien Didelot
2017-12-07 18:53 ` [PATCH net 0/2] mv88e6xxx error patch fixes David Miller
2 siblings, 1 reply; 6+ messages in thread
From: Andrew Lunn @ 2017-12-07 0:05 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Vivien Didelot, Andrew Lunn
The MDIO busses need to be unregistered before they are freed,
otherwise BUG() is called. Add a call to the unregister code if the
registration fails, since we can have multiple busses, of which some
may correctly register before one fails. This requires moving the code
around a little.
Fixes: a3c53be55c95 ("net: dsa: mv88e6xxx: Support multiple MDIO busses")
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 30 ++++++++++++++++--------------
1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 70004264f60d..66d33e97cbc5 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2177,6 +2177,19 @@ static const struct of_device_id mv88e6xxx_mdio_external_match[] = {
{ },
};
+static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
+
+{
+ struct mv88e6xxx_mdio_bus *mdio_bus;
+ struct mii_bus *bus;
+
+ list_for_each_entry(mdio_bus, &chip->mdios, list) {
+ bus = mdio_bus->bus;
+
+ mdiobus_unregister(bus);
+ }
+}
+
static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
struct device_node *np)
{
@@ -2201,27 +2214,16 @@ static int mv88e6xxx_mdios_register(struct mv88e6xxx_chip *chip,
match = of_match_node(mv88e6xxx_mdio_external_match, child);
if (match) {
err = mv88e6xxx_mdio_register(chip, child, true);
- if (err)
+ if (err) {
+ mv88e6xxx_mdios_unregister(chip);
return err;
+ }
}
}
return 0;
}
-static void mv88e6xxx_mdios_unregister(struct mv88e6xxx_chip *chip)
-
-{
- struct mv88e6xxx_mdio_bus *mdio_bus;
- struct mii_bus *bus;
-
- list_for_each_entry(mdio_bus, &chip->mdios, list) {
- bus = mdio_bus->bus;
-
- mdiobus_unregister(bus);
- }
-}
-
static int mv88e6xxx_get_eeprom_len(struct dsa_switch *ds)
{
struct mv88e6xxx_chip *chip = ds->priv;
--
2.15.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH net 2/2] net: dsa: mv88e6xxx: Unregister MDIO bus on error path
2017-12-07 0:05 ` [PATCH net 2/2] net: dsa: mv88e6xxx: Unregister MDIO bus on error path Andrew Lunn
@ 2017-12-07 15:33 ` Vivien Didelot
0 siblings, 0 replies; 6+ messages in thread
From: Vivien Didelot @ 2017-12-07 15:33 UTC (permalink / raw)
To: Andrew Lunn, David Miller; +Cc: netdev, Andrew Lunn
Andrew Lunn <andrew@lunn.ch> writes:
> The MDIO busses need to be unregistered before they are freed,
> otherwise BUG() is called. Add a call to the unregister code if the
> registration fails, since we can have multiple busses, of which some
> may correctly register before one fails. This requires moving the code
> around a little.
>
> Fixes: a3c53be55c95 ("net: dsa: mv88e6xxx: Support multiple MDIO busses")
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net 0/2] mv88e6xxx error patch fixes
2017-12-07 0:05 [PATCH net 0/2] mv88e6xxx error patch fixes Andrew Lunn
2017-12-07 0:05 ` [PATCH net 1/2] net: dsa: mv88e6xxx: Fix interrupt masking on removal Andrew Lunn
2017-12-07 0:05 ` [PATCH net 2/2] net: dsa: mv88e6xxx: Unregister MDIO bus on error path Andrew Lunn
@ 2017-12-07 18:53 ` David Miller
2 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2017-12-07 18:53 UTC (permalink / raw)
To: andrew; +Cc: netdev, vivien.didelot
From: Andrew Lunn <andrew@lunn.ch>
Date: Thu, 7 Dec 2017 01:05:55 +0100
> While trying to bring up a new PHY on a board, i exercised the error
> paths a bit, and discovered some bugs. The unwind for interrupt
> handling deadlocks, and the MDIO code hits a BUG() when a registered
> MDIO device is freed without first being unregistered.
Series applied, thanks Andrew.
^ permalink raw reply [flat|nested] 6+ messages in thread