aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/irq_work.h1
-rw-r--r--kernel/irq_work.c15
-rw-r--r--kernel/time/timer.c2
3 files changed, 15 insertions, 3 deletions
diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h
index 6b47b2ede405..bf3fe719c7ce 100644
--- a/include/linux/irq_work.h
+++ b/include/linux/irq_work.h
@@ -39,6 +39,7 @@ bool irq_work_queue_on(struct irq_work *work, int cpu);
39#endif 39#endif
40 40
41void irq_work_run(void); 41void irq_work_run(void);
42void irq_work_tick(void);
42void irq_work_sync(struct irq_work *work); 43void irq_work_sync(struct irq_work *work);
43 44
44#ifdef CONFIG_IRQ_WORK 45#ifdef CONFIG_IRQ_WORK
diff --git a/kernel/irq_work.c b/kernel/irq_work.c
index e6bcbe756663..385b85aded19 100644
--- a/kernel/irq_work.c
+++ b/kernel/irq_work.c
@@ -115,8 +115,10 @@ bool irq_work_needs_cpu(void)
115 115
116 raised = &__get_cpu_var(raised_list); 116 raised = &__get_cpu_var(raised_list);
117 lazy = &__get_cpu_var(lazy_list); 117 lazy = &__get_cpu_var(lazy_list);
118 if (llist_empty(raised) && llist_empty(lazy)) 118
119 return false; 119 if (llist_empty(raised) || arch_irq_work_has_interrupt())
120 if (llist_empty(lazy))
121 return false;
120 122
121 /* All work should have been flushed before going offline */ 123 /* All work should have been flushed before going offline */
122 WARN_ON_ONCE(cpu_is_offline(smp_processor_id())); 124 WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));
@@ -171,6 +173,15 @@ void irq_work_run(void)
171} 173}
172EXPORT_SYMBOL_GPL(irq_work_run); 174EXPORT_SYMBOL_GPL(irq_work_run);
173 175
176void irq_work_tick(void)
177{
178 struct llist_head *raised = &__get_cpu_var(raised_list);
179
180 if (!llist_empty(raised) && !arch_irq_work_has_interrupt())
181 irq_work_run_list(raised);
182 irq_work_run_list(&__get_cpu_var(lazy_list));
183}
184
174/* 185/*
175 * Synchronize against the irq_work @entry, ensures the entry is not 186 * Synchronize against the irq_work @entry, ensures the entry is not
176 * currently in use. 187 * currently in use.
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index aca5dfe2fa3d..9bbb8344ed3b 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1385,7 +1385,7 @@ void update_process_times(int user_tick)
1385 rcu_check_callbacks(cpu, user_tick); 1385 rcu_check_callbacks(cpu, user_tick);
1386#ifdef CONFIG_IRQ_WORK 1386#ifdef CONFIG_IRQ_WORK
1387 if (in_irq()) 1387 if (in_irq())
1388 irq_work_run(); 1388 irq_work_tick();
1389#endif 1389#endif
1390 scheduler_tick(); 1390 scheduler_tick();
1391 run_posix_cpu_timers(p); 1391 run_posix_cpu_timers(p);