Messages in this thread | | | From | Ankur Arora <> | Subject | Re: [RFC PATCH 85/86] treewide: drivers: remove cond_resched() | Date | Thu, 09 Nov 2023 16:01:54 -0800 |
| |
Dmitry Torokhov <dmitry.torokhov@gmail.com> writes:
> Hi Anhur, > > On Tue, Nov 07, 2023 at 03:08:21PM -0800, Ankur Arora wrote: >> There are broadly three sets of uses of cond_resched(): >> >> 1. Calls to cond_resched() out of the goodness of our heart, >> otherwise known as avoiding lockup splats. > > ... > > What about RCU stalls? The calls to cond_resched() in evdev.c and > mousedev.c were added specifically to allow RCU to run in cases when > userspace passes a large buffer and the kernel is not fully preemptable.
Hi Dmitry
The short answer is that even if the kernel isn't fully preemptible, it will always have preempt-count which means that RCU will always know when a read-side critical section gets over.
Long version: cond_resched_rcu() is defined as:
static inline void cond_resched_rcu(void) { #if defined(CONFIG_DEBUG_ATOMIC_SLEEP) || !defined(CONFIG_PREEMPT_RCU) rcu_read_unlock(); cond_resched(); rcu_read_lock(); #endif }
So the relevant case is PREEMPT_RCU=n.
Now, currently PREEMPT_RCU=n, also implies PREEMPT_COUNT=n. And so the rcu_read_lock()/_unlock() reduce to a barrier. And, that's why we need the explicit cond_resched() there.
The reason we can remove the cond_resched() after patch 43, and 47 is because rcu_read_lock()/_unlock() will modify the preempt count and so RCU will have visibility into when RCU read-side critical sections finish.
That said, this series in this form isn't really going anywhere in the short-term so none of this is imminent.
On the calls to cond_resched(), if the kernel is fully preemptible they are a NOP. And then the code would be polling in a tight loop.
Would it make sense to do something like this instead?
if (!cond_resched()) msleep()/usleep()/cpu_relax();
-- ankur
| |