aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/irq_work.h
diff options
context:
space:
mode:
authorPeter Zijlstra <peterz@infradead.org>2020-05-26 18:11:02 +0200
committerIngo Molnar <mingo@kernel.org>2020-05-28 10:54:15 +0200
commit4b44a21dd640b692d4e9b12d3e37c24825f90baa (patch)
tree5dea8495f643a9152ce6ada83d8f5f6466f1d898 /include/linux/irq_work.h
parentsmp: Optimize send_call_function_single_ipi() (diff)
downloadlinux-dev-4b44a21dd640b692d4e9b12d3e37c24825f90baa.tar.xz
linux-dev-4b44a21dd640b692d4e9b12d3e37c24825f90baa.zip
irq_work, smp: Allow irq_work on call_single_queue
Currently irq_work_queue_on() will issue an unconditional arch_send_call_function_single_ipi() and has the handler do irq_work_run(). This is unfortunate in that it makes the IPI handler look at a second cacheline and it misses the opportunity to avoid the IPI. Instead note that struct irq_work and struct __call_single_data are very similar in layout, so use a few bits in the flags word to encode a type and stick the irq_work on the call_single_queue list. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Ingo Molnar <mingo@kernel.org> Link: https://lore.kernel.org/r/20200526161908.011635912@infradead.org
Diffstat (limited to 'include/linux/irq_work.h')
-rw-r--r--include/linux/irq_work.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/include/linux/irq_work.h b/include/linux/irq_work.h
index 3b752e80c017..f23a359c8f46 100644
--- a/include/linux/irq_work.h
+++ b/include/linux/irq_work.h
@@ -13,6 +13,8 @@
* busy NULL, 2 -> {free, claimed} : callback in progress, can be claimed
*/
+/* flags share CSD_FLAG_ space */
+
#define IRQ_WORK_PENDING BIT(0)
#define IRQ_WORK_BUSY BIT(1)
@@ -23,9 +25,12 @@
#define IRQ_WORK_CLAIMED (IRQ_WORK_PENDING | IRQ_WORK_BUSY)
+/*
+ * structure shares layout with single_call_data_t.
+ */
struct irq_work {
- atomic_t flags;
struct llist_node llnode;
+ atomic_t flags;
void (*func)(struct irq_work *);
};