Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61c4c0bc authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 39c13319 a2004907
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -553,7 +553,7 @@ int phy_start_aneg(struct phy_device *phydev)
	if (err < 0)
		goto out_unlock;

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

	mutex_lock(&phydev->lock);
	if (__phy_is_started(phydev))
	if (phy_is_started(phydev))
		phydev->state = PHY_UP;
	mutex_unlock(&phydev->lock);
}
@@ -839,15 +839,14 @@ EXPORT_SYMBOL(phy_stop_interrupts);
 */
void phy_stop(struct phy_device *phydev)
{
	mutex_lock(&phydev->lock);

	if (!__phy_is_started(phydev)) {
	if (!phy_is_started(phydev)) {
		WARN(1, "called from state %s\n",
		     phy_state_to_str(phydev->state));
		mutex_unlock(&phydev->lock);
		return;
	}

	mutex_lock(&phydev->lock);

	if (phy_interrupt_is_valid(phydev))
		phy_disable_interrupts(phydev);

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

/**
+1 −14
Original line number Diff line number Diff line
@@ -674,26 +674,13 @@ phy_lookup_setting(int speed, int duplex, const unsigned long *mask,
size_t phy_speeds(unsigned int *speeds, size_t size,
		  unsigned long *mask);

static inline bool __phy_is_started(struct phy_device *phydev)
{
	WARN_ON(!mutex_is_locked(&phydev->lock));

	return phydev->state >= PHY_UP;
}

/**
 * phy_is_started - Convenience function to check whether PHY is started
 * @phydev: The phy_device struct
 */
static inline bool phy_is_started(struct phy_device *phydev)
{
	bool started;

	mutex_lock(&phydev->lock);
	started = __phy_is_started(phydev);
	mutex_unlock(&phydev->lock);

	return started;
	return phydev->state >= PHY_UP;
}

void phy_resolve_aneg_linkmode(struct phy_device *phydev);