Re: [PATCH -mm 4/4] irq_work, Use llist in irq_work

From: Huang Ying
Date: Tue Sep 06 2011 - 20:55:32 EST


On 09/06/2011 06:57 PM, Mathieu Desnoyers wrote:
> * Huang Ying (ying.huang@xxxxxxxxx) wrote:
>> Use llist in irq_work instead of the lock-less linked list
>> implementation in irq_work to avoid the code duplication.
>>
>> Signed-off-by: Huang Ying <ying.huang@xxxxxxxxx>
>> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
>> ---
>> include/linux/irq_work.h | 15 ++++---
>> kernel/irq_work.c | 92 ++++++++++++++++-------------------------------
>> 2 files changed, 41 insertions(+), 66 deletions(-)
>>
> [...]
>> -static void __irq_work_queue(struct irq_work *entry)
>> +static void __irq_work_queue(struct irq_work *work)
>> {
>> - struct irq_work *next;
>> -
>> preempt_disable();
>>
>> - do {
>> - next = __this_cpu_read(irq_work_list);
>> - /* Can assign non-atomic because we keep the flags set. */
>> - entry->next = next_flags(next, IRQ_WORK_FLAGS);
>> - } while (this_cpu_cmpxchg(irq_work_list, next, entry) != next);
>> -
>> + llist_add(&work->llnode, &__get_cpu_var(irq_work_list));
>> /* The list was empty, raise self-interrupt to start processing. */
>> - if (!irq_work_next(entry))
>> + if (!work->llnode.next)
>
>
> Hrm. What happens if this function gets delayed between llist_add and
> "if (!work->llnode.next)" ? It seems like the threads performing
> llist_del_all would be within its right to free the memory pointed to by
> work in the meantime.

Yes. This is an issue. This can be fixed in several way

1) use another flag to indicate whether list is empty
2) make llist_add return whether list is empty before adding
3) request irq_work users to free the memory with call_rcu() or after
synchronize_rcu().

Personally I prefer 1), which will not expose llist implementation
details too.

Best Regards,
Huang Ying
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/