0011-genirq-Add-support-for-oneshot-safe-threaded-EOIs.patch 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. From ee6459d60f24d91052f0288155f44e6a7f991050 Mon Sep 17 00:00:00 2001
  2. From: Samuel Holland <[email protected]>
  3. Date: Sat, 7 May 2022 18:34:25 -0500
  4. Subject: [PATCH 011/117] genirq: Add support for oneshot-safe threaded EOIs
  5. irqchips can use the combination of flags IRQCHIP_ONESHOT_SAFE |
  6. IRQCHIP_EOI_THREADED to elide mask operations.
  7. Signed-off-by: Samuel Holland <[email protected]>
  8. ---
  9. kernel/irq/chip.c | 36 +++++++++++++++++-------------------
  10. kernel/irq/internals.h | 2 +-
  11. kernel/irq/manage.c | 12 ++++++------
  12. 3 files changed, 24 insertions(+), 26 deletions(-)
  13. --- a/kernel/irq/chip.c
  14. +++ b/kernel/irq/chip.c
  15. @@ -439,16 +439,6 @@ void unmask_irq(struct irq_desc *desc)
  16. }
  17. }
  18. -void unmask_threaded_irq(struct irq_desc *desc)
  19. -{
  20. - struct irq_chip *chip = desc->irq_data.chip;
  21. -
  22. - if (chip->flags & IRQCHIP_EOI_THREADED)
  23. - chip->irq_eoi(&desc->irq_data);
  24. -
  25. - unmask_irq(desc);
  26. -}
  27. -
  28. /*
  29. * handle_nested_irq - Handle a nested irq from a irq thread
  30. * @irq: the interrupt number
  31. @@ -656,25 +646,33 @@ out_unlock:
  32. }
  33. EXPORT_SYMBOL_GPL(handle_level_irq);
  34. -static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip)
  35. +void unmask_eoi_threaded_irq(struct irq_desc *desc)
  36. {
  37. - if (!(desc->istate & IRQS_ONESHOT)) {
  38. + struct irq_chip *chip = desc->irq_data.chip;
  39. +
  40. + if (desc->istate & IRQS_ONESHOT)
  41. + unmask_irq(desc);
  42. +
  43. + if (chip->flags & IRQCHIP_EOI_THREADED)
  44. chip->irq_eoi(&desc->irq_data);
  45. +}
  46. +
  47. +static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip)
  48. +{
  49. + /* Do not send EOI if the thread will do it for us. */
  50. + if ((chip->flags & IRQCHIP_EOI_THREADED) && desc->threads_oneshot)
  51. return;
  52. - }
  53. +
  54. /*
  55. * We need to unmask in the following cases:
  56. * - Oneshot irq which did not wake the thread (caused by a
  57. * spurious interrupt or a primary handler handling it
  58. * completely).
  59. */
  60. - if (!irqd_irq_disabled(&desc->irq_data) &&
  61. - irqd_irq_masked(&desc->irq_data) && !desc->threads_oneshot) {
  62. - chip->irq_eoi(&desc->irq_data);
  63. + if ((desc->istate & IRQS_ONESHOT) && !desc->threads_oneshot)
  64. unmask_irq(desc);
  65. - } else if (!(chip->flags & IRQCHIP_EOI_THREADED)) {
  66. - chip->irq_eoi(&desc->irq_data);
  67. - }
  68. +
  69. + chip->irq_eoi(&desc->irq_data);
  70. }
  71. /**
  72. --- a/kernel/irq/internals.h
  73. +++ b/kernel/irq/internals.h
  74. @@ -93,7 +93,7 @@ extern void irq_percpu_enable(struct irq
  75. extern void irq_percpu_disable(struct irq_desc *desc, unsigned int cpu);
  76. extern void mask_irq(struct irq_desc *desc);
  77. extern void unmask_irq(struct irq_desc *desc);
  78. -extern void unmask_threaded_irq(struct irq_desc *desc);
  79. +extern void unmask_eoi_threaded_irq(struct irq_desc *desc);
  80. #ifdef CONFIG_SPARSE_IRQ
  81. static inline void irq_mark_irq(unsigned int irq) { }
  82. --- a/kernel/irq/manage.c
  83. +++ b/kernel/irq/manage.c
  84. @@ -1074,9 +1074,9 @@ static int irq_wait_for_interrupt(struct
  85. static void irq_finalize_oneshot(struct irq_desc *desc,
  86. struct irqaction *action)
  87. {
  88. - if (!(desc->istate & IRQS_ONESHOT) ||
  89. - action->handler == irq_forced_secondary_handler)
  90. + if (action->handler == irq_forced_secondary_handler)
  91. return;
  92. +
  93. again:
  94. chip_bus_lock(desc);
  95. raw_spin_lock_irq(&desc->lock);
  96. @@ -1112,9 +1112,8 @@ again:
  97. desc->threads_oneshot &= ~action->thread_mask;
  98. - if (!desc->threads_oneshot && !irqd_irq_disabled(&desc->irq_data) &&
  99. - irqd_irq_masked(&desc->irq_data))
  100. - unmask_threaded_irq(desc);
  101. + if (!desc->threads_oneshot)
  102. + unmask_eoi_threaded_irq(desc);
  103. out_unlock:
  104. raw_spin_unlock_irq(&desc->lock);
  105. @@ -1662,7 +1661,8 @@ __setup_irq(unsigned int irq, struct irq
  106. * !ONESHOT irqs the thread mask is 0 so we can avoid a
  107. * conditional in irq_wake_thread().
  108. */
  109. - if (new->flags & IRQF_ONESHOT) {
  110. + if ((new->flags & IRQF_ONESHOT) ||
  111. + (desc->irq_data.chip->flags & (IRQCHIP_ONESHOT_SAFE | IRQCHIP_EOI_THREADED)) == (IRQCHIP_ONESHOT_SAFE | IRQCHIP_EOI_THREADED)) {
  112. /*
  113. * Unlikely to have 32 resp 64 irqs sharing one line,
  114. * but who knows.