Re: [PATCH] Use a spinlock to guard `fep->ptp_clk_on`
From: Andrew Lunn <andrew@lunn.ch>
Date: 2022-08-31 14:04:07
On Wed, Aug 31, 2022 at 02:56:31PM +0200, Csókás Bence wrote:
quoted hunk ↗ jump to hunk
Mutexes cannot be taken in a non-preemptible context, causing a panic in `fec_ptp_save_state()`. Replacing `ptp_clk_mutex` by `ptp_clk_lock` fixes this. Fixes: 91c0d987a9788dcc5fe26baafd73bf9242b68900 Fixes: 6a4d7234ae9a3bb31181f348ade9bbdb55aeb5c5 Fixes: f79959220fa5fbda939592bf91c7a9ea90419040 Reported-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Csókás Bence <redacted> --- drivers/net/ethernet/freescale/fec.h | 2 +- drivers/net/ethernet/freescale/fec_main.c | 17 ++++++------ drivers/net/ethernet/freescale/fec_ptp.c | 32 +++++++++++------------ 3 files changed, 26 insertions(+), 25 deletions(-)diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 0cebe4b63adb..9aac74d14f26 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h@@ -557,7 +557,7 @@ struct fec_enet_private { struct clk *clk_2x_txclk; bool ptp_clk_on; - struct mutex ptp_clk_mutex; + spinlock_t ptp_clk_lock; unsigned int num_tx_queues; unsigned int num_rx_queues;diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index b0d60f898249..98d8f8d6034e 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c@@ -2029,6 +2029,7 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable) { struct fec_enet_private *fep = netdev_priv(ndev); int ret; + unsigned long flags;
Please keep to reverse christmas tree
quoted hunk ↗ jump to hunk
if (enable) { ret = clk_prepare_enable(fep->clk_enet_out);@@ -2036,15 +2037,15 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable) return ret; if (fep->clk_ptp) { - mutex_lock(&fep->ptp_clk_mutex); + spin_lock_irqsave(&fep->ptp_clk_lock, flags);
Is the ptp hardware accessed in interrupt context? If not, you can use
a plain spinlock, not _irqsave..
Looking at fec_enet_interrupt() and fec_enet_collect_events() i do not
see anything.
Andrew