diff options
-rw-r--r-- | include/linux/irq_work.h | 1 | ||||
-rw-r--r-- | kernel/irq_work.c | 15 | ||||
-rw-r--r-- | kernel/time/timer.c | 2 |
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 | ||
41 | void irq_work_run(void); | 41 | void irq_work_run(void); |
42 | void irq_work_tick(void); | ||
42 | void irq_work_sync(struct irq_work *work); | 43 | void 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 | } |
172 | EXPORT_SYMBOL_GPL(irq_work_run); | 174 | EXPORT_SYMBOL_GPL(irq_work_run); |
173 | 175 | ||
176 | void 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); |