Re: [RFC][PATCH] irq_work -v2

From: huang ying
Date: Fri Jun 25 2010 - 21:26:26 EST


On Sat, Jun 26, 2010 at 2:30 AM, Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote:
> +
> +static DEFINE_PER_CPU(struct irq_work *, irq_work_list);
> +
> +/*
> + * Claim the entry so that no one else will poke at it.
> + */
> +static bool irq_work_claim(struct irq_work *entry)
> +{
> + Â Â Â unsigned long flags;
> +
> + Â Â Â do {
> + Â Â Â Â Â Â Â flags = (unsigned long)entry->next;
> + Â Â Â Â Â Â Â if (flags & IRQ_WORK_PENDING)
> + Â Â Â Â Â Â Â Â Â Â Â return false;
> + Â Â Â } while (cmpxchg(&entry->next, flags, flags | IRQ_WORK_FLAGS) != flags);
> +
> + Â Â Â return true;
> +}
> +
> +
> +void __weak arch_irq_work_raise(void)
> +{
> + Â Â Â /*
> + Â Â Â Â* Lame architectures will get the timer tick callback
> + Â Â Â Â*/
> +}
> +
> +/*
> + * Queue the entry and raise the IPI if needed.
> + */
> +static void __irq_work_queue(struct irq_work *entry)
> +{
> + Â Â Â struct irq_work **head;
> +
> + Â Â Â head = &get_cpu_var(irq_work_list);
> +
> + Â Â Â do {
> + Â Â Â Â Â Â Â /*
> + Â Â Â Â Â Â Â Â* Can assign non-atomic because we keep the flags set.
> + Â Â Â Â Â Â Â Â*/
> + Â Â Â Â Â Â Â entry->next = next_flags(*head, IRQ_WORK_FLAGS);
> + Â Â Â } while (cmpxchg(head, entry->next, entry) != entry->next);

*head & IRQ_WORK_FLAGS == 0, but entry->next & IRQ_WORK_FLAGS ==
IRQ_WORK_FLAGS. So the cmpxchg will never succeed.

> +
> + Â Â Â /*
> + Â Â Â Â* The list was empty, raise self-interrupt to start processing.
> + Â Â Â Â*/
> + Â Â Â if (!irq_work_next(entry))
> + Â Â Â Â Â Â Â arch_irq_work_raise();
> +
> + Â Â Â put_cpu_var(irq_work_list);
> +}

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/