summaryrefslogtreecommitdiffstats
path: root/kernel/softirq.c
diff options
context:
space:
mode:
authorVegard Nossum <vegard.nossum@gmail.com>2008-05-21 22:53:13 +0200
committerVegard Nossum <vegard.nossum@gmail.com>2009-06-13 10:02:24 +0200
commit7c692cbade8b8884f1c20500393bcc7cd6d24ef8 (patch)
tree2cf4353c684304dfdefb89e0a70bfbd7eeadf85b /kernel/softirq.c
parent8eae985f08138758e06503588f5f1196269bc415 (diff)
tasklets: new tasklet scheduling function
Rationale: kmemcheck needs to be able to schedule a tasklet without touching any dynamically allocated memory _at_ _all_ (since that would lead to a recursive page fault). This tasklet is used for writing the error reports to the kernel log. The new scheduling function avoids touching any other tasklets by inserting the new tasklist as the head of the "tasklet_hi" list instead of on the tail. Also don't wake up the softirq thread lest the scheduler access some tracked memory and we go down with a recursive page fault. In this case, we'd better just wait for the maximum time of 1/HZ for the message to appear. Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
Diffstat (limited to 'kernel/softirq.c')
-rw-r--r--kernel/softirq.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 258885a543d..b41fb710e11 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -382,6 +382,17 @@ void __tasklet_hi_schedule(struct tasklet_struct *t)
EXPORT_SYMBOL(__tasklet_hi_schedule);
+void __tasklet_hi_schedule_first(struct tasklet_struct *t)
+{
+ BUG_ON(!irqs_disabled());
+
+ t->next = __get_cpu_var(tasklet_hi_vec).head;
+ __get_cpu_var(tasklet_hi_vec).head = t;
+ __raise_softirq_irqoff(HI_SOFTIRQ);
+}
+
+EXPORT_SYMBOL(__tasklet_hi_schedule_first);
+
static void tasklet_action(struct softirq_action *a)
{
struct tasklet_struct *list;