Merge branch 'core/irq_work' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/linux-dynticks into irq/core
irq_work fixes and cleanups, in preparation for full dyntics support. Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
+15
-6
@@ -34,15 +34,21 @@ static DEFINE_PER_CPU(struct llist_head, irq_work_list);
|
||||
*/
|
||||
static bool irq_work_claim(struct irq_work *work)
|
||||
{
|
||||
unsigned long flags, nflags;
|
||||
unsigned long flags, oflags, nflags;
|
||||
|
||||
/*
|
||||
* Start with our best wish as a premise but only trust any
|
||||
* flag value after cmpxchg() result.
|
||||
*/
|
||||
flags = work->flags & ~IRQ_WORK_PENDING;
|
||||
for (;;) {
|
||||
flags = work->flags;
|
||||
if (flags & IRQ_WORK_PENDING)
|
||||
return false;
|
||||
nflags = flags | IRQ_WORK_FLAGS;
|
||||
if (cmpxchg(&work->flags, flags, nflags) == flags)
|
||||
oflags = cmpxchg(&work->flags, flags, nflags);
|
||||
if (oflags == flags)
|
||||
break;
|
||||
if (oflags & IRQ_WORK_PENDING)
|
||||
return false;
|
||||
flags = oflags;
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
@@ -119,8 +125,11 @@ void irq_work_run(void)
|
||||
/*
|
||||
* Clear the PENDING bit, after this point the @work
|
||||
* can be re-used.
|
||||
* Make it immediately visible so that other CPUs trying
|
||||
* to claim that work don't rely on us to handle their data
|
||||
* while we are in the middle of the func.
|
||||
*/
|
||||
work->flags = IRQ_WORK_BUSY;
|
||||
xchg(&work->flags, IRQ_WORK_BUSY);
|
||||
work->func(work);
|
||||
/*
|
||||
* Clear the BUSY bit and return to the free state if
|
||||
|
||||
Reference in New Issue
Block a user