softirq: Consolidate common code in tasklet_[hi]_action()
tasklet_action() + tasklet_hi_action() are almost identical. Move the common code from both function into __tasklet_action_common() and let both functions invoke it with different arguments. [ bigeasy: Splitted out from RT's "tasklet: Prevent tasklets from going into infinite spin in RT" and added commit message] Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: Julia Cartwright <juliac@eso.teric.us> Link: https://lkml.kernel.org/r/20180227164808.10093-3-bigeasy@linutronix.de
This commit is contained in:
parent
6498ddad30
commit
82b691bedf
|
@ -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_action(struct softirq_action *a)
|
||||
{
|
||||
tasklet_action_common(a, this_cpu_ptr(&tasklet_vec), TASKLET_SOFTIRQ);
|
||||
}
|
||||
|
||||
static __latent_entropy void tasklet_hi_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);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
tasklet_action_common(a, this_cpu_ptr(&tasklet_hi_vec), HI_SOFTIRQ);
|
||||
}
|
||||
|
||||
void tasklet_init(struct tasklet_struct *t,
|
||||
|
|
Loading…
Reference in New Issue