On Tue, Oct 27, 2020 at 10:56:36AM -0700, Sean Christopherson wrote: > On Tue, Oct 27, 2020 at 09:49:50AM -0700, Ben Gardon wrote: > > Rescheduling while holding a spin lock is essential for keeping long > > running kernel operations running smoothly. Add the facility to > > cond_resched rwlocks. > > This adds two new exports and two new macros without any in-tree users, which > is generally frowned upon. You and I know these will be used by KVM's new > TDP MMU, but the non-KVM folks, and more importantly the maintainers of this > code, are undoubtedly going to ask "why". I.e. these patches probably belong > in the KVM series to switch to a rwlock for the TDP MMU. I was informed about this ;-) > Regarding the code, it's all copy-pasted from the spinlock code and darn near > identical. It might be worth adding builder macros for these. I considered mentioning them; I'm typically a fan of them, but I'm not quite sure it's worth the effort here. > > +int __cond_resched_rwlock_read(rwlock_t *lock) > > +{ > > + int resched = should_resched(PREEMPT_LOCK_OFFSET); > > + int ret = 0; > > + > > + lockdep_assert_held(lock); > > + > > + if (rwlock_needbreak(lock) || resched) { > > + read_unlock(lock); > > + if (resched) > > + preempt_schedule_common(); > > + else > > + cpu_relax(); > > + ret = 1; > > AFAICT, this rather odd code flow from __cond_resched_lock() is an artifact of > code changes over the years and not intentionally weird. IMO, it would be > cleaner and easier to read as: > > int resched = should_resched(PREEMPT_LOCK_OFFSET); > > lockdep_assert_held(lock); lockdep_assert_held_read() :-) > > if (!rwlock_needbreak(lock) && !resched) > return 0; > > read_unlock(lock); > if (resched) > preempt_schedule_common(); > else > cpu_relax(); > read_lock(lock) > return 1; > I suppose that works, but then also change the existing one.