Skip to content

Commit 61c4c0b

Browse files
committed
Merge branch 'net-phy-fix-locking-issue'
Heiner Kallweit says: ==================== net: phy: fix locking issue Russell pointed out that the locking used in phy_is_started() isn't needed and misleading. This locking also contributes to a race fixed with patch 2. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 39c1331 + a200490 commit 61c4c0b

File tree

2 files changed

+8
-20
lines changed

2 files changed

+8
-20
lines changed

drivers/net/phy/phy.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ int phy_start_aneg(struct phy_device *phydev)
553553
if (err < 0)
554554
goto out_unlock;
555555

556-
if (__phy_is_started(phydev)) {
556+
if (phy_is_started(phydev)) {
557557
if (phydev->autoneg == AUTONEG_ENABLE) {
558558
err = phy_check_link_status(phydev);
559559
} else {
@@ -709,7 +709,7 @@ void phy_stop_machine(struct phy_device *phydev)
709709
cancel_delayed_work_sync(&phydev->state_queue);
710710

711711
mutex_lock(&phydev->lock);
712-
if (__phy_is_started(phydev))
712+
if (phy_is_started(phydev))
713713
phydev->state = PHY_UP;
714714
mutex_unlock(&phydev->lock);
715715
}
@@ -839,15 +839,14 @@ EXPORT_SYMBOL(phy_stop_interrupts);
839839
*/
840840
void phy_stop(struct phy_device *phydev)
841841
{
842-
mutex_lock(&phydev->lock);
843-
844-
if (!__phy_is_started(phydev)) {
842+
if (!phy_is_started(phydev)) {
845843
WARN(1, "called from state %s\n",
846844
phy_state_to_str(phydev->state));
847-
mutex_unlock(&phydev->lock);
848845
return;
849846
}
850847

848+
mutex_lock(&phydev->lock);
849+
851850
if (phy_interrupt_is_valid(phydev))
852851
phy_disable_interrupts(phydev);
853852

@@ -986,8 +985,10 @@ void phy_state_machine(struct work_struct *work)
986985
* state machine would be pointless and possibly error prone when
987986
* called from phy_disconnect() synchronously.
988987
*/
988+
mutex_lock(&phydev->lock);
989989
if (phy_polling_mode(phydev) && phy_is_started(phydev))
990990
phy_queue_state_machine(phydev, PHY_STATE_TIME);
991+
mutex_unlock(&phydev->lock);
991992
}
992993

993994
/**

include/linux/phy.h

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -674,26 +674,13 @@ phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
674674
size_t phy_speeds(unsigned int *speeds, size_t size,
675675
unsigned long *mask);
676676

677-
static inline bool __phy_is_started(struct phy_device *phydev)
678-
{
679-
WARN_ON(!mutex_is_locked(&phydev->lock));
680-
681-
return phydev->state >= PHY_UP;
682-
}
683-
684677
/**
685678
* phy_is_started - Convenience function to check whether PHY is started
686679
* @phydev: The phy_device struct
687680
*/
688681
static inline bool phy_is_started(struct phy_device *phydev)
689682
{
690-
bool started;
691-
692-
mutex_lock(&phydev->lock);
693-
started = __phy_is_started(phydev);
694-
mutex_unlock(&phydev->lock);
695-
696-
return started;
683+
return phydev->state >= PHY_UP;
697684
}
698685

699686
void phy_resolve_aneg_linkmode(struct phy_device *phydev);

0 commit comments

Comments
 (0)