irq_work.c 879 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. /*
  2. * x86 specific code for irq_work
  3. *
  4. * Copyright (C) 2010 Red Hat, Inc., Peter Zijlstra
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/irq_work.h>
  8. #include <linux/hardirq.h>
  9. #include <asm/apic.h>
  10. #include <asm/trace/irq_vectors.h>
  11. static inline void __smp_irq_work_interrupt(void)
  12. {
  13. inc_irq_stat(apic_irq_work_irqs);
  14. irq_work_run();
  15. }
  16. __visible void smp_irq_work_interrupt(struct pt_regs *regs)
  17. {
  18. ipi_entering_ack_irq();
  19. __smp_irq_work_interrupt();
  20. exiting_irq();
  21. }
  22. __visible void smp_trace_irq_work_interrupt(struct pt_regs *regs)
  23. {
  24. ipi_entering_ack_irq();
  25. trace_irq_work_entry(IRQ_WORK_VECTOR);
  26. __smp_irq_work_interrupt();
  27. trace_irq_work_exit(IRQ_WORK_VECTOR);
  28. exiting_irq();
  29. }
  30. void arch_irq_work_raise(void)
  31. {
  32. #ifdef CONFIG_X86_LOCAL_APIC
  33. if (!arch_irq_work_has_interrupt())
  34. return;
  35. apic->send_IPI_self(IRQ_WORK_VECTOR);
  36. apic_wait_icr_idle();
  37. #endif
  38. }