Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xen: implement IRQ_WORK_VECTOR handler

Signed-off-by: Lin Ming <mlin@ss.pku.edu.cn>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>

authored by

Lin Ming and committed by
Konrad Rzeszutek Wilk
1ff2b0c3 f447d56d

+31
+1
arch/x86/include/asm/xen/events.h
··· 6 6 XEN_CALL_FUNCTION_VECTOR, 7 7 XEN_CALL_FUNCTION_SINGLE_VECTOR, 8 8 XEN_SPIN_UNLOCK_VECTOR, 9 + XEN_IRQ_WORK_VECTOR, 9 10 10 11 XEN_NR_IPIS, 11 12 };
+30
arch/x86/xen/smp.c
··· 16 16 #include <linux/err.h> 17 17 #include <linux/slab.h> 18 18 #include <linux/smp.h> 19 + #include <linux/irq_work.h> 19 20 20 21 #include <asm/paravirt.h> 21 22 #include <asm/desc.h> ··· 42 41 static DEFINE_PER_CPU(int, xen_resched_irq); 43 42 static DEFINE_PER_CPU(int, xen_callfunc_irq); 44 43 static DEFINE_PER_CPU(int, xen_callfuncsingle_irq); 44 + static DEFINE_PER_CPU(int, xen_irq_work); 45 45 static DEFINE_PER_CPU(int, xen_debug_irq) = -1; 46 46 47 47 static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id); 48 48 static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id); 49 + static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id); 49 50 50 51 /* 51 52 * Reschedule call back. ··· 146 143 goto fail; 147 144 per_cpu(xen_callfuncsingle_irq, cpu) = rc; 148 145 146 + callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu); 147 + rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR, 148 + cpu, 149 + xen_irq_work_interrupt, 150 + IRQF_DISABLED|IRQF_PERCPU|IRQF_NOBALANCING, 151 + callfunc_name, 152 + NULL); 153 + if (rc < 0) 154 + goto fail; 155 + per_cpu(xen_irq_work, cpu) = rc; 156 + 149 157 return 0; 150 158 151 159 fail: ··· 169 155 if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0) 170 156 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), 171 157 NULL); 158 + if (per_cpu(xen_irq_work, cpu) >= 0) 159 + unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); 172 160 173 161 return rc; 174 162 } ··· 525 509 case CALL_FUNCTION_SINGLE_VECTOR: 526 510 xen_vector = XEN_CALL_FUNCTION_SINGLE_VECTOR; 527 511 break; 512 + case IRQ_WORK_VECTOR: 513 + xen_vector = XEN_IRQ_WORK_VECTOR; 514 + break; 528 515 default: 529 516 xen_vector = -1; 530 517 printk(KERN_ERR "xen: vector 0x%x is not implemented\n", ··· 607 588 return IRQ_HANDLED; 608 589 } 609 590 591 + static irqreturn_t xen_irq_work_interrupt(int irq, void *dev_id) 592 + { 593 + irq_enter(); 594 + irq_work_run(); 595 + inc_irq_stat(apic_irq_work_irqs); 596 + irq_exit(); 597 + 598 + return IRQ_HANDLED; 599 + } 600 + 610 601 static const struct smp_ops xen_smp_ops __initconst = { 611 602 .smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu, 612 603 .smp_prepare_cpus = xen_smp_prepare_cpus, ··· 663 634 unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL); 664 635 unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL); 665 636 unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL); 637 + unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL); 666 638 native_cpu_die(cpu); 667 639 } 668 640