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.

Merge tag 'smp-core-2025-07-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull smp updates from Thomas Gleixner:
"A set of updates for SMP function calls:

- Improve locality of smp_call_function_any() by utilizing
sched_numa_find_nth_cpu() instead of picking a random CPU

- Wait for work completion in smp_call_function_many_cond() only when
there was actually work enqueued

- Simplify functions by unutlizing the appropriate cpumask_*()
interfaces

- Trivial cleanups"

* tag 'smp-core-2025-07-27' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
smp: Wait only if work was enqueued
smp: Defer check for local execution in smp_call_function_many_cond()
smp: Use cpumask_any_but() in smp_call_function_many_cond()
smp: Improve locality in smp_call_function_any()
smp: Fix typo in comment for raw_smp_processor_id()

+15 -31
+1 -1
include/linux/smp.h
··· 234 234 #endif /* !SMP */ 235 235 236 236 /** 237 - * raw_processor_id() - get the current (unstable) CPU id 237 + * raw_smp_processor_id() - get the current (unstable) CPU id 238 238 * 239 239 * For then you know what you are doing and need an unstable 240 240 * CPU id.
+14 -30
kernel/smp.c
··· 741 741 * 742 742 * Selection preference: 743 743 * 1) current cpu if in @mask 744 - * 2) any cpu of current node if in @mask 745 - * 3) any other online cpu in @mask 744 + * 2) nearest cpu in @mask, based on NUMA topology 746 745 */ 747 746 int smp_call_function_any(const struct cpumask *mask, 748 747 smp_call_func_t func, void *info, int wait) 749 748 { 750 749 unsigned int cpu; 751 - const struct cpumask *nodemask; 752 750 int ret; 753 751 754 752 /* Try for same CPU (cheapest) */ 755 753 cpu = get_cpu(); 756 - if (cpumask_test_cpu(cpu, mask)) 757 - goto call; 754 + if (!cpumask_test_cpu(cpu, mask)) 755 + cpu = sched_numa_find_nth_cpu(mask, 0, cpu_to_node(cpu)); 758 756 759 - /* Try for same node. */ 760 - nodemask = cpumask_of_node(cpu_to_node(cpu)); 761 - for (cpu = cpumask_first_and(nodemask, mask); cpu < nr_cpu_ids; 762 - cpu = cpumask_next_and(cpu, nodemask, mask)) { 763 - if (cpu_online(cpu)) 764 - goto call; 765 - } 766 - 767 - /* Any online will do: smp_call_function_single handles nr_cpu_ids. */ 768 - cpu = cpumask_any_and(mask, cpu_online_mask); 769 - call: 770 757 ret = smp_call_function_single(cpu, func, info, wait); 771 758 put_cpu(); 772 759 return ret; ··· 779 792 bool wait = scf_flags & SCF_WAIT; 780 793 int nr_cpus = 0; 781 794 bool run_remote = false; 782 - bool run_local = false; 783 795 784 796 lockdep_assert_preemption_disabled(); 785 797 ··· 800 814 */ 801 815 WARN_ON_ONCE(!in_task()); 802 816 803 - /* Check if we need local execution. */ 804 - if ((scf_flags & SCF_RUN_LOCAL) && cpumask_test_cpu(this_cpu, mask) && 805 - (!cond_func || cond_func(this_cpu, info))) 806 - run_local = true; 807 - 808 817 /* Check if we need remote execution, i.e., any CPU excluding this one. */ 809 - cpu = cpumask_first_and(mask, cpu_online_mask); 810 - if (cpu == this_cpu) 811 - cpu = cpumask_next_and(cpu, mask, cpu_online_mask); 812 - if (cpu < nr_cpu_ids) 813 - run_remote = true; 814 - 815 - if (run_remote) { 818 + if (cpumask_any_and_but(mask, cpu_online_mask, this_cpu) < nr_cpu_ids) { 816 819 cfd = this_cpu_ptr(&cfd_data); 817 820 cpumask_and(cfd->cpumask, mask, cpu_online_mask); 818 821 __cpumask_clear_cpu(this_cpu, cfd->cpumask); ··· 815 840 continue; 816 841 } 817 842 843 + /* Work is enqueued on a remote CPU. */ 844 + run_remote = true; 845 + 818 846 csd_lock(csd); 819 847 if (wait) 820 848 csd->node.u_flags |= CSD_TYPE_SYNC; ··· 829 851 #endif 830 852 trace_csd_queue_cpu(cpu, _RET_IP_, func, csd); 831 853 854 + /* 855 + * Kick the remote CPU if this is the first work 856 + * item enqueued. 857 + */ 832 858 if (llist_add(&csd->node.llist, &per_cpu(call_single_queue, cpu))) { 833 859 __cpumask_set_cpu(cpu, cfd->cpumask_ipi); 834 860 nr_cpus++; ··· 851 869 send_call_function_ipi_mask(cfd->cpumask_ipi); 852 870 } 853 871 854 - if (run_local) { 872 + /* Check if we need local execution. */ 873 + if ((scf_flags & SCF_RUN_LOCAL) && cpumask_test_cpu(this_cpu, mask) && 874 + (!cond_func || cond_func(this_cpu, info))) { 855 875 unsigned long flags; 856 876 857 877 local_irq_save(flags);