Skip to content

Commit 1d6d399

Browse files
committed
Merge tag 'kthread-for-6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks
Pull kthread updates from Frederic Weisbecker: "Kthreads affinity follow either of 4 existing different patterns: 1) Per-CPU kthreads must stay affine to a single CPU and never execute relevant code on any other CPU. This is currently handled by smpboot code which takes care of CPU-hotplug operations. Affinity here is a correctness constraint. 2) Some kthreads _have_ to be affine to a specific set of CPUs and can't run anywhere else. The affinity is set through kthread_bind_mask() and the subsystem takes care by itself to handle CPU-hotplug operations. Affinity here is assumed to be a correctness constraint. 3) Per-node kthreads _prefer_ to be affine to a specific NUMA node. This is not a correctness constraint but merely a preference in terms of memory locality. kswapd and kcompactd both fall into this category. The affinity is set manually like for any other task and CPU-hotplug is supposed to be handled by the relevant subsystem so that the task is properly reaffined whenever a given CPU from the node comes up. Also care should be taken so that the node affinity doesn't cross isolated (nohz_full) cpumask boundaries. 4) Similar to the previous point except kthreads have a _preferred_ affinity different than a node. Both RCU boost kthreads and RCU exp kworkers fall into this category as they refer to "RCU nodes" from a distinctly distributed tree. Currently the preferred affinity patterns (3 and 4) have at least 4 identified users, with more or less success when it comes to handle CPU-hotplug operations and CPU isolation. Each of which do it in its own ad-hoc way. This is an infrastructure proposal to handle this with the following API changes: - kthread_create_on_node() automatically affines the created kthread to its target node unless it has been set as per-cpu or bound with kthread_bind[_mask]() before the first wake-up. - kthread_affine_preferred() is a new function that can be called right after kthread_create_on_node() to specify a preferred affinity different than the specified node. When the preferred affinity can't be applied because the possible targets are offline or isolated (nohz_full), the kthread is affine to the housekeeping CPUs (which means to all online CPUs most of the time or only the non-nohz_full CPUs when nohz_full= is set). kswapd, kcompactd, RCU boost kthreads and RCU exp kworkers have been converted, along with a few old drivers. Summary of the changes: - Consolidate a bunch of ad-hoc implementations of kthread_run_on_cpu() - Introduce task_cpu_fallback_mask() that defines the default last resort affinity of a task to become nohz_full aware - Add some correctness check to ensure kthread_bind() is always called before the first kthread wake up. - Default affine kthread to its preferred node. - Convert kswapd / kcompactd and remove their halfway working ad-hoc affinity implementation - Implement kthreads preferred affinity - Unify kthread worker and kthread API's style - Convert RCU kthreads to the new API and remove the ad-hoc affinity implementation" * tag 'kthread-for-6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks: kthread: modify kernel-doc function name to match code rcu: Use kthread preferred affinity for RCU exp kworkers treewide: Introduce kthread_run_worker[_on_cpu]() kthread: Unify kthread_create_on_cpu() and kthread_create_worker_on_cpu() automatic format rcu: Use kthread preferred affinity for RCU boost kthread: Implement preferred affinity mm: Create/affine kswapd to its preferred node mm: Create/affine kcompactd to its preferred node kthread: Default affine kthread to its preferred NUMA node kthread: Make sure kthread hasn't started while binding it sched,arm64: Handle CPU isolation on last resort fallback rq selection arm64: Exclude nohz_full CPUs from 32bits el0 support lib: test_objpool: Use kthread_run_on_cpu() kallsyms: Use kthread_run_on_cpu() soc/qman: test: Use kthread_run_on_cpu() arm/bL_switcher: Use kthread_run_on_cpu()
2 parents 96c8470 + d8b4bf4 commit 1d6d399

File tree

47 files changed

+341
-221
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+341
-221
lines changed

Documentation/arch/arm64/asymmetric-32bit.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,11 @@ asymmetric system, a broken guest at EL1 could still attempt to execute
153153
mode will return to host userspace with an ``exit_reason`` of
154154
``KVM_EXIT_FAIL_ENTRY`` and will remain non-runnable until successfully
155155
re-initialised by a subsequent ``KVM_ARM_VCPU_INIT`` operation.
156+
157+
NOHZ FULL
158+
---------
159+
160+
To avoid perturbing an adaptive-ticks CPU (specified using
161+
``nohz_full=``) when a 32-bit task is forcefully migrated, these CPUs
162+
are treated as 64-bit-only when support for asymmetric 32-bit systems
163+
is enabled.

arch/arm/common/bL_switcher.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -307,13 +307,11 @@ static struct task_struct *bL_switcher_thread_create(int cpu, void *arg)
307307
{
308308
struct task_struct *task;
309309

310-
task = kthread_create_on_node(bL_switcher_thread, arg,
311-
cpu_to_node(cpu), "kswitcher_%d", cpu);
312-
if (!IS_ERR(task)) {
313-
kthread_bind(task, cpu);
314-
wake_up_process(task);
315-
} else
310+
task = kthread_run_on_cpu(bL_switcher_thread, arg,
311+
cpu, "kswitcher_%d");
312+
if (IS_ERR(task))
316313
pr_err("%s failed for CPU %d\n", __func__, cpu);
314+
317315
return task;
318316
}
319317

arch/arm64/include/asm/cpufeature.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ static inline bool supports_clearbhb(int scope)
671671
}
672672

