Commit 5564c123 authored by Frederic Weisbecker's avatar Frederic Weisbecker
Browse files

kthread: Include unbound kthreads in the managed affinity list



The managed affinity list currently contains only unbound kthreads that
have affinity preferences. Unbound kthreads globally affine by default
are outside of the list because their affinity is automatically managed
by the scheduler (through the fallback housekeeping mask) and by cpuset.

However in order to preserve the preferred affinity of kthreads, cpuset
will delegate the isolated partition update propagation to the
housekeeping and kthread code.

Prepare for that with including all unbound kthreads in the managed
affinity list.

Signed-off-by: default avatarFrederic Weisbecker <frederic@kernel.org>
Reviewed-by: default avatarWaiman Long <longman@redhat.com>
Cc: Marco Crivellari <marco.crivellari@suse.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Waiman Long <longman@redhat.com>
parent 012fef0e
Loading
Loading
Loading
Loading
+40 −28
Original line number Diff line number Diff line
@@ -365,8 +365,9 @@ static void kthread_fetch_affinity(struct kthread *kthread, struct cpumask *cpum
	if (kthread->preferred_affinity) {
		pref = kthread->preferred_affinity;
	} else {
		if (WARN_ON_ONCE(kthread->node == NUMA_NO_NODE))
			return;
		if (kthread->node == NUMA_NO_NODE)
			pref = housekeeping_cpumask(HK_TYPE_KTHREAD);
		else
			pref = cpumask_of_node(kthread->node);
	}

@@ -380,11 +381,9 @@ static void kthread_affine_node(void)
	struct kthread *kthread = to_kthread(current);
	cpumask_var_t affinity;

	WARN_ON_ONCE(kthread_is_per_cpu(current));
	if (WARN_ON_ONCE(kthread_is_per_cpu(current)))
		return;

	if (kthread->node == NUMA_NO_NODE) {
		housekeeping_affine(current, HK_TYPE_KTHREAD);
	} else {
	if (!zalloc_cpumask_var(&affinity, GFP_KERNEL)) {
		WARN_ON_ONCE(1);
		return;
@@ -406,7 +405,6 @@ static void kthread_affine_node(void)

	free_cpumask_var(affinity);
}
}

static int kthread(void *_create)
{
@@ -919,9 +917,23 @@ static int kthreads_online_cpu(unsigned int cpu)
			ret = -EINVAL;
			continue;
		}

		/*
		 * Unbound kthreads without preferred affinity are already affine
		 * to housekeeping, whether those CPUs are online or not. So no need
		 * to handle newly online CPUs for them.
		 *
		 * But kthreads with a preferred affinity or node are different:
		 * if none of their preferred CPUs are online and part of
		 * housekeeping at the same time, they must be affine to housekeeping.
		 * But as soon as one of their preferred CPU becomes online, they must
		 * be affine to them.
		 */
		if (k->preferred_affinity || k->node != NUMA_NO_NODE) {
			kthread_fetch_affinity(k, affinity);
			set_cpus_allowed_ptr(k->task, affinity);
		}
	}

	free_cpumask_var(affinity);