Re: [PATCH v2 03/17] cpumask: Introduce cpu_preferred_mask

Shrikanth Hegde
2026-05-05T04:11:19Z

Hi Yury.

On 4/8/26 11:27 PM, Yury Norov wrote:

> I suggest adding, for example, config PREFERRED_CPUS that would select
> PARAVIRT, and would be disabled by default.
>
> Regardless, whatever you decide, please keep all the cpu_paravirt_mask
> ifdefery on the cpumasks level. For example, in patch #5:
>
> +#ifdef CONFIG_PARAVIRT
> +static inline bool task_can_run_on_preferred_cpu(struct task_struct *p)
> +{
> + return cpumask_intersects(p->cpus_ptr, cpu_preferred_mask);
> +}
> +#else
> +static inline bool task_can_run_on_preferred_cpu(struct task_struct *p)
> +{
> + return true;
> +}
> +#endif
>
> That looks wrong to me. Instead, either declare cpu_preferred_mask
> unconditionally, and maintain it well, or
>
> +#ifdef CONFIG_PREFERRED_CPUS
> +extern struct cpumask __cpu_preferred_mask;
> +#else
> +#define __cpu_preferred_mask __cpu_online_mask
> +#endif
>
> This way, your higher level code will be clean.
>
> Thanks,
> Yury

Thanks Yury for the suggestion. This method is indeed cleaner.

So I have made it as below. It is rough patch, i may have to clean it up still.
But this helps to get much of ifdeffery elsewhere.
Most of the ifdeffery will be in cpumask.h, sched.h.

Hopefully I should be able to send the series by this week.
---

diff --git a/kernel/Kconfig.preempt b/kernel/Kconfig.preempt
index 88c594c6d7fc..c62001b52fab 100644
--- a/kernel/Kconfig.preempt
+++ b/kernel/Kconfig.preempt
@@ -192,3 +192,17 @@ config SCHED_CLASS_EXT
For more information:
Documentation/scheduler/sched-ext.rst
https://github.com/sched-ext/scx
+
+config PREFERRED_CPU
+ bool "Dynamic vCPU management based on steal time"
+ default y if PARAVIRT
+ help
+ This feature helps to reduce the steal time in paravirtualised
+ environment, there by reducing vCPU preemption. Reducing vCPU
+ preemption provides improved lock holder preemption and reduces
+ cost of vCPU preemption in the host.

diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h
index 80211900f373..577b8d992a45 100644
--- a/include/linux/cpumask.h
+++ b/include/linux/cpumask.h
@@ -120,12 +120,20 @@ extern struct cpumask __cpu_enabled_mask;
extern struct cpumask __cpu_present_mask;
extern struct cpumask __cpu_active_mask;
extern struct cpumask __cpu_dying_mask;
+
+#ifdef CONFIG_PREFERRED_CPU
+extern struct cpumask __cpu_preferred_mask;
+#else
+#define __cpu_preferred_mask __cpu_online_mask
+#endif
+
#define cpu_possible_mask ((const struct cpumask *)&__cpu_possible_mask)
#define cpu_online_mask ((const struct cpumask *)&__cpu_online_mask)
#define cpu_enabled_mask ((const struct cpumask *)&__cpu_enabled_mask)
#define cpu_present_mask ((const struct cpumask *)&__cpu_present_mask)
#define cpu_active_mask ((const struct cpumask *)&__cpu_active_mask)
#define cpu_dying_mask ((const struct cpumask *)&__cpu_dying_mask)
+#define cpu_preferred_mask ((const struct cpumask *)&__cpu_preferred_mask)

extern atomic_t __num_online_cpus;
extern unsigned int __num_possible_cpus;
@@ -1164,6 +1172,7 @@ void init_cpu_possible(const struct cpumask *src);

void set_cpu_online(unsigned int cpu, bool online);
void set_cpu_possible(unsigned int cpu, bool possible);
+void set_cpu_preferred(unsigned int cpu, bool preferred);

/**
* to_cpumask - convert a NR_CPUS bitmap to a struct cpumask *
@@ -1256,7 +1265,12 @@ static __always_inline bool cpu_dying(unsigned int cpu)
return cpumask_test_cpu(cpu, cpu_dying_mask);
}

-#else
+static __always_inline bool cpu_preferred(unsigned int cpu)
+{
+ return cpumask_test_cpu(cpu, cpu_preferred_mask);
+}
+
+#else /* NR_CPUS <= 1 */

#define num_online_cpus() 1U
#define num_possible_cpus() 1U
@@ -1294,6 +1308,11 @@ static __always_inline bool cpu_dying(unsigned int cpu)
return false;
}

+static __always_inline bool cpu_preferred(unsigned int cpu)
+{
+ return false;
+}
+
#endif /* NR_CPUS > 1 */

#define cpu_is_offline(cpu) unlikely(!cpu_online(cpu))
diff --git a/kernel/cpu.c b/kernel/cpu.c
index bc4f7a9ba64e..7787c907f9b8 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -3107,6 +3107,11 @@ EXPORT_SYMBOL(__cpu_dying_mask);
atomic_t __num_online_cpus __read_mostly;
EXPORT_SYMBOL(__num_online_cpus);

+#ifdef CONFIG_PREFERRED_CPU
+struct cpumask __cpu_preferred_mask __read_mostly;
+EXPORT_SYMBOL(__cpu_preferred_mask);
+#endif
+
void init_cpu_present(const struct cpumask *src)
{
cpumask_copy(&__cpu_present_mask, src);
@@ -3154,6 +3159,14 @@ void set_cpu_possible(unsigned int cpu, bool possible)
}
}

+void set_cpu_preferred(unsigned int cpu, bool preferred)
+{
+ if(!IS_ENABLED(CONFIG_PREFERRED_CPU))
+ return;
+
+ assign_cpu((cpu), &__cpu_preferred_mask, (preferred));
+}
+
/*
* Activate the first processor.
*/