Skip to content

Commit ca9ab07

Browse files
HoratiuVulturopsiff
authored andcommitted
phy: mscc: Stop taking ts_lock for tx_queue and use its own lock
[ Upstream commit 9b2bfdbf43adb9929c5ddcdd96efedbf1c88cf53 ] 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 deepin-community#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 deepin-community#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 0000000 0000000 0004b47a 0000003a 00000000 5fc0: 00000001 0000000 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. Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Fixes: 7d272e6 ("net: phy: mscc: timestamping and PHC support") Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> Link: https://patch.msgid.link/20250902121259.3257536-1-horatiu.vultur@microchip.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org> (cherry picked from commit a4e366fbec8a5854451e971e89ea8e1b3c5530bc)
1 parent b375815 commit ca9ab07

File tree

1 file changed

+8
-10
lines changed

1 file changed

+8
-10
lines changed

drivers/net/phy/mscc/mscc_ptp.c

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -455,12 +455,12 @@ static void vsc85xx_dequeue_skb(struct vsc85xx_ptp *ptp)
455455
*p++ = (reg >> 24) & 0xff;
456456
}
457457

458-
len = skb_queue_len(&ptp->tx_queue);
458+
len = skb_queue_len_lockless(&ptp->tx_queue);
459459
if (len < 1)
460460
return;
461461

462462
while (len--) {
463-
skb = __skb_dequeue(&ptp->tx_queue);
463+
skb = skb_dequeue(&ptp->tx_queue);
464464
if (!skb)
465465
return;
466466

@@ -485,7 +485,7 @@ static void vsc85xx_dequeue_skb(struct vsc85xx_ptp *ptp)
485485
* packet in the FIFO right now, reschedule it for later
486486
* packets.
487487
*/
488-
__skb_queue_tail(&ptp->tx_queue, skb);
488+
skb_queue_tail(&ptp->tx_queue, skb);
489489
}
490490
}
491491

@@ -1067,6 +1067,7 @@ static int vsc85xx_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr)
10671067
case HWTSTAMP_TX_ON:
10681068
break;
10691069
case HWTSTAMP_TX_OFF:
1070+
skb_queue_purge(&vsc8531->ptp->tx_queue);
10701071
break;
10711072
default:
10721073
return -ERANGE;
@@ -1091,9 +1092,6 @@ static int vsc85xx_hwtstamp(struct mii_timestamper *mii_ts, struct ifreq *ifr)
10911092

10921093
mutex_lock(&vsc8531->ts_lock);
10931094

1094-
__skb_queue_purge(&vsc8531->ptp->tx_queue);
1095-
__skb_queue_head_init(&vsc8531->ptp->tx_queue);
1096-
10971095
/* Disable predictor while configuring the 1588 block */
10981096
val = vsc85xx_ts_read_csr(phydev, PROCESSOR,
10991097
MSCC_PHY_PTP_INGR_PREDICTOR);
@@ -1179,9 +1177,7 @@ static void vsc85xx_txtstamp(struct mii_timestamper *mii_ts,
11791177

11801178
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
11811179

1182-
mutex_lock(&vsc8531->ts_lock);
1183-
__skb_queue_tail(&vsc8531->ptp->tx_queue, skb);
1184-
mutex_unlock(&vsc8531->ts_lock);
1180+
skb_queue_tail(&vsc8531->ptp->tx_queue, skb);
11851181
return;
11861182

11871183
out:
@@ -1547,6 +1543,7 @@ void vsc8584_ptp_deinit(struct phy_device *phydev)
15471543
if (vsc8531->ptp->ptp_clock) {
15481544
ptp_clock_unregister(vsc8531->ptp->ptp_clock);
15491545
skb_queue_purge(&vsc8531->rx_skbs_list);
1546+
skb_queue_purge(&vsc8531->ptp->tx_queue);
15501547
}
15511548
}
15521549

@@ -1570,7 +1567,7 @@ irqreturn_t vsc8584_handle_ts_interrupt(struct phy_device *phydev)
15701567
if (rc & VSC85XX_1588_INT_FIFO_ADD) {
15711568
vsc85xx_get_tx_ts(priv->ptp);
15721569
} else if (rc & VSC85XX_1588_INT_FIFO_OVERFLOW) {
1573-
__skb_queue_purge(&priv->ptp->tx_queue);
1570+
skb_queue_purge(&priv->ptp->tx_queue);
15741571
vsc85xx_ts_reset_fifo(phydev);
15751572
}
15761573

@@ -1590,6 +1587,7 @@ int vsc8584_ptp_probe(struct phy_device *phydev)
15901587
mutex_init(&vsc8531->phc_lock);
15911588
mutex_init(&vsc8531->ts_lock);
15921589
skb_queue_head_init(&vsc8531->rx_skbs_list);
1590+
skb_queue_head_init(&vsc8531->ptp->tx_queue);
15931591

15941592
/* Retrieve the shared load/save GPIO. Request it as non exclusive as
15951593
* the same GPIO can be requested by all the PHYs of the same package.

0 commit comments

Comments
 (0)