673673
const struct cpumask *system_32bit_el0_cpumask(void);
674+
const struct cpumask *fallback_32bit_el0_cpumask(void);
674675
DECLARE_STATIC_KEY_FALSE(arm64_mismatched_32bit_el0);
675676

676677
static inline bool system_supports_32bit_el0(void)

arch/arm64/include/asm/mmu_context.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,18 +271,26 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next,
271271
}
272272

273273
static inline const struct cpumask *
274-
task_cpu_possible_mask(struct task_struct *p)
274+
__task_cpu_possible_mask(struct task_struct *p, const struct cpumask *mask)
275275
{
276276
if (!static_branch_unlikely(&arm64_mismatched_32bit_el0))
277-
return cpu_possible_mask;
277+
return mask;
278278

279279
if (!is_compat_thread(task_thread_info(p)))
280-
return cpu_possible_mask;
280+
return mask;
281281

282282
return system_32bit_el0_cpumask();
283283
}
284+
285+
static inline const struct cpumask *
286+
task_cpu_possible_mask(struct task_struct *p)
287+
{
288+
return __task_cpu_possible_mask(p, cpu_possible_mask);
289+
}
284290
#define task_cpu_possible_mask task_cpu_possible_mask
285291

292+
const struct cpumask *task_cpu_fallback_mask(struct task_struct *p);
293+
286294
void verify_cpu_asid_bits(void);
287295
void post_ttbr_update_workaround(void);
288296

arch/arm64/kernel/cpufeature.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include <linux/cpu.h>
7676
#include <linux/kasan.h>
7777
#include <linux/percpu.h>
78+
#include <linux/sched/isolation.h>
7879

7980
#include <asm/cpu.h>
8081
#include <asm/cpufeature.h>
@@ -1644,6 +1645,11 @@ const struct cpumask *system_32bit_el0_cpumask(void)
16441645
return cpu_possible_mask;
16451646
}
16461647

1648+
const struct cpumask *task_cpu_fallback_mask(struct task_struct *p)
1649+
{
1650+
return __task_cpu_possible_mask(p, housekeeping_cpumask(HK_TYPE_TICK));
1651+
}
1652+
16471653
static int __init parse_32bit_el0_param(char *str)
16481654
{
16491655
allow_mismatched_32bit_el0 = true;
@@ -3773,7 +3779,14 @@ static int enable_mismatched_32bit_el0(unsigned int cpu)
37733779
static int lucky_winner = -1;
37743780

37753781
struct cpuinfo_arm64 *info = &per_cpu(cpu_data, cpu);
3776-
bool cpu_32bit = id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0);
3782+
bool cpu_32bit = false;
3783+
3784+
if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) {
3785+
if (!housekeeping_cpu(cpu, HK_TYPE_TICK))
3786+
pr_info("Treating adaptive-ticks CPU %u as 64-bit only\n", cpu);
3787+
else
3788+
cpu_32bit = true;
3789+
}
37773790

37783791
if (cpu_32bit) {
37793792
cpumask_set_cpu(cpu, cpu_32bit_el0_mask);

arch/x86/kvm/i8254.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags)
681681
pid_nr = pid_vnr(pid);
682682
put_pid(pid);
683683

684-
pit->worker = kthread_create_worker(0, "kvm-pit/%d", pid_nr);
684+
pit->worker = kthread_run_worker(0, "kvm-pit/%d", pid_nr);
685685
if (IS_ERR(pit->worker))
686686
goto fail_kthread;
687687

crypto/crypto_engine.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ struct crypto_engine *crypto_engine_alloc_init_and_set(struct device *dev,
517517
crypto_init_queue(&engine->queue, qlen);
518518
spin_lock_init(&engine->queue_lock);
519519

520-
engine->kworker = kthread_create_worker(0, "%s", engine->name);
520+
engine->kworker = kthread_run_worker(0, "%s", engine->name);
521521
if (IS_ERR(engine->kworker)) {
522522
dev_err(dev, "failed to create crypto request pump task\n");
523523
return NULL;

drivers/cpufreq/cppc_cpufreq.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ static void __init cppc_freq_invariance_init(void)
225225
if (fie_disabled)
226226
return;
227227

228-
kworker_fie = kthread_create_worker(0, "cppc_fie");
228+
kworker_fie = kthread_run_worker(0, "cppc_fie");
229229
if (IS_ERR(kworker_fie)) {
230230
pr_warn("%s: failed to create kworker_fie: %ld\n", __func__,
231231
PTR_ERR(kworker_fie));

drivers/gpu/drm/drm_vblank_work.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ int drm_vblank_worker_init(struct drm_vblank_crtc *vblank)
277277

278278
INIT_LIST_HEAD(&vblank->pending_work);
279279
init_waitqueue_head(&vblank->work_wait_queue);
280-
worker = kthread_create_worker(0, "card%d-crtc%d",
280+
worker = kthread_run_worker(0, "card%d-crtc%d",
281281
vblank->dev->primary->index,
282282
vblank->pipe);
283283
if (IS_ERR(worker))

drivers/gpu/drm/i915/gem/selftests/i915_gem_context.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ static int live_parallel_switch(void *arg)
369369
if (!data[n].ce[0])
370370
continue;
371371

372-
worker = kthread_create_worker(0, "igt/parallel:%s",
372+
worker = kthread_run_worker(0, "igt/parallel:%s",
373373
data[n].ce[0]->engine->name);
374374
if (IS_ERR(worker)) {
375375
err = PTR_ERR(worker);

0 commit comments

Comments
 (0)