mirror of https://gitee.com/openkylin/linux.git
stmmac: fix concurrency in eee initialization.
This patch aims to fix the concurrency in eee initialization inside the stmmac driver and related warnings when enable DEBUG_ATOMIC_SLEEP. Prior this patch, the stmmac_eee_init could be called in several places as shown below: stmmac_open stmmac_resume PHY Layer | | | stmmac_hw_setup stmmac_adjust_link | | stmmac ethtool |__________________________|______________| | stmmac_eee_init The patch removes the stmmac_eee_init call inside the stmmac_hw_setup that is unnecessary. It is sufficient to call it in the adjust_link to always guarantee that EEE is always configured at mac level too. Fixing the lock protection now it is covered another case (not considered before). The stmmac_eee_init could be called by the ethtool so critical sections must be protected inside this function too. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b9d73704aa
commit
4741cf9cec
|
@ -276,6 +276,7 @@ static void stmmac_eee_ctrl_timer(unsigned long arg)
|
||||||
bool stmmac_eee_init(struct stmmac_priv *priv)
|
bool stmmac_eee_init(struct stmmac_priv *priv)
|
||||||
{
|
{
|
||||||
char *phy_bus_name = priv->plat->phy_bus_name;
|
char *phy_bus_name = priv->plat->phy_bus_name;
|
||||||
|
unsigned long flags;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
/* Using PCS we cannot dial with the phy registers at this stage
|
/* Using PCS we cannot dial with the phy registers at this stage
|
||||||
|
@ -300,6 +301,7 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
|
||||||
* changed).
|
* changed).
|
||||||
* In that case the driver disable own timers.
|
* In that case the driver disable own timers.
|
||||||
*/
|
*/
|
||||||
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
if (priv->eee_active) {
|
if (priv->eee_active) {
|
||||||
pr_debug("stmmac: disable EEE\n");
|
pr_debug("stmmac: disable EEE\n");
|
||||||
del_timer_sync(&priv->eee_ctrl_timer);
|
del_timer_sync(&priv->eee_ctrl_timer);
|
||||||
|
@ -307,9 +309,11 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
|
||||||
tx_lpi_timer);
|
tx_lpi_timer);
|
||||||
}
|
}
|
||||||
priv->eee_active = 0;
|
priv->eee_active = 0;
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* Activate the EEE and start timers */
|
/* Activate the EEE and start timers */
|
||||||
|
spin_lock_irqsave(&priv->lock, flags);
|
||||||
if (!priv->eee_active) {
|
if (!priv->eee_active) {
|
||||||
priv->eee_active = 1;
|
priv->eee_active = 1;
|
||||||
init_timer(&priv->eee_ctrl_timer);
|
init_timer(&priv->eee_ctrl_timer);
|
||||||
|
@ -325,9 +329,10 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
|
||||||
/* Set HW EEE according to the speed */
|
/* Set HW EEE according to the speed */
|
||||||
priv->hw->mac->set_eee_pls(priv->hw, priv->phydev->link);
|
priv->hw->mac->set_eee_pls(priv->hw, priv->phydev->link);
|
||||||
|
|
||||||
pr_debug("stmmac: Energy-Efficient Ethernet initialized\n");
|
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
|
pr_debug("stmmac: Energy-Efficient Ethernet initialized\n");
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -760,12 +765,12 @@ static void stmmac_adjust_link(struct net_device *dev)
|
||||||
if (new_state && netif_msg_link(priv))
|
if (new_state && netif_msg_link(priv))
|
||||||
phy_print_status(phydev);
|
phy_print_status(phydev);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&priv->lock, flags);
|
||||||
|
|
||||||
/* At this stage, it could be needed to setup the EEE or adjust some
|
/* At this stage, it could be needed to setup the EEE or adjust some
|
||||||
* MAC related HW registers.
|
* MAC related HW registers.
|
||||||
*/
|
*/
|
||||||
priv->eee_enabled = stmmac_eee_init(priv);
|
priv->eee_enabled = stmmac_eee_init(priv);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&priv->lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1705,8 +1710,6 @@ static int stmmac_hw_setup(struct net_device *dev)
|
||||||
}
|
}
|
||||||
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
|
priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS;
|
||||||
|
|
||||||
priv->eee_enabled = stmmac_eee_init(priv);
|
|
||||||
|
|
||||||
stmmac_init_tx_coalesce(priv);
|
stmmac_init_tx_coalesce(priv);
|
||||||
|
|
||||||
if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
|
if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) {
|
||||||
|
|
Loading…
Reference in New Issue