// SPDX-License-Identifier: GPL-2.0-only /* * Housekeeping management. Manage the targets for routine code that can run on * any CPU: unbound workqueues, timers, kthreads and any offloadable work. * * Copyright (C) 2017 Red Hat, Inc., Frederic Weisbecker * Copyright (C) 2017-2018 SUSE, Frederic Weisbecker *
*/ #include <linux/sched/isolation.h> #include"sched.h"
int housekeeping_any_cpu(enum hk_type type)
{ int cpu;
if (static_branch_unlikely(&housekeeping_overridden)) { if (housekeeping.flags & BIT(type)) {
cpu = sched_numa_find_closest(housekeeping.cpumasks[type], smp_processor_id()); if (cpu < nr_cpu_ids) return cpu;
cpu = cpumask_any_and_distribute(housekeeping.cpumasks[type], cpu_online_mask); if (likely(cpu < nr_cpu_ids)) return cpu; /* * Unless we have another problem this can only happen * at boot time before start_secondary() brings the 1st * housekeeping CPU up.
*/
WARN_ON_ONCE(system_state == SYSTEM_RUNNING ||
type != HK_TYPE_TIMER);
}
} return smp_processor_id();
}
EXPORT_SYMBOL_GPL(housekeeping_any_cpu);
conststruct cpumask *housekeeping_cpumask(enum hk_type type)
{ if (static_branch_unlikely(&housekeeping_overridden)) if (housekeeping.flags & BIT(type)) return housekeeping.cpumasks[type]; return cpu_possible_mask;
}
EXPORT_SYMBOL_GPL(housekeeping_cpumask);
void housekeeping_affine(struct task_struct *t, enum hk_type type)
{ if (static_branch_unlikely(&housekeeping_overridden)) if (housekeeping.flags & BIT(type))
set_cpus_allowed_ptr(t, housekeeping.cpumasks[type]);
}
EXPORT_SYMBOL_GPL(housekeeping_affine);
bool housekeeping_test_cpu(int cpu, enum hk_type type)
{ if (static_branch_unlikely(&housekeeping_overridden)) if (housekeeping.flags & BIT(type)) return cpumask_test_cpu(cpu, housekeeping.cpumasks[type]); returntrue;
}
EXPORT_SYMBOL_GPL(housekeeping_test_cpu);
if (housekeeping.flags & HK_FLAG_KERNEL_NOISE)
sched_tick_offload_init();
for_each_set_bit(type, &housekeeping.flags, HK_TYPE_MAX) { /* We need at least one CPU to handle housekeeping work */
WARN_ON_ONCE(cpumask_empty(housekeeping.cpumasks[type]));
}
}
/* * Skip unknown sub-parameter and validate that it is not * containing an invalid character.
*/ for (par = str, len = 0; *str && *str != ','; str++, len++) { if (!isalpha(*str) && *str != '_')
illegal = true;
}
if (illegal) {
pr_warn("isolcpus: Invalid flag %.*s\n", len, par); return 0;
}
pr_info("isolcpus: Skipped unknown flag %.*s\n", len, par);
str++;
}
/* Default behaviour for isolcpus without flags */ if (!flags)
flags |= HK_FLAG_DOMAIN;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.