Thread (32 messages) read the whole thread 32 messages, 5 authors, 2023-08-22

Re: [PATCH v9 1/7] irqchip/gic-v3: Enable support for SGIs to act as NMIs

From: Mark Rutland <mark.rutland@arm.com>
Date: 2023-08-07 13:35:45
Also in: linux-perf-users, lkml

On Mon, Aug 07, 2023 at 04:52:40PM +0530, Sumit Garg wrote:
On Mon, 7 Aug 2023 at 15:20, Mark Rutland [off-list ref] wrote:
quoted
On Thu, Jun 01, 2023 at 02:31:45PM -0700, Douglas Anderson wrote:
quoted
@@ -542,16 +543,22 @@ static int gic_irq_nmi_setup(struct irq_data *d)
              return -EINVAL;

      /* desc lock should already be held */
-     if (gic_irq_in_rdist(d)) {
-             u32 idx = gic_get_ppi_index(d);
+     switch (get_intid_range(d)) {
+     case SGI_RANGE:
+             break;
+     case PPI_RANGE:
+     case EPPI_RANGE:
+             idx = gic_get_ppi_index(d);

              /* Setting up PPI as NMI, only switch handler for first NMI */
              if (!refcount_inc_not_zero(&ppi_nmi_refs[idx])) {
                      refcount_set(&ppi_nmi_refs[idx], 1);
                      desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
              }
-     } else {
+             break;
+     default:
              desc->handle_irq = handle_fasteoi_nmi;
+             break;
      }
As above, I reckon this isn't right, and we should treat all rdist interrupts
(which are all percpu) the same.

I reckon what we should be doing here is make ppi_nmi_refs cover all of the
rdist interrupts (e.g. make that rdist_nmi_refs, add a gic_get_rdist_idx()
helper), and then here have something like:

        if (gic_irq_in_rdist(d)) {
                u32 idx = gic_get_rdist_idx(d);

                /*
                 * Setting up a percpu interrupt as NMI, only switch handler
                 * for first NMI
                 */
                if (!refcount_inc_not_zero(&rdist_nmi_refs[idx])) {
                        refcount_set(&ppi_nmi_refs[idx], 1);
                        desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
                }
        }
It looks like you missed the else part here as follows for all other
interrupt types:

         } else {
                 desc->handle_irq = handle_fasteoi_nmi;
         }
Yes, sorry; I had meant for that to be included, i.e.

	if (gic_irq_in_rdist(d)) {
		u32 idx = gic_get_rdist_idx(d);

		/*
		 * Setting up a percpu interrupt as NMI, only switch handler
		 * for first NMI
		 */
		if (!refcount_inc_not_zero(&rdist_nmi_refs[idx])) {
			refcount_set(&ppi_nmi_refs[idx], 1);
			desc->handle_irq = handle_percpu_devid_fasteoi_nmi;
		}
	} else {
		desc->handle_irq = handle_fasteoi_nmi;
	}
Apart from that, your logic sounds good to me.
Great!

Thanks,
Mark.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help