Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-only 2 : /* 3 : * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra 4 : * 5 : * Provides a framework for enqueueing and running callbacks from hardirq 6 : * context. The enqueueing is NMI-safe. 7 : */ 8 : 9 : #include <linux/bug.h> 10 : #include <linux/kernel.h> 11 : #include <linux/export.h> 12 : #include <linux/irq_work.h> 13 : #include <linux/percpu.h> 14 : #include <linux/hardirq.h> 15 : #include <linux/irqflags.h> 16 : #include <linux/sched.h> 17 : #include <linux/tick.h> 18 : #include <linux/cpu.h> 19 : #include <linux/notifier.h> 20 : #include <linux/smp.h> 21 : #include <asm/processor.h> 22 : 23 : 24 : static DEFINE_PER_CPU(struct llist_head, raised_list); 25 : static DEFINE_PER_CPU(struct llist_head, lazy_list); 26 : 27 : /* 28 : * Claim the entry so that no one else will poke at it. 29 : */ 30 69 : static bool irq_work_claim(struct irq_work *work) 31 : { 32 69 : int oflags; 33 : 34 69 : oflags = atomic_fetch_or(IRQ_WORK_CLAIMED | CSD_TYPE_IRQ_WORK, &work->node.a_flags); 35 : /* 36 : * If the work is already pending, no need to raise the IPI. 37 : * The pairing smp_mb() in irq_work_single() makes sure 38 : * everything we did before is visible. 39 : */ 40 69 : if (oflags & IRQ_WORK_PENDING) 41 : return false; 42 : return true; 43 : } 44 : 45 0 : void __weak arch_irq_work_raise(void) 46 : { 47 : /* 48 : * Lame architectures will get the timer tick callback 49 : */ 50 0 : } 51 : 52 : /* Enqueue on current CPU, work must already be claimed and preempt disabled */ 53 38 : static void __irq_work_queue_local(struct irq_work *work) 54 : { 55 : /* If the work is "lazy", handle it from next tick if any */ 56 38 : if (atomic_read(&work->node.a_flags) & IRQ_WORK_LAZY) { 57 76 : if (llist_add(&work->node.llist, this_cpu_ptr(&lazy_list)) && 58 38 : tick_nohz_tick_stopped()) 59 0 : arch_irq_work_raise(); 60 : } else { 61 0 : if (llist_add(&work->node.llist, this_cpu_ptr(&raised_list))) 62 0 : arch_irq_work_raise(); 63 : } 64 38 : } 65 : 66 : /* Enqueue the irq work @work on the current CPU */ 67 69 : bool irq_work_queue(struct irq_work *work) 68 : { 69 : /* Only queue if not already pending */ 70 69 : if (!irq_work_claim(work)) 71 : return false; 72 : 73 : /* Queue the entry and raise the IPI if needed. */ 74 38 : preempt_disable(); 75 38 : __irq_work_queue_local(work); 76 38 : preempt_enable(); 77 : 78 38 : return true; 79 : } 80 : EXPORT_SYMBOL_GPL(irq_work_queue); 81 : 82 : /* 83 : * Enqueue the irq_work @work on @cpu unless it's already pending 84 : * somewhere. 85 : * 86 : * Can be re-enqueued while the callback is still in progress. 87 : */ 88 0 : bool irq_work_queue_on(struct irq_work *work, int cpu) 89 : { 90 : #ifndef CONFIG_SMP 91 : return irq_work_queue(work); 92 : 93 : #else /* CONFIG_SMP: */ 94 : /* All work should have been flushed before going offline */ 95 0 : WARN_ON_ONCE(cpu_is_offline(cpu)); 96 : 97 : /* Only queue if not already pending */ 98 0 : if (!irq_work_claim(work)) 99 : return false; 100 : 101 0 : preempt_disable(); 102 0 : if (cpu != smp_processor_id()) { 103 : /* Arch remote IPI send/receive backend aren't NMI safe */ 104 0 : WARN_ON_ONCE(in_nmi()); 105 0 : __smp_call_single_queue(cpu, &work->node.llist); 106 : } else { 107 0 : __irq_work_queue_local(work); 108 : } 109 0 : preempt_enable(); 110 : 111 0 : return true; 112 : #endif /* CONFIG_SMP */ 113 : } 114 : 115 : 116 1458 : bool irq_work_needs_cpu(void) 117 : { 118 1458 : struct llist_head *raised, *lazy; 119 : 120 1458 : raised = this_cpu_ptr(&raised_list); 121 1459 : lazy = this_cpu_ptr(&lazy_list); 122 : 123 1460 : if (llist_empty(raised) || arch_irq_work_has_interrupt()) 124 1460 : if (llist_empty(lazy)) 125 : return false; 126 : 127 : /* All work should have been flushed before going offline */ 128 0 : WARN_ON_ONCE(cpu_is_offline(smp_processor_id())); 129 : 130 : return true; 131 : } 132 : 133 38 : void irq_work_single(void *arg) 134 : { 135 38 : struct irq_work *work = arg; 136 38 : int flags; 137 : 138 : /* 139 : * Clear the PENDING bit, after this point the @work can be re-used. 140 : * The PENDING bit acts as a lock, and we own it, so we can clear it 141 : * without atomic ops. 142 : */ 143 38 : flags = atomic_read(&work->node.a_flags); 144 38 : flags &= ~IRQ_WORK_PENDING; 145 38 : atomic_set(&work->node.a_flags, flags); 146 : 147 : /* 148 : * See irq_work_claim(). 149 : */ 150 38 : smp_mb(); 151 : 152 38 : lockdep_irq_work_enter(flags); 153 38 : work->func(work); 154 38 : lockdep_irq_work_exit(flags); 155 : 156 : /* 157 : * Clear the BUSY bit, if set, and return to the free state if no-one 158 : * else claimed it meanwhile. 159 : */ 160 38 : (void)atomic_cmpxchg(&work->node.a_flags, flags, flags & ~IRQ_WORK_BUSY); 161 38 : } 162 : 163 31867 : static void irq_work_run_list(struct llist_head *list) 164 : { 165 31867 : struct irq_work *work, *tmp; 166 31867 : struct llist_node *llnode; 167 : 168 31867 : BUG_ON(!irqs_disabled()); 169 : 170 31913 : if (llist_empty(list)) 171 : return; 172 : 173 38 : llnode = llist_del_all(list); 174 114 : llist_for_each_entry_safe(work, tmp, llnode, node.llist) 175 38 : irq_work_single(work); 176 : } 177 : 178 : /* 179 : * hotplug calls this through: 180 : * hotplug_cfd() -> flush_smp_call_function_queue() 181 : */ 182 0 : void irq_work_run(void) 183 : { 184 0 : irq_work_run_list(this_cpu_ptr(&raised_list)); 185 0 : irq_work_run_list(this_cpu_ptr(&lazy_list)); 186 0 : } 187 : EXPORT_SYMBOL_GPL(irq_work_run); 188 : 189 31420 : void irq_work_tick(void) 190 : { 191 31420 : struct llist_head *raised = this_cpu_ptr(&raised_list); 192 : 193 32066 : if (!llist_empty(raised) && !arch_irq_work_has_interrupt()) 194 0 : irq_work_run_list(raised); 195 32066 : irq_work_run_list(this_cpu_ptr(&lazy_list)); 196 31952 : } 197 : 198 : /* 199 : * Synchronize against the irq_work @entry, ensures the entry is not 200 : * currently in use. 201 : */ 202 0 : void irq_work_sync(struct irq_work *work) 203 : { 204 0 : lockdep_assert_irqs_enabled(); 205 : 206 0 : while (irq_work_is_busy(work)) 207 0 : cpu_relax(); 208 0 : } 209 : EXPORT_SYMBOL_GPL(irq_work_sync);