Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sched/core: Drop spinlocks on contention iff kernel is preemptible

Use preempt_model_preemptible() to detect a preemptible kernel when
deciding whether or not to reschedule in order to drop a contended
spinlock or rwlock. Because PREEMPT_DYNAMIC selects PREEMPTION, kernels
built with PREEMPT_DYNAMIC=y will yield contended locks even if the live
preemption model is "none" or "voluntary". In short, make kernels with
dynamically selected models behave the same as kernels with statically
selected models.

Somewhat counter-intuitively, NOT yielding a lock can provide better
latency for the relevant tasks/processes. E.g. KVM x86's mmu_lock, a
rwlock, is often contended between an invalidation event (takes mmu_lock
for write) and a vCPU servicing a guest page fault (takes mmu_lock for
read). For _some_ setups, letting the invalidation task complete even
if there is mmu_lock contention provides lower latency for *all* tasks,
i.e. the invalidation completes sooner *and* the vCPU services the guest
page fault sooner.

But even KVM's mmu_lock behavior isn't uniform, e.g. the "best" behavior
can vary depending on the host VMM, the guest workload, the number of
vCPUs, the number of pCPUs in the host, why there is lock contention, etc.

In other words, simply deleting the CONFIG_PREEMPTION guard (or doing the
opposite and removing contention yielding entirely) needs to come with a
big pile of data proving that changing the status quo is a net positive.

Opportunistically document this side effect of preempt=full, as yielding
contended spinlocks can have significant, user-visible impact.

Fixes: c597bfddc9e9 ("sched: Provide Kconfig support for default dynamic preempt mode")
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Ankur Arora <ankur.a.arora@oracle.com>
Reviewed-by: Chen Yu <yu.c.chen@intel.com>
Link: https://lore.kernel.org/kvm/ef81ff36-64bb-4cfe-ae9b-e3acf47bff24@proxmox.com

authored by

Sean Christopherson and committed by
Peter Zijlstra
c793a628 f0dc887f

+9 -9
+3 -1
Documentation/admin-guide/kernel-parameters.txt
··· 4752 4752 none - Limited to cond_resched() calls 4753 4753 voluntary - Limited to cond_resched() and might_sleep() calls 4754 4754 full - Any section that isn't explicitly preempt disabled 4755 - can be preempted anytime. 4755 + can be preempted anytime. Tasks will also yield 4756 + contended spinlocks (if the critical section isn't 4757 + explicitly preempt disabled beyond the lock itself). 4756 4758 4757 4759 print-fatal-signals= 4758 4760 [KNL] debug: print fatal signals
+6 -8
include/linux/spinlock.h
··· 462 462 */ 463 463 static inline int spin_needbreak(spinlock_t *lock) 464 464 { 465 - #ifdef CONFIG_PREEMPTION 465 + if (!preempt_model_preemptible()) 466 + return 0; 467 + 466 468 return spin_is_contended(lock); 467 - #else 468 - return 0; 469 - #endif 470 469 } 471 470 472 471 /* ··· 478 479 */ 479 480 static inline int rwlock_needbreak(rwlock_t *lock) 480 481 { 481 - #ifdef CONFIG_PREEMPTION 482 + if (!preempt_model_preemptible()) 483 + return 0; 484 + 482 485 return rwlock_is_contended(lock); 483 - #else 484 - return 0; 485 - #endif 486 486 } 487 487 488 488 /*