Re: [PATCH v4 1/1] powerpc: enable dynamic preemption
From: Jirka Hladky
Date: Mon Jul 27 2026 - 07:04:23 EST
On Mon, Jul 27, 2026 at 12:29 PM Shrikanth Hegde <sshegde@xxxxxxxxxxxxx> wrote:
> That means comparison is between preempt=voluntary vs preempt=lazy.
>
> If you make it full preemption in 6.15 you will likely see similar
> data as 7.1+. Only on 7.0/7.1 there is force switch to lazy/full.
> Can you give that a try?
>
> If it shows same data, that implies the regression is mainly due to
> change of preemption modes, rather than the static key stuff.
Tested on 7.1 by switching the runtime mode via
/sys/kernel/debug/sched/preempt:
Mode kill bogo-ops/sec
---- -----------------
full 57,476
lazy 56,892
Delta ~1% (noise)
The preemption mode (full vs lazy) makes no difference. The regression
is from CONFIG_PREEMPT_RCU being enabled, not from the choice of
preemption mode.
And as Christophe pointed out, it's CONFIG_PREEMPT_DYNAMIC that pulls
in CONFIG_PREEMPT_RCU, not CONFIG_PREEMPT_LAZY:
config PREEMPT_RCU
default y if (PREEMPT || PREEMPT_RT || PREEMPT_DYNAMIC)
So the chain is: your patch enables HAVE_PREEMPT_DYNAMIC_KEY ->
CONFIG_PREEMPT_DYNAMIC takes effect -> CONFIG_PREEMPT_RCU=y ->
expensive rcu_read_lock/unlock on ppc64le.
> Plus, it may call schedule in lazy/pull preemption.
The full vs lazy results above suggest extra scheduling is not a
significant factor here.
> This seems strange. How come rcu lock/unlock depends on SELinux
> policy? One should call rcu lock/unlock if they are working with
> rcu updated fields.
>
> Does the policy change itself protected with rcu lock/unlock?
The rcu_read_lock/unlock calls don't depend on SELinux policy -- they
are in the SELinux *code path* itself. SELinux uses RCU to protect
its AVC (Access Vector Cache) lookups. Every call to avc_has_perm()
takes rcu_read_lock() around the avc_lookup() hash table access.
When you boot with selinux=0, the SELinux LSM hooks are never called,
so the AVC code path (and its rcu_read_lock/unlock pairs) is never
reached. That's why disabling SELinux removes those call sites from
the hot path.
The call chain is:
sys_kill -> check_kill_permission -> security_task_kill
-> selinux_task_kill -> avc_has_perm
-> rcu_read_lock()
-> avc_lookup() <-- hash table lookup under RCU protection
-> rcu_read_unlock()
With selinux=0, security_task_kill() is essentially a no-op and none
of the avc/rcu code runs.
Jirka