Hi, Paul,
On Thu, Aug 24, 2023 at 6:41 AM Paul E. McKenney paulmck@kernel.org wrote:
On Thu, Aug 24, 2023 at 12:03:25AM +0200, Thomas Gleixner wrote:
On Thu, Aug 17 2023 at 16:06, Huacai Chen wrote:
On Thu, Aug 17, 2023 at 3:27 AM Joel Fernandes joel@joelfernandes.org wrote:
If do_update_jiffies_64() cannot be used in NMI context,
Can you not make the jiffies update conditional on whether it is called within NMI context?
Which solves what? If KGDB has a breakpoint in the jiffies lock held region then you still dead lock.
I dislike that..
Is this acceptable?
void rcu_cpu_stall_reset(void) { unsigned long delta;
delta = nsecs_to_jiffies(ktime_get_ns() - ktime_get_coarse_ns()); WRITE_ONCE(rcu_state.jiffies_stall, jiffies + delta + rcu_jiffies_till_stall_check());
}
This can update jiffies_stall without updating jiffies (but has the same effect).
Now you traded the potential dead lock on jiffies lock for a potential live lock vs. tk_core.seq. Not really an improvement, right?
The only way you can do the above is something like the incomplete and uncompiled below. NMI safe and therefore livelock proof time interfaces exist for a reason.
Just for completeness, another approach, with its own advantages and disadvantage, is to add something like ULONG_MAX/4 to rcu_state.jiffies_stall, but also set a counter indicating that this has been done. Then RCU's force-quiescent processing could decrement that counter (if non-zero) and reset rcu_state.jiffies_stall when it does reach zero.
Setting the counter to three should cover most cases, but "live by the heuristic, die by the heuristic". ;-)
It would be good to have some indication when gdb exited, but things like the gdb "next" command can make that "interesting" when applied to a long-running function.
The original code is adding ULONG_MAX/2, so adding ULONG_MAX/4 may make no much difference? The simplest way is adding 300*HZ, but Joel dislikes that.
Huacai
Thanx, Paul
Thanks,
tglx
--- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -51,6 +51,13 @@ struct tick_sched *tick_get_tick_sched(i */ static ktime_t last_jiffies_update;
+unsigned long tick_estimate_stale_jiffies(void) +{
ktime_t delta = ktime_get_mono_fast_ns() - READ_ONCE(last_jiffies_update);
return delta < 0 ? 0 : div_s64(delta, TICK_NSEC);
+}
/*
- Must be called with interrupts disabled !
*/