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

Reply via email to