Skip to content

Commit

Permalink
net: mdio: Fix lockdep falls positive splat
Browse files Browse the repository at this point in the history
MDIO devices can be stacked upon each other. The current code supports
two levels, which until recently has been enough for a DSA mdio bus on
top of another bus. Now we have hardware which has an MDIO mux in the
middle.

Define an MDIO MUTEX class with three levels.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Andrew Lunn authored and David S. Miller committed Apr 12, 2016
1 parent 7c3da7d commit 9a6f2b0
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 10 deletions.
10 changes: 2 additions & 8 deletions drivers/net/phy/mdio-mux.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,7 @@ static int mdio_mux_read(struct mii_bus *bus, int phy_id, int regnum)
struct mdio_mux_parent_bus *pb = cb->parent;
int r;

/* In theory multiple mdio_mux could be stacked, thus creating
* more than a single level of nesting. But in practice,
* SINGLE_DEPTH_NESTING will cover the vast majority of use
* cases. We use it, instead of trying to handle the general
* case.
*/
mutex_lock_nested(&pb->mii_bus->mdio_lock, SINGLE_DEPTH_NESTING);
mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX);
r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data);
if (r)
goto out;
Expand All @@ -76,7 +70,7 @@ static int mdio_mux_write(struct mii_bus *bus, int phy_id,

int r;

mutex_lock_nested(&pb->mii_bus->mdio_lock, SINGLE_DEPTH_NESTING);
mutex_lock_nested(&pb->mii_bus->mdio_lock, MDIO_MUTEX_MUX);
r = pb->switch_fn(pb->current_child, cb->bus_number, pb->switch_data);
if (r)
goto out;
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/phy/mdio_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ int mdiobus_read_nested(struct mii_bus *bus, int addr, u32 regnum)

BUG_ON(in_interrupt());

mutex_lock_nested(&bus->mdio_lock, SINGLE_DEPTH_NESTING);
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
retval = bus->read(bus, addr, regnum);
mutex_unlock(&bus->mdio_lock);

Expand Down Expand Up @@ -509,7 +509,7 @@ int mdiobus_write_nested(struct mii_bus *bus, int addr, u32 regnum, u16 val)

BUG_ON(in_interrupt());

mutex_lock_nested(&bus->mdio_lock, SINGLE_DEPTH_NESTING);
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
err = bus->write(bus, addr, regnum, val);
mutex_unlock(&bus->mdio_lock);

Expand Down
11 changes: 11 additions & 0 deletions include/linux/mdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@

struct mii_bus;

/* Multiple levels of nesting are possible. However typically this is
* limited to nested DSA like layer, a MUX layer, and the normal
* user. Instead of trying to handle the general case, just define
* these cases.
*/
enum mdio_mutex_lock_class {
MDIO_MUTEX_NORMAL,
MDIO_MUTEX_MUX,
MDIO_MUTEX_NESTED,
};

struct mdio_device {
struct device dev;

Expand Down

0 comments on commit 9a6f2b0

Please sign in to comment.