From e2361e04b02aafa927c32c4f5a39e6fd96196082 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 31 Oct 2022 14:33:58 +0000 Subject: [PATCH] LinuxKPI: implement cpumask_of() Add a static set of cpumasks for all (possible) cpus with only the one indexed cpu enabled in each set. This is needed for cpumask_of(_cpuid) which returns a cpumask (cpuset) with only cpu _cpuid enabled and is used by one wireless driver at least. MFC after: 3 days Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D37223 --- .../linuxkpi/common/include/linux/cpu.h | 4 ++++ sys/compat/linuxkpi/common/src/linux_compat.c | 20 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/sys/compat/linuxkpi/common/include/linux/cpu.h b/sys/compat/linuxkpi/common/include/linux/cpu.h index 53fa9db424c2..08e59b33e53a 100644 --- a/sys/compat/linuxkpi/common/include/linux/cpu.h +++ b/sys/compat/linuxkpi/common/include/linux/cpu.h @@ -44,6 +44,8 @@ typedef cpuset_t cpumask_t; extern cpumask_t cpu_online_mask; +cpumask_t *lkpi_get_static_single_cpu_mask(int); + static __inline int cpumask_next(int cpuid, cpumask_t mask) { @@ -73,4 +75,6 @@ cpumask_set_cpu(int cpu, cpumask_t *mask) CPU_SET(cpu, mask); } +#define cpumask_of(_cpu) (lkpi_get_static_single_cpu_mask(_cpu)) + #endif /* _LINUXKPI_LINUX_CPU_H */ diff --git a/sys/compat/linuxkpi/common/src/linux_compat.c b/sys/compat/linuxkpi/common/src/linux_compat.c index 8c5d2e4ecd16..1367556a6f43 100644 --- a/sys/compat/linuxkpi/common/src/linux_compat.c +++ b/sys/compat/linuxkpi/common/src/linux_compat.c @@ -132,6 +132,7 @@ static void linux_cdev_deref(struct linux_cdev *ldev); static struct vm_area_struct *linux_cdev_handle_find(void *handle); cpumask_t cpu_online_mask; +static cpumask_t static_single_cpu_mask[MAXCPU]; struct kobject linux_class_root; struct device linux_root_device; struct class linux_class_misc; @@ -2734,6 +2735,16 @@ bool linux_cpu_has_clflush; struct cpuinfo_x86 boot_cpu_data; #endif +cpumask_t * +lkpi_get_static_single_cpu_mask(int cpuid) +{ + + KASSERT((cpuid >= 0 && cpuid < MAXCPU), ("%s: invalid cpuid %d\n", + __func__, cpuid)); + + return (&static_single_cpu_mask[cpuid]); +} + static void linux_compat_init(void *arg) { @@ -2771,6 +2782,15 @@ linux_compat_init(void *arg) init_waitqueue_head(&linux_var_waitq); CPU_COPY(&all_cpus, &cpu_online_mask); + /* + * Generate a single-CPU cpumask_t for each CPU (possibly) in the system. + * CPUs are indexed from 0..(MAXCPU-1). The entry for cpuid 0 will only + * have itself in the cpumask, cupid 1 only itself on entry 1, and so on. + * This is used by cpumask_of() (and possibly others in the future) for, + * e.g., drivers to pass hints to irq_set_affinity_hint(). + */ + for (i = 0; i < MAXCPU; i++) + CPU_SET(i, &static_single_cpu_mask[i]); } SYSINIT(linux_compat, SI_SUB_DRIVERS, SI_ORDER_SECOND, linux_compat_init, NULL);