On 11/03/2017 01:06 PM, Christoph Müllner wrote: >> On 29 Oct 2017, at 18:36, Philippe Gerum <r...@xenomai.org> wrote: >> >> On 10/23/2017 04:59 PM, Christoph Muellner wrote: >>> To set a GPIO interrupt's CPU affinity, we simply call >>> rtdm_irq_affinity() with a proper bitmask. >>> >>> Signed-off-by: Christoph Muellner <christoph.muell...@theobroma-systems.com> >>> --- >>> kernel/drivers/gpio/gpio-core.c | 25 +++++++++++++++++++++++++ >>> 1 file changed, 25 insertions(+) >>> >>> diff --git a/kernel/drivers/gpio/gpio-core.c >>> b/kernel/drivers/gpio/gpio-core.c >>> index 55594f6ae..84153a937 100644 >>> --- a/kernel/drivers/gpio/gpio-core.c >>> +++ b/kernel/drivers/gpio/gpio-core.c >>> @@ -118,6 +118,23 @@ static void release_gpio_irq(unsigned int gpio, struct >>> rtdm_gpio_pin *pin, >>> chan->requested = false; >>> } >>> >>> +static int set_gpio_irq_affinity(struct rtdm_gpio_pin *pin, int val) >>> +{ >>> + cpumask_t tgt; >>> + unsigned int i = 0; >>> + >>> + cpumask_clear(&tgt); >>> + >>> + while (val) { >>> + if (val & (1 << i)) >>> + cpumask_set_cpu(i, &tgt); >>> + val &= ~(1 << i); >>> + i++; >>> + } >>> + >>> + return rtdm_irq_affinity(&pin->irqh, tgt); >>> +} >>> + >> >> Reflecting the change from int -> cpu_set_t in the ABI, we could have >> something along these lines instead: >> >> static int set_gpio_irq_affinity(struct rtdm_gpio_pin *pin, unsigned >> long __user *u_set, size_t setsize) >> { >> cpumask_var_t mask; >> int ret; >> >> if (!alloc_cpumask_var(&mask, GFP_KERNEL)) >> return -ENOMEM; >> >> ret = get_user_cpu_mask(u_set, setsize, mask); >> if (ret == 0) >> ret = do_set_gpio_affinity(pin, mask); >> >> free_cpumask_var(mask); >> >> ... > > Thanks for your review! > > I guess this is inspired from kernel/sched/core.c's sched_setaffinity() > syscall handler. > However, I prefer not to use the use the alloc_cpumask_var() function. > The reason is, that "alloc_cpumask_var allocates only nr_cpumask_bits bits", > whil> a "real cpumask_t always has NR_CPUS bits" (quoting from the warning in linux/cpumask.h) > As rtdm_irq_affinity() expects a cpumask_t as second argument, we would copy > a too small mask. Instead I'm going to use a (stack allocated) cpumask_t.
Unfortunately, this is somewhat papering over the real issue: ipipe_set_irq_affinity(), xnintr_affinity() and rtdm_irq_affinity() should all receive a struct cpumask pointer instead. Passing the mask by value is wrong. This said, we have API backward compat requirements which prevents from fixing ipipe_set_irq_affinity() without introducing specific conditional cruft. So, ok. Let's go for propagating the problem, until the interrupt pipeline is overhauled. -- Philippe. _______________________________________________ Xenomai mailing list Xenomai@xenomai.org https://xenomai.org/mailman/listinfo/xenomai