[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <4E66C0EA.6010302@intel.com>
Date: Wed, 07 Sep 2011 08:55:06 +0800
From: Huang Ying <ying.huang@...el.com>
To: Mathieu Desnoyers <mathieu.desnoyers@...icios.com>
CC: Andrew Morton <akpm@...ux-foundation.org>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
Andi Kleen <andi@...stfloor.org>,
Peter Zijlstra <peterz@...radead.org>
Subject: Re: [PATCH -mm 4/4] irq_work, Use llist in irq_work
On 09/06/2011 06:57 PM, Mathieu Desnoyers wrote:
> * Huang Ying (ying.huang@...el.com) 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@...el.com>
>> Cc: Peter Zijlstra <peterz@...radead.org>
>> ---
>> 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@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists