drivers/net/phy/mscc/mscc_ptp.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
When transmitting a PTP frame which is timestamp using 2 step, the
following warning appears if CONFIG_PROVE_LOCKING is enabled:
=============================
[ BUG: Invalid wait context ]
6.17.0-rc1-00326-ge6160462704e #427 Not tainted
-----------------------------
ptp4l/119 is trying to lock:
c2a44ed4 (&vsc8531->ts_lock){+.+.}-{3:3}, at: vsc85xx_txtstamp+0x50/0xac
other info that might help us debug this:
context-{4:4}
4 locks held by ptp4l/119:
#0: c145f068 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x58/0x1440
#1: c29df974 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: __dev_queue_xmit+0x5c4/0x1440
#2: c2aaaad0 (_xmit_ETHER#2){+.-.}-{2:2}, at: sch_direct_xmit+0x108/0x350
#3: c2aac170 (&lan966x->tx_lock){+.-.}-{2:2}, at: lan966x_port_xmit+0xd0/0x350
stack backtrace:
CPU: 0 UID: 0 PID: 119 Comm: ptp4l Not tainted 6.17.0-rc1-00326-ge6160462704e #427 NONE
Hardware name: Generic DT based system
Call trace:
unwind_backtrace from show_stack+0x10/0x14
show_stack from dump_stack_lvl+0x7c/0xac
dump_stack_lvl from __lock_acquire+0x8e8/0x29dc
__lock_acquire from lock_acquire+0x108/0x38c
lock_acquire from __mutex_lock+0xb0/0xe78
__mutex_lock from mutex_lock_nested+0x1c/0x24
mutex_lock_nested from vsc85xx_txtstamp+0x50/0xac
vsc85xx_txtstamp from lan966x_fdma_xmit+0xd8/0x3a8
lan966x_fdma_xmit from lan966x_port_xmit+0x1bc/0x350
lan966x_port_xmit from dev_hard_start_xmit+0xc8/0x2c0
dev_hard_start_xmit from sch_direct_xmit+0x8c/0x350
sch_direct_xmit from __dev_queue_xmit+0x680/0x1440
__dev_queue_xmit from packet_sendmsg+0xfa4/0x1568
packet_sendmsg from __sys_sendto+0x110/0x19c
__sys_sendto from sys_send+0x18/0x20
sys_send from ret_fast_syscall+0x0/0x1c
Exception stack(0xf0b05fa8 to 0xf0b05ff0)
5fa0: 00000001 0000000e 0000000e 0004b47a 0000003a 00000000
5fc0: 00000001 0000000e 00000000 00000121 0004af58 00044874 00000000 00000000
5fe0: 00000001 bee9d420 00025a10 b6e75c7c
So, instead of using the ts_lock for tx_queue, use the spinlock that
skb_buff_head has.
Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support")
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
---
v1->v2:
- initialize tx_queue in ptp_probe
- purge the tx_queue when the driver is removed or when TX timestamping
is OFF
---
drivers/net/phy/mscc/mscc_ptp.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c
index 72847320cb652..e866a1d865f8b 100644
--- a/drivers/net/phy/mscc/mscc_ptp.c
+++ b/drivers/net/phy/mscc/mscc_ptp.c
@@ -461,7 +461,7 @@ static void vsc85xx_dequeue_skb(struct vsc85xx_ptp *ptp)
return;
while (len--) {
- skb = __skb_dequeue(&ptp->tx_queue);
+ skb = skb_dequeue(&ptp->tx_queue);
if (!skb)
return;
@@ -486,7 +486,7 @@ static void vsc85xx_dequeue_skb(struct vsc85xx_ptp *ptp)
* packet in the FIFO right now, reschedule it for later
* packets.
*/
- __skb_queue_tail(&ptp->tx_queue, skb);
+ skb_queue_tail(&ptp->tx_queue, skb);
}
}
@@ -1068,6 +1068,7 @@ static int vsc85xx_hwtstamp(struct mii_timestamper *mii_ts,
case HWTSTAMP_TX_ON:
break;
case HWTSTAMP_TX_OFF:
+ skb_queue_purge(&vsc8531->ptp->tx_queue);
break;
default:
return -ERANGE;
@@ -1092,9 +1093,6 @@ static int vsc85xx_hwtstamp(struct mii_timestamper *mii_ts,
mutex_lock(&vsc8531->ts_lock);
- __skb_queue_purge(&vsc8531->ptp->tx_queue);
- __skb_queue_head_init(&vsc8531->ptp->tx_queue);
-
/* Disable predictor while configuring the 1588 block */
val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
MSCC_PHY_PTP_INGR_PREDICTOR);
@@ -1180,9 +1178,7 @@ static void vsc85xx_txtstamp(struct mii_timestamper *mii_ts,
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
- mutex_lock(&vsc8531->ts_lock);
- __skb_queue_tail(&vsc8531->ptp->tx_queue, skb);
- mutex_unlock(&vsc8531->ts_lock);
+ skb_queue_tail(&vsc8531->ptp->tx_queue, skb);
return;
out:
@@ -1548,6 +1544,7 @@ void vsc8584_ptp_deinit(struct phy_device *phydev)
if (vsc8531->ptp->ptp_clock) {
ptp_clock_unregister(vsc8531->ptp->ptp_clock);
skb_queue_purge(&vsc8531->rx_skbs_list);
+ skb_queue_purge(&vsc8531->ptp->tx_queue);
}
}
@@ -1571,7 +1568,7 @@ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
if (rc & VSC85XX_1588_INT_FIFO_ADD) {
vsc85xx_get_tx_ts(priv->ptp);
} else if (rc & VSC85XX_1588_INT_FIFO_OVERFLOW) {
- __skb_queue_purge(&priv->ptp->tx_queue);
+ skb_queue_purge(&priv->ptp->tx_queue);
vsc85xx_ts_reset_fifo(phydev);
}
@@ -1591,6 +1588,7 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
mutex_init(&vsc8531->phc_lock);
mutex_init(&vsc8531->ts_lock);
skb_queue_head_init(&vsc8531->rx_skbs_list);
+ skb_queue_head_init(&vsc8531->ptp->tx_queue);
/* Retrieve the shared load/save GPIO. Request it as non exclusive as
* the same GPIO can be requested by all the PHYs of the same package.
--
2.34.1
On 01/09/2025 10:23, Horatiu Vultur wrote: > When transmitting a PTP frame which is timestamp using 2 step, the > following warning appears if CONFIG_PROVE_LOCKING is enabled: > ============================= > [ BUG: Invalid wait context ] > 6.17.0-rc1-00326-ge6160462704e #427 Not tainted > ----------------------------- > ptp4l/119 is trying to lock: > c2a44ed4 (&vsc8531->ts_lock){+.+.}-{3:3}, at: vsc85xx_txtstamp+0x50/0xac > other info that might help us debug this: > context-{4:4} > 4 locks held by ptp4l/119: > #0: c145f068 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x58/0x1440 > #1: c29df974 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: __dev_queue_xmit+0x5c4/0x1440 > #2: c2aaaad0 (_xmit_ETHER#2){+.-.}-{2:2}, at: sch_direct_xmit+0x108/0x350 > #3: c2aac170 (&lan966x->tx_lock){+.-.}-{2:2}, at: lan966x_port_xmit+0xd0/0x350 > stack backtrace: > CPU: 0 UID: 0 PID: 119 Comm: ptp4l Not tainted 6.17.0-rc1-00326-ge6160462704e #427 NONE > Hardware name: Generic DT based system > Call trace: > unwind_backtrace from show_stack+0x10/0x14 > show_stack from dump_stack_lvl+0x7c/0xac > dump_stack_lvl from __lock_acquire+0x8e8/0x29dc > __lock_acquire from lock_acquire+0x108/0x38c > lock_acquire from __mutex_lock+0xb0/0xe78 > __mutex_lock from mutex_lock_nested+0x1c/0x24 > mutex_lock_nested from vsc85xx_txtstamp+0x50/0xac > vsc85xx_txtstamp from lan966x_fdma_xmit+0xd8/0x3a8 > lan966x_fdma_xmit from lan966x_port_xmit+0x1bc/0x350 > lan966x_port_xmit from dev_hard_start_xmit+0xc8/0x2c0 > dev_hard_start_xmit from sch_direct_xmit+0x8c/0x350 > sch_direct_xmit from __dev_queue_xmit+0x680/0x1440 > __dev_queue_xmit from packet_sendmsg+0xfa4/0x1568 > packet_sendmsg from __sys_sendto+0x110/0x19c > __sys_sendto from sys_send+0x18/0x20 > sys_send from ret_fast_syscall+0x0/0x1c > Exception stack(0xf0b05fa8 to 0xf0b05ff0) > 5fa0: 00000001 0000000e 0000000e 0004b47a 0000003a 00000000 > 5fc0: 00000001 0000000e 00000000 00000121 0004af58 00044874 00000000 00000000 > 5fe0: 00000001 bee9d420 00025a10 b6e75c7c > > So, instead of using the ts_lock for tx_queue, use the spinlock that > skb_buff_head has. > > Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support") > Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> > > --- > v1->v2: > - initialize tx_queue in ptp_probe > - purge the tx_queue when the driver is removed or when TX timestamping > is OFF > --- > drivers/net/phy/mscc/mscc_ptp.c | 16 +++++++--------- > 1 file changed, 7 insertions(+), 9 deletions(-) > > diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c > index 72847320cb652..e866a1d865f8b 100644 > --- a/drivers/net/phy/mscc/mscc_ptp.c > +++ b/drivers/net/phy/mscc/mscc_ptp.c > @@ -461,7 +461,7 @@ static void vsc85xx_dequeue_skb(struct vsc85xx_ptp *ptp) > return; > > while (len--) { > - skb = __skb_dequeue(&ptp->tx_queue); > + skb = skb_dequeue(&ptp->tx_queue); Now as you switched to use spinlock of tx_queue, it is technically correct to change skb_queue_len(&ptp->tx_queue) to skb_queue_len_lockless(&ptp->tx_queue) a couple of lines above this chunk. Otherwise LGTM, once skb_queue_len fixed you can add Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Thanks! > if (!skb) > return; > > @@ -486,7 +486,7 @@ static void vsc85xx_dequeue_skb(struct vsc85xx_ptp *ptp) > * packet in the FIFO right now, reschedule it for later > * packets. > */ > - __skb_queue_tail(&ptp->tx_queue, skb); > + skb_queue_tail(&ptp->tx_queue, skb);
The 09/01/2025 11:19, Vadim Fedorenko wrote: Hi Vadim, > > On 01/09/2025 10:23, Horatiu Vultur wrote: > > When transmitting a PTP frame which is timestamp using 2 step, the > > following warning appears if CONFIG_PROVE_LOCKING is enabled: > > ============================= > > [ BUG: Invalid wait context ] > > 6.17.0-rc1-00326-ge6160462704e #427 Not tainted > > ----------------------------- > > ptp4l/119 is trying to lock: > > c2a44ed4 (&vsc8531->ts_lock){+.+.}-{3:3}, at: vsc85xx_txtstamp+0x50/0xac > > other info that might help us debug this: > > context-{4:4} > > 4 locks held by ptp4l/119: > > #0: c145f068 (rcu_read_lock_bh){....}-{1:2}, at: __dev_queue_xmit+0x58/0x1440 > > #1: c29df974 (dev->qdisc_tx_busylock ?: &qdisc_tx_busylock){+...}-{2:2}, at: __dev_queue_xmit+0x5c4/0x1440 > > #2: c2aaaad0 (_xmit_ETHER#2){+.-.}-{2:2}, at: sch_direct_xmit+0x108/0x350 > > #3: c2aac170 (&lan966x->tx_lock){+.-.}-{2:2}, at: lan966x_port_xmit+0xd0/0x350 > > stack backtrace: > > CPU: 0 UID: 0 PID: 119 Comm: ptp4l Not tainted 6.17.0-rc1-00326-ge6160462704e #427 NONE > > Hardware name: Generic DT based system > > Call trace: > > unwind_backtrace from show_stack+0x10/0x14 > > show_stack from dump_stack_lvl+0x7c/0xac > > dump_stack_lvl from __lock_acquire+0x8e8/0x29dc > > __lock_acquire from lock_acquire+0x108/0x38c > > lock_acquire from __mutex_lock+0xb0/0xe78 > > __mutex_lock from mutex_lock_nested+0x1c/0x24 > > mutex_lock_nested from vsc85xx_txtstamp+0x50/0xac > > vsc85xx_txtstamp from lan966x_fdma_xmit+0xd8/0x3a8 > > lan966x_fdma_xmit from lan966x_port_xmit+0x1bc/0x350 > > lan966x_port_xmit from dev_hard_start_xmit+0xc8/0x2c0 > > dev_hard_start_xmit from sch_direct_xmit+0x8c/0x350 > > sch_direct_xmit from __dev_queue_xmit+0x680/0x1440 > > __dev_queue_xmit from packet_sendmsg+0xfa4/0x1568 > > packet_sendmsg from __sys_sendto+0x110/0x19c > > __sys_sendto from sys_send+0x18/0x20 > > sys_send from ret_fast_syscall+0x0/0x1c > > Exception stack(0xf0b05fa8 to 0xf0b05ff0) > > 5fa0: 00000001 0000000e 0000000e 0004b47a 0000003a 00000000 > > 5fc0: 00000001 0000000e 00000000 00000121 0004af58 00044874 00000000 00000000 > > 5fe0: 00000001 bee9d420 00025a10 b6e75c7c > > > > So, instead of using the ts_lock for tx_queue, use the spinlock that > > skb_buff_head has. > > > > Fixes: 7d272e63e0979d ("net: phy: mscc: timestamping and PHC support") > > Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> > > > > --- > > v1->v2: > > - initialize tx_queue in ptp_probe > > - purge the tx_queue when the driver is removed or when TX timestamping > > is OFF > > --- > > drivers/net/phy/mscc/mscc_ptp.c | 16 +++++++--------- > > 1 file changed, 7 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c > > index 72847320cb652..e866a1d865f8b 100644 > > --- a/drivers/net/phy/mscc/mscc_ptp.c > > +++ b/drivers/net/phy/mscc/mscc_ptp.c > > @@ -461,7 +461,7 @@ static void vsc85xx_dequeue_skb(struct vsc85xx_ptp *ptp) > > return; > > > > while (len--) { > > - skb = __skb_dequeue(&ptp->tx_queue); > > + skb = skb_dequeue(&ptp->tx_queue); > > Now as you switched to use spinlock of tx_queue, it is technically > correct to change skb_queue_len(&ptp->tx_queue) to > skb_queue_len_lockless(&ptp->tx_queue) a couple of lines above this > chunk. I will update this in the next version. Thanks! > > Otherwise LGTM, once skb_queue_len fixed you can add > > Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> > > > Thanks! > > > if (!skb) > > return; > > > > @@ -486,7 +486,7 @@ static void vsc85xx_dequeue_skb(struct vsc85xx_ptp *ptp) > > * packet in the FIFO right now, reschedule it for later > > * packets. > > */ > > - __skb_queue_tail(&ptp->tx_queue, skb); > > + skb_queue_tail(&ptp->tx_queue, skb); > -- /Horatiu
© 2016 - 2025 Red Hat, Inc.