Skip to content

Commit

Permalink
net: fec: use reinit_completion() in mdio accessor functions
Browse files Browse the repository at this point in the history
Rather than re-initialising the entire completion on every mdio access,
use reinit_completion() which only resets the completion count.  This
avoids possible reinitialisation of the contained spinlock and waitqueue
while they may be in use (eg, mid-completion.)

Such an event could occur if there's a long delay in interrupt handling
causing the mdio accessor to time out, then a second access comes in
while the interrupt handler on a different CPU has called complete().
Another scenario where this has been observed is while locking has
been missing at the phy layer, allowing concurrent attempts to access
the MDIO bus.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Russell King authored and David S. Miller committed Aug 25, 2015
1 parent 05a7f58 commit aac27c7
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions drivers/net/ethernet/freescale/fec_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1778,7 +1778,7 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
return ret;

fep->mii_timeout = 0;
init_completion(&fep->mdio_done);
reinit_completion(&fep->mdio_done);

/* start a read op */
writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
Expand Down Expand Up @@ -1817,7 +1817,7 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
return ret;

fep->mii_timeout = 0;
init_completion(&fep->mdio_done);
reinit_completion(&fep->mdio_done);

/* start a write op */
writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE |
Expand Down

0 comments on commit aac27c7

Please sign in to comment.