mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
ptp: vclock: Switch from RCU to SRCU
[ Upstream commit672bd0519e] The usage of PTP vClocks leads immediately to the following issues with ptp4l with LOCKDEP and DEBUG_ATOMIC_SLEEP enabled: "BUG: sleeping function called from invalid context". ptp_convert_timestamp() acquires a mutex_t within a RCU read section. This is illegal, because acquiring a mutex_t can result in voluntary scheduling request which is not allowed within a RCU read section. Replace the RCU usage with SRCU where sleeping is allowed. Reported-by: Florian Zeitz <florian.zeitz@schettke.com> Closes: https://lore.kernel.org/all/00a8cce8-410e-4038-98af-49be6d93d7bd@schettke.com/ Fixes:67d93ffc0f("ptp: vclock: use mutex to fix "sleep on atomic" bug") Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Link: https://patch.msgid.link/20260529-vclock_rcu-v2-1-02a5531fab92@linutronix.de Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
a4f3fd6516
commit
9a263bbd1e
@@ -19,6 +19,8 @@ static DEFINE_SPINLOCK(vclock_hash_lock);
|
||||
|
||||
static DEFINE_READ_MOSTLY_HASHTABLE(vclock_hash, 8);
|
||||
|
||||
DEFINE_STATIC_SRCU(vclock_srcu);
|
||||
|
||||
static void ptp_vclock_hash_add(struct ptp_vclock *vclock)
|
||||
{
|
||||
spin_lock(&vclock_hash_lock);
|
||||
@@ -37,7 +39,7 @@ static void ptp_vclock_hash_del(struct ptp_vclock *vclock)
|
||||
|
||||
spin_unlock(&vclock_hash_lock);
|
||||
|
||||
synchronize_rcu();
|
||||
synchronize_srcu(&vclock_srcu);
|
||||
}
|
||||
|
||||
static int ptp_vclock_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
@@ -276,14 +278,16 @@ ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index)
|
||||
{
|
||||
unsigned int hash = vclock_index % HASH_SIZE(vclock_hash);
|
||||
struct ptp_vclock *vclock;
|
||||
u64 ns;
|
||||
u64 vclock_ns = 0;
|
||||
int srcu_idx;
|
||||
u64 ns;
|
||||
|
||||
ns = ktime_to_ns(*hwtstamp);
|
||||
|
||||
rcu_read_lock();
|
||||
srcu_idx = srcu_read_lock(&vclock_srcu);
|
||||
|
||||
hlist_for_each_entry_rcu(vclock, &vclock_hash[hash], vclock_hash_node) {
|
||||
hlist_for_each_entry_srcu(vclock, &vclock_hash[hash], vclock_hash_node,
|
||||
srcu_read_lock_held(&vclock_srcu)) {
|
||||
if (vclock->clock->index != vclock_index)
|
||||
continue;
|
||||
|
||||
@@ -294,7 +298,7 @@ ktime_t ptp_convert_timestamp(const ktime_t *hwtstamp, int vclock_index)
|
||||
break;
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
srcu_read_unlock(&vclock_srcu, srcu_idx);
|
||||
|
||||
return ns_to_ktime(vclock_ns);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user