aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/interrupt.h14
-rw-r--r--kernel/softirq.c11
2 files changed, 25 insertions, 0 deletions
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index ff374ceface0..dd574d51bcaa 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -466,6 +466,20 @@ static inline void tasklet_hi_schedule(struct tasklet_struct *t)
466 __tasklet_hi_schedule(t); 466 __tasklet_hi_schedule(t);
467} 467}
468 468
469extern void __tasklet_hi_schedule_first(struct tasklet_struct *t);
470
471/*
472 * This version avoids touching any other tasklets. Needed for kmemcheck
473 * in order not to take any page faults while enqueueing this tasklet;
474 * consider VERY carefully whether you really need this or
475 * tasklet_hi_schedule()...
476 */
477static inline void tasklet_hi_schedule_first(struct tasklet_struct *t)
478{
479 if (!test_and_set_bit(TASKLET_STATE_SCHED, &t->state))
480 __tasklet_hi_schedule_first(t);
481}
482
469 483
470static inline void tasklet_disable_nosync(struct tasklet_struct *t) 484static inline void tasklet_disable_nosync(struct tasklet_struct *t)
471{ 485{
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 258885a543db..b41fb710e114 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -382,6 +382,17 @@ void __tasklet_hi_schedule(struct tasklet_struct *t)
382 382
383EXPORT_SYMBOL(__tasklet_hi_schedule); 383EXPORT_SYMBOL(__tasklet_hi_schedule);
384 384
385void __tasklet_hi_schedule_first(struct tasklet_struct *t)
386{
387 BUG_ON(!irqs_disabled());
388
389 t->next = __get_cpu_var(tasklet_hi_vec).head;
390 __get_cpu_var(tasklet_hi_vec).head = t;
391 __raise_softirq_irqoff(HI_SOFTIRQ);
392}
393
394EXPORT_SYMBOL(__tasklet_hi_schedule_first);
395
385static void tasklet_action(struct softirq_action *a) 396static void tasklet_action(struct softirq_action *a)
386{ 397{
387 struct tasklet_struct *list; 398 struct tasklet_struct *list;