diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-18 15:29:53 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-08-18 15:29:53 -0700 |
| commit | 0dd1a54f44348d9cf6bae57a2b5cb0b53826a2c7 (patch) | |
| tree | cc7ca2ad4a92fb593ffdf72fe6ebc0dff75155c0 /include/linux | |
| parent | b844715e8aca2929c0a97a32b3a5650496b5872f (diff) | |
| parent | 99b49e02f9488335156c896c24aab0785623eb67 (diff) | |
Merge tag 'smp-core-2026-08-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull SMP core updates from Thomas Gleixner:
- Reduce the preemption disabled sections in smp_call_function*().
The various smp call functions keep preemption disabled accross the
full operation which includes the wait for completion. Especially the
latter can take some time when one of the target CPUs is not
immediately responding to the IPI, which can result in large latency
spikes.
To improve this provide a per task CPU mask to track the CPUs to wait
for. That makes the information required for the wait task local and
therefore allows to reenable preemption before the wait.
While this comes with moderate extra memory cost this reduces SMP
function call induced latency measured in a fleet for high priority
tasks from ~17ms to ~1.5ms (~90%).
- Reduce the overhead of the CSD debug code by replacing the heavy
memory barriers with smp_store_release()/acquire()
- Remove obsolute unused hotplug states
* tag 'smp-core-2026-08-17' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
scftorture: Remove preempt_disable() in scftorture_invoke_one()
smp: Remove preempt_disable() from on_each_cpu_cond_mask()
smp: Remove preempt_disable() from smp_call_function()
smp: Enable preemption early in smp_call_function_many_cond()
smp: Alloc percpu csd data in smpcfd_prepare_cpu() only once
smp: Use task-local IPI cpumask in smp_call_function_many_cond()
smp: Refactor remote CPU selection in smp_call_function_any()
smp: Enable preemption early in smp_call_function_single()
smp: Disable preemption explicitly in __csd_lock_wait()
cpu/hotplug: Remove CPUHP_AP_ARM_CORESIGHT_CTI_STARTING
smp: Use release stores for csd_lock_record() state
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/cpuhotplug.h | 1 | ||||
| -rw-r--r-- | include/linux/sched.h | 12 | ||||
| -rw-r--r-- | include/linux/smp.h | 15 |
3 files changed, 25 insertions, 3 deletions
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index 0fb3a2a62eb0..feb32949aeea 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -180,7 +180,6 @@ enum cpuhp_state { CPUHP_AP_DUMMY_TIMER_STARTING, CPUHP_AP_ARM_XEN_STARTING, CPUHP_AP_ARM_XEN_RUNSTATE_STARTING, - CPUHP_AP_ARM_CORESIGHT_CTI_STARTING, CPUHP_AP_ARM64_ISNDEP_STARTING, CPUHP_AP_SMPCFD_DYING, CPUHP_AP_HRTIMERS_DYING, diff --git a/include/linux/sched.h b/include/linux/sched.h index 3188fc78ac9b..193a4a4dcc27 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -821,6 +821,17 @@ struct kmap_ctrl { #endif }; +#if defined(CONFIG_SMP) && defined(CONFIG_PREEMPTION) +struct task_ipi_mask { + union { + cpumask_t *ipi_mask_ptr; + unsigned long ipi_mask_val; + }; +}; +#else +struct task_ipi_mask { }; +#endif + struct task_struct { #ifdef CONFIG_THREAD_INFO_IN_TASK /* @@ -1358,6 +1369,7 @@ struct task_struct { struct list_head perf_event_list; struct perf_ctx_data __rcu *perf_ctx_data; #endif + struct task_ipi_mask __private ipi_mask; #ifdef CONFIG_DEBUG_PREEMPT unsigned long preempt_disable_ip; #endif diff --git a/include/linux/smp.h b/include/linux/smp.h index 6925d15ccaa7..2dfa7390717a 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -47,8 +47,7 @@ extern void __smp_call_single_queue(int cpu, struct llist_node *node); /* total number of cpus in this system (may exceed NR_CPUS) */ extern unsigned int total_cpus; -int smp_call_function_single(int cpuid, smp_call_func_t func, void *info, - int wait); +int smp_call_function_single(int cpuid, smp_call_func_t func, void *info, bool wait); void on_each_cpu_cond_mask(smp_cond_func_t cond_func, smp_call_func_t func, void *info, bool wait, const struct cpumask *mask); @@ -239,6 +238,18 @@ static inline int get_boot_cpu_id(void) #endif /* !SMP */ +#if defined(CONFIG_PREEMPTION) && defined(CONFIG_SMP) +int smp_task_ipi_mask_alloc(struct task_struct *task); +void smp_task_ipi_mask_free(struct task_struct *task); +#else +static inline int smp_task_ipi_mask_alloc(struct task_struct *task) +{ + return 0; +} + +static inline void smp_task_ipi_mask_free(struct task_struct *task) { } +#endif + /* * raw_smp_processor_id() - get the current (unstable) CPU id * |
