drivers/ptp/ptp_private.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
ABBA deadlock occurs in the following scenario:
CPU0 CPU1
---- ----
n_vclocks_store()
lock(&ptp->n_vclocks_mux) [1]
pc_clock_adjtime()
lock(&clk->rwsem) [2]
...
ptp_clock_freerun()
ptp_vclock_in_use()
lock(&ptp->n_vclocks_mux) [3]
ptp_clock_unregister()
posix_clock_unregister()
lock(&clk->rwsem) [4]
To solve this with minimal patches, we should change ptp_clock_freerun()
to briefly release the read lock before calling ptp_vclock_in_use() and
then re-lock it when we're done.
Reported-by: syzbot+7cfb66a237c4a5fb22ad@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=7cfb66a237c4a5fb22ad
Fixes: 73f37068d540 ("ptp: support ptp physical/virtual clocks conversion")
Signed-off-by: Jeongjun Park <aha310510@gmail.com>
---
drivers/ptp/ptp_private.h | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h
index a6aad743c282..e2c37e968c88 100644
--- a/drivers/ptp/ptp_private.h
+++ b/drivers/ptp/ptp_private.h
@@ -124,10 +124,16 @@ static inline bool ptp_vclock_in_use(struct ptp_clock *ptp)
/* Check if ptp clock shall be free running */
static inline bool ptp_clock_freerun(struct ptp_clock *ptp)
{
+ bool ret = false;
+
if (ptp->has_cycles)
- return false;
+ return ret;
+
+ up_read(&ptp->clock.rwsem);
+ ret = ptp_vclock_in_use(ptp);
+ down_read(&ptp->clock.rwsem);
- return ptp_vclock_in_use(ptp);
+ return ret;
}
extern const struct class ptp_class;
--
On Sat, 5 Jul 2025 23:50:31 +0900 Jeongjun Park wrote: > ABBA deadlock occurs in the following scenario: > > CPU0 CPU1 > ---- ---- > n_vclocks_store() > lock(&ptp->n_vclocks_mux) [1] > pc_clock_adjtime() > lock(&clk->rwsem) [2] > ... > ptp_clock_freerun() > ptp_vclock_in_use() > lock(&ptp->n_vclocks_mux) [3] > ptp_clock_unregister() > posix_clock_unregister() > lock(&clk->rwsem) [4] > > To solve this with minimal patches, we should change ptp_clock_freerun() > to briefly release the read lock before calling ptp_vclock_in_use() and > then re-lock it when we're done. Dropping locks randomly is very rarely the correct fix. Either way - you forgot to CC Vladimir, again. -- pw-bot: cr
Hello, Jakub Kicinski <kuba@kernel.org> wrote: > > On Sat, 5 Jul 2025 23:50:31 +0900 Jeongjun Park wrote: > > ABBA deadlock occurs in the following scenario: > > > > CPU0 CPU1 > > ---- ---- > > n_vclocks_store() > > lock(&ptp->n_vclocks_mux) [1] > > pc_clock_adjtime() > > lock(&clk->rwsem) [2] > > ... > > ptp_clock_freerun() > > ptp_vclock_in_use() > > lock(&ptp->n_vclocks_mux) [3] > > ptp_clock_unregister() > > posix_clock_unregister() > > lock(&clk->rwsem) [4] > > > > To solve this with minimal patches, we should change ptp_clock_freerun() > > to briefly release the read lock before calling ptp_vclock_in_use() and > > then re-lock it when we're done. > > Dropping locks randomly is very rarely the correct fix. Of course, we can change it to lock clk->rwsem before calling ptp_clock_unregister(), but it would require a lot of code modifications, and posix_clock_unregister() would also have to be modified, so I don't think it's very appropriate. That's why I suggested a way to briefly release the lock in ptp_clock_freerun(). > > Either way - you forgot to CC Vladimir, again. No need to reference Vladimir, as this bug is a structural issue that has been around since the n_vclocks feature was added, as indicated in the Fixes tag. > -- > pw-bot: cr Regards, Jeongjun Park
On Wed, 16 Jul 2025 14:12:27 +0900 Jeongjun Park wrote: > > Either way - you forgot to CC Vladimir, again. > > No need to reference Vladimir, as this bug is a structural issue that has > been around since the n_vclocks feature was added, as indicated in the > Fixes tag. I'm asking you to CC him, so that he can help reviewing your code.
© 2016 - 2025 Red Hat, Inc.