|
@@ -490,14 +490,16 @@ void __tasklet_hi_schedule(struct tasklet_struct *t)
|
|
|
}
|
|
|
EXPORT_SYMBOL(__tasklet_hi_schedule);
|
|
|
|
|
|
-static __latent_entropy void tasklet_action(struct softirq_action *a)
|
|
|
+static void tasklet_action_common(struct softirq_action *a,
|
|
|
+ struct tasklet_head *tl_head,
|
|
|
+ unsigned int softirq_nr)
|
|
|
{
|
|
|
struct tasklet_struct *list;
|
|
|
|
|
|
local_irq_disable();
|
|
|
- list = __this_cpu_read(tasklet_vec.head);
|
|
|
- __this_cpu_write(tasklet_vec.head, NULL);
|
|
|
- __this_cpu_write(tasklet_vec.tail, this_cpu_ptr(&tasklet_vec.head));
|
|
|
+ list = tl_head->head;
|
|
|
+ tl_head->head = NULL;
|
|
|
+ tl_head->tail = &tl_head->head;
|
|
|
local_irq_enable();
|
|
|
|
|
|
while (list) {
|
|
@@ -519,47 +521,21 @@ static __latent_entropy void tasklet_action(struct softirq_action *a)
|
|
|
|
|
|
local_irq_disable();
|
|
|
t->next = NULL;
|
|
|
- *__this_cpu_read(tasklet_vec.tail) = t;
|
|
|
- __this_cpu_write(tasklet_vec.tail, &(t->next));
|
|
|
- __raise_softirq_irqoff(TASKLET_SOFTIRQ);
|
|
|
+ *tl_head->tail = t;
|
|
|
+ tl_head->tail = &t->next;
|
|
|
+ __raise_softirq_irqoff(softirq_nr);
|
|
|
local_irq_enable();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static __latent_entropy void tasklet_hi_action(struct softirq_action *a)
|
|
|
+static __latent_entropy void tasklet_action(struct softirq_action *a)
|
|
|
{
|
|
|
- struct tasklet_struct *list;
|
|
|
-
|
|
|
- local_irq_disable();
|
|
|
- list = __this_cpu_read(tasklet_hi_vec.head);
|
|
|
- __this_cpu_write(tasklet_hi_vec.head, NULL);
|
|
|
- __this_cpu_write(tasklet_hi_vec.tail, this_cpu_ptr(&tasklet_hi_vec.head));
|
|
|
- local_irq_enable();
|
|
|
-
|
|
|
- while (list) {
|
|
|
- struct tasklet_struct *t = list;
|
|
|
-
|
|
|
- list = list->next;
|
|
|
-
|
|
|
- if (tasklet_trylock(t)) {
|
|
|
- if (!atomic_read(&t->count)) {
|
|
|
- if (!test_and_clear_bit(TASKLET_STATE_SCHED,
|
|
|
- &t->state))
|
|
|
- BUG();
|
|
|
- t->func(t->data);
|
|
|
- tasklet_unlock(t);
|
|
|
- continue;
|
|
|
- }
|
|
|
- tasklet_unlock(t);
|
|
|
- }
|
|
|
+ tasklet_action_common(a, this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ);
|
|
|
+}
|
|
|
|
|
|
- local_irq_disable();
|
|
|
- t->next = NULL;
|
|
|
- *__this_cpu_read(tasklet_hi_vec.tail) = t;
|
|
|
- __this_cpu_write(tasklet_hi_vec.tail, &(t->next));
|
|
|
- __raise_softirq_irqoff(HI_SOFTIRQ);
|
|
|
- local_irq_enable();
|
|
|
- }
|
|
|
+static __latent_entropy void tasklet_hi_action(struct softirq_action *a)
|
|
|
+{
|
|
|
+ tasklet_action_common(a, this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ);
|
|
|
}
|
|
|
|
|
|
void tasklet_init(struct tasklet_struct *t,
|