All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2)
@ 2007-03-29 16:41 Mitch Williams
  2007-03-29 16:59 ` Eric W. Biederman
  2007-03-29 17:25 ` Chuck Ebbert
  0 siblings, 2 replies; 9+ messages in thread
From: Mitch Williams @ 2007-03-29 16:41 UTC (permalink / raw)
  To: linux-pci; +Cc: gregkh, ebiederm, linux-kernel, akpm, auke-jan.h.kok

This patch fixes a kernel bug which is triggered when using the
irqbalance daemon with MSI-X hardware.

Because both MSI-X interrupt messages and MSI-X table writes are posted,
it's possible for them to cross while in-flight.  This results in
interrupts being received long after the kernel thinks they're disabled,
and in interrupts being sent to stale vectors after rebalancing.

This patch performs a read flush after writes to the MSI-X table for
mask/unmask and rebalancing operations.

This patch has been validated with (unreleased) network hardware which
uses MSI-X.

Revised with input from Eric Biederman.

Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>

diff -urpN -X dontdiff linux-2.6.21-rc5-clean/arch/i386/kernel/io_apic.c linux-2.6.21-rc5/arch/i386/kernel/io_apic.c
--- linux-2.6.21-rc5-clean/arch/i386/kernel/io_apic.c	2007-03-28 10:05:22.000000000 -0700
+++ linux-2.6.21-rc5/arch/i386/kernel/io_apic.c	2007-03-28 10:19:14.000000000 -0700
@@ -2584,6 +2584,7 @@ static void set_msi_irq_affinity(unsigne
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
 	write_msi_msg(irq, &msg);
+	msix_flush_writes(irq);
 	irq_desc[irq].affinity = mask;
 }
 #endif /* CONFIG_SMP */
diff -urpN -X dontdiff linux-2.6.21-rc5-clean/arch/ia64/kernel/msi_ia64.c linux-2.6.21-rc5/arch/ia64/kernel/msi_ia64.c
--- linux-2.6.21-rc5-clean/arch/ia64/kernel/msi_ia64.c	2007-03-28 10:05:22.000000000 -0700
+++ linux-2.6.21-rc5/arch/ia64/kernel/msi_ia64.c	2007-03-28 09:34:27.000000000 -0700
@@ -60,6 +60,7 @@ static void ia64_set_msi_irq_affinity(un
 	msg.address_lo = addr;
 
 	write_msi_msg(irq, &msg);
+	msix_flush_writes(irq);
 	irq_desc[irq].affinity = cpu_mask;
 }
 #endif /* CONFIG_SMP */
diff -urpN -X dontdiff linux-2.6.21-rc5-clean/arch/ia64/sn/kernel/msi_sn.c linux-2.6.21-rc5/arch/ia64/sn/kernel/msi_sn.c
--- linux-2.6.21-rc5-clean/arch/ia64/sn/kernel/msi_sn.c	2007-03-28 10:05:22.000000000 -0700
+++ linux-2.6.21-rc5/arch/ia64/sn/kernel/msi_sn.c	2007-03-28 09:34:06.000000000 -0700
@@ -204,6 +204,7 @@ static void sn_set_msi_irq_affinity(unsi
 	msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
 
 	write_msi_msg(irq, &msg);
+	msix_flush_writes(irq);
 	irq_desc[irq].affinity = cpu_mask;
 }
 #endif /* CONFIG_SMP */
diff -urpN -X dontdiff linux-2.6.21-rc5-clean/arch/x86_64/kernel/io_apic.c linux-2.6.21-rc5/arch/x86_64/kernel/io_apic.c
--- linux-2.6.21-rc5-clean/arch/x86_64/kernel/io_apic.c	2007-03-28 10:05:22.000000000 -0700
+++ linux-2.6.21-rc5/arch/x86_64/kernel/io_apic.c	2007-03-28 10:18:52.000000000 -0700
@@ -1956,6 +1956,7 @@ static void set_msi_irq_affinity(unsigne
 	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
 	write_msi_msg(irq, &msg);
+	msix_flush_writes(irq);
 	irq_desc[irq].affinity = mask;
 }
 #endif /* CONFIG_SMP */
diff -urpN -X dontdiff linux-2.6.21-rc5-clean/drivers/pci/msi.c linux-2.6.21-rc5/drivers/pci/msi.c
--- linux-2.6.21-rc5-clean/drivers/pci/msi.c	2007-03-28 10:05:24.000000000 -0700
+++ linux-2.6.21-rc5/drivers/pci/msi.c	2007-03-28 09:21:34.000000000 -0700
@@ -68,6 +68,29 @@ static void msix_set_enable(struct pci_d
 	}
 }
 
+void msix_flush_writes(unsigned int irq)
+{
+	struct msi_desc *entry;
+
+	entry = get_irq_msi(irq);
+	BUG_ON(!entry || !entry->dev);
+	switch (entry->msi_attrib.type) {
+	case PCI_CAP_ID_MSI:
+		/* nothing to do */
+		break;
+	case PCI_CAP_ID_MSIX:
+	{
+		int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
+			PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
+		readl(entry->mask_base + offset);
+		break;
+	}
+	default:
+		BUG();
+		break;
+	}
+}
+
 static void msi_set_mask_bit(unsigned int irq, int flag)
 {
 	struct msi_desc *entry;
@@ -186,11 +209,13 @@ void write_msi_msg(unsigned int irq, str
 void mask_msi_irq(unsigned int irq)
 {
 	msi_set_mask_bit(irq, 1);
+	msix_flush_writes(irq);
 }
 
 void unmask_msi_irq(unsigned int irq)
 {
 	msi_set_mask_bit(irq, 0);
+	msix_flush_writes(irq);
 }
 
 static int msi_free_irq(struct pci_dev* dev, int irq);
diff -urpN -X dontdiff linux-2.6.21-rc5-clean/include/linux/msi.h linux-2.6.21-rc5/include/linux/msi.h
--- linux-2.6.21-rc5-clean/include/linux/msi.h	2007-03-28 10:05:25.000000000 -0700
+++ linux-2.6.21-rc5/include/linux/msi.h	2007-03-28 09:21:51.000000000 -0700
@@ -12,6 +12,7 @@ extern void mask_msi_irq(unsigned int ir
 extern void unmask_msi_irq(unsigned int irq);
 extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
 extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);
+extern void msix_flush_writes(unsigned int irq);
 
 struct msi_desc {
 	struct {

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2)
  2007-03-29 16:41 [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2) Mitch Williams
@ 2007-03-29 16:59 ` Eric W. Biederman
  2007-03-29 22:01   ` Williams, Mitch A
  2007-03-29 17:25 ` Chuck Ebbert
  1 sibling, 1 reply; 9+ messages in thread
From: Eric W. Biederman @ 2007-03-29 16:59 UTC (permalink / raw)
  To: Mitch Williams
  Cc: linux-pci, gregkh, ebiederm, linux-kernel, akpm, auke-jan.h.kok

Mitch Williams <mitch.a.williams@intel.com> writes:

> This patch fixes a kernel bug which is triggered when using the
> irqbalance daemon with MSI-X hardware.
>
> Because both MSI-X interrupt messages and MSI-X table writes are posted,
> it's possible for them to cross while in-flight.  This results in
> interrupts being received long after the kernel thinks they're disabled,
> and in interrupts being sent to stale vectors after rebalancing.
>
> This patch performs a read flush after writes to the MSI-X table for
> mask/unmask and rebalancing operations.
>
> This patch has been validated with (unreleased) network hardware which
> uses MSI-X.
>
> Revised with input from Eric Biederman.

Do we still need the flush the set affinity routines?
Shouldn't flush in mask and unmask should now be enough?


>
> Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
>
> diff -urpN -X dontdiff linux-2.6.21-rc5-clean/arch/i386/kernel/io_apic.c
> linux-2.6.21-rc5/arch/i386/kernel/io_apic.c
> --- linux-2.6.21-rc5-clean/arch/i386/kernel/io_apic.c 2007-03-28
> 10:05:22.000000000 -0700
> +++ linux-2.6.21-rc5/arch/i386/kernel/io_apic.c 2007-03-28 10:19:14.000000000
> -0700
> @@ -2584,6 +2584,7 @@ static void set_msi_irq_affinity(unsigne
>  	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
>  
>  	write_msi_msg(irq, &msg);
> +	msix_flush_writes(irq);
>  	irq_desc[irq].affinity = mask;
>  }
>  #endif /* CONFIG_SMP */
> diff -urpN -X dontdiff linux-2.6.21-rc5-clean/arch/ia64/kernel/msi_ia64.c
> linux-2.6.21-rc5/arch/ia64/kernel/msi_ia64.c
> --- linux-2.6.21-rc5-clean/arch/ia64/kernel/msi_ia64.c 2007-03-28
> 10:05:22.000000000 -0700
> +++ linux-2.6.21-rc5/arch/ia64/kernel/msi_ia64.c 2007-03-28 09:34:27.000000000
> -0700
> @@ -60,6 +60,7 @@ static void ia64_set_msi_irq_affinity(un
>  	msg.address_lo = addr;
>  
>  	write_msi_msg(irq, &msg);
> +	msix_flush_writes(irq);
>  	irq_desc[irq].affinity = cpu_mask;
>  }
>  #endif /* CONFIG_SMP */
> diff -urpN -X dontdiff linux-2.6.21-rc5-clean/arch/ia64/sn/kernel/msi_sn.c
> linux-2.6.21-rc5/arch/ia64/sn/kernel/msi_sn.c
> --- linux-2.6.21-rc5-clean/arch/ia64/sn/kernel/msi_sn.c 2007-03-28
> 10:05:22.000000000 -0700
> +++ linux-2.6.21-rc5/arch/ia64/sn/kernel/msi_sn.c 2007-03-28 09:34:06.000000000
> -0700
> @@ -204,6 +204,7 @@ static void sn_set_msi_irq_affinity(unsi
>  	msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
>  
>  	write_msi_msg(irq, &msg);
> +	msix_flush_writes(irq);
>  	irq_desc[irq].affinity = cpu_mask;
>  }
>  #endif /* CONFIG_SMP */
> diff -urpN -X dontdiff linux-2.6.21-rc5-clean/arch/x86_64/kernel/io_apic.c
> linux-2.6.21-rc5/arch/x86_64/kernel/io_apic.c
> --- linux-2.6.21-rc5-clean/arch/x86_64/kernel/io_apic.c 2007-03-28
> 10:05:22.000000000 -0700
> +++ linux-2.6.21-rc5/arch/x86_64/kernel/io_apic.c 2007-03-28 10:18:52.000000000
> -0700
> @@ -1956,6 +1956,7 @@ static void set_msi_irq_affinity(unsigne
>  	msg.address_lo |= MSI_ADDR_DEST_ID(dest);
>  
>  	write_msi_msg(irq, &msg);
> +	msix_flush_writes(irq);
>  	irq_desc[irq].affinity = mask;
>  }
>  #endif /* CONFIG_SMP */
> diff -urpN -X dontdiff linux-2.6.21-rc5-clean/drivers/pci/msi.c
> linux-2.6.21-rc5/drivers/pci/msi.c
> --- linux-2.6.21-rc5-clean/drivers/pci/msi.c 2007-03-28 10:05:24.000000000 -0700
> +++ linux-2.6.21-rc5/drivers/pci/msi.c	2007-03-28 09:21:34.000000000 -0700
> @@ -68,6 +68,29 @@ static void msix_set_enable(struct pci_d
>  	}
>  }
>  
> +void msix_flush_writes(unsigned int irq)
> +{
> +	struct msi_desc *entry;
> +
> +	entry = get_irq_msi(irq);
> +	BUG_ON(!entry || !entry->dev);
> +	switch (entry->msi_attrib.type) {
> +	case PCI_CAP_ID_MSI:
> +		/* nothing to do */
> +		break;
> +	case PCI_CAP_ID_MSIX:
> +	{
> +		int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
> +			PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
> +		readl(entry->mask_base + offset);
> +		break;
> +	}
> +	default:
> +		BUG();
> +		break;
> +	}
> +}
> +
>  static void msi_set_mask_bit(unsigned int irq, int flag)
>  {
>  	struct msi_desc *entry;
> @@ -186,11 +209,13 @@ void write_msi_msg(unsigned int irq, str
>  void mask_msi_irq(unsigned int irq)
>  {
>  	msi_set_mask_bit(irq, 1);
> +	msix_flush_writes(irq);
>  }
>  
>  void unmask_msi_irq(unsigned int irq)
>  {
>  	msi_set_mask_bit(irq, 0);
> +	msix_flush_writes(irq);
>  }
>  
>  static int msi_free_irq(struct pci_dev* dev, int irq);
> diff -urpN -X dontdiff linux-2.6.21-rc5-clean/include/linux/msi.h
> linux-2.6.21-rc5/include/linux/msi.h
> --- linux-2.6.21-rc5-clean/include/linux/msi.h 2007-03-28 10:05:25.000000000
> -0700
> +++ linux-2.6.21-rc5/include/linux/msi.h 2007-03-28 09:21:51.000000000 -0700
> @@ -12,6 +12,7 @@ extern void mask_msi_irq(unsigned int ir
>  extern void unmask_msi_irq(unsigned int irq);
>  extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
>  extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);
> +extern void msix_flush_writes(unsigned int irq);
>  
>  struct msi_desc {
>  	struct {

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2)
  2007-03-29 16:41 [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2) Mitch Williams
  2007-03-29 16:59 ` Eric W. Biederman
@ 2007-03-29 17:25 ` Chuck Ebbert
  2007-03-29 17:31   ` Randy Dunlap
  2007-03-29 22:05   ` Williams, Mitch A
  1 sibling, 2 replies; 9+ messages in thread
From: Chuck Ebbert @ 2007-03-29 17:25 UTC (permalink / raw)
  To: Mitch Williams; +Cc: gregkh, linux-kernel, auke-jan.h.kok

Mitch Williams wrote:
> This patch fixes a kernel bug which is triggered when using the
> irqbalance daemon with MSI-X hardware.
> 
> Because both MSI-X interrupt messages and MSI-X table writes are posted,
> it's possible for them to cross while in-flight.  This results in
> interrupts being received long after the kernel thinks they're disabled,
> and in interrupts being sent to stale vectors after rebalancing.
> 
> This patch performs a read flush after writes to the MSI-X table for
> mask/unmask and rebalancing operations.
> 
> This patch has been validated with (unreleased) network hardware which
> uses MSI-X.
> 
> Revised with input from Eric Biederman.
> 
> Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
> 

Are you going to post one for 2.6.20 as well? Some people might be
interested...



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2)
  2007-03-29 17:25 ` Chuck Ebbert
@ 2007-03-29 17:31   ` Randy Dunlap
  2007-03-29 22:05   ` Williams, Mitch A
  1 sibling, 0 replies; 9+ messages in thread
From: Randy Dunlap @ 2007-03-29 17:31 UTC (permalink / raw)
  To: Chuck Ebbert; +Cc: Mitch Williams, gregkh, linux-kernel, auke-jan.h.kok

On Thu, 29 Mar 2007 13:25:34 -0400 Chuck Ebbert wrote:

> 
> Are you going to post one for 2.6.20 as well? Some people might be
> interested...

Please don't drop cc:s.

---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2)
  2007-03-29 16:59 ` Eric W. Biederman
@ 2007-03-29 22:01   ` Williams, Mitch A
  0 siblings, 0 replies; 9+ messages in thread
From: Williams, Mitch A @ 2007-03-29 22:01 UTC (permalink / raw)
  To: Eric W. Biederman; +Cc: linux-pci, gregkh, linux-kernel, akpm, Kok, Auke-jan H

Eric W. Biederman wrote:

>Do we still need the flush the set affinity routines?
>Shouldn't flush in mask and unmask should now be enough?

Yeah, I think you're right.  I've removed that call, and 
we're running some basic validation on the change.  I'll
post a new patch tomorrow AM.
-Mitch

^ permalink raw reply	[flat|nested] 9+ messages in thread

* RE: [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2)
  2007-03-29 17:25 ` Chuck Ebbert
  2007-03-29 17:31   ` Randy Dunlap
@ 2007-03-29 22:05   ` Williams, Mitch A
  2007-03-29 22:14     ` Chuck Ebbert
                       ` (2 more replies)
  1 sibling, 3 replies; 9+ messages in thread
From: Williams, Mitch A @ 2007-03-29 22:05 UTC (permalink / raw)
  To: Chuck Ebbert
  Cc: linux-pci, gregkh, ebiederm, linux-kernel, akpm, Kok, Auke-jan H

Chuck Ebbert wrote:
>Are you going to post one for 2.6.20 as well? Some people might be
>interested...

The first time I posted this patch, Greg KH indicated that he thought
it was too intrusive to add to -stable, especially considering that
our MSI-X capable hardware isn't in the field yet.

So the answer to your question is, "probably not".
-Mitch

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2)
  2007-03-29 22:05   ` Williams, Mitch A
@ 2007-03-29 22:14     ` Chuck Ebbert
  2007-03-30  5:02     ` Eric W. Biederman
  2007-03-30  5:03     ` Eric W. Biederman
  2 siblings, 0 replies; 9+ messages in thread
From: Chuck Ebbert @ 2007-03-29 22:14 UTC (permalink / raw)
  To: Williams, Mitch A
  Cc: linux-pci, gregkh, ebiederm, linux-kernel, akpm, Kok, Auke-jan H

Williams, Mitch A wrote:
> Chuck Ebbert wrote:
>> Are you going to post one for 2.6.20 as well? Some people might be
>> interested...
> 
> The first time I posted this patch, Greg KH indicated that he thought
> it was too intrusive to add to -stable, especially considering that
> our MSI-X capable hardware isn't in the field yet.
> 
> So the answer to your question is, "probably not".

So it's not useful in 2.6.20 for anything that's available today, from
any vendor? We can put it in Fedora if you think it is.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2)
  2007-03-29 22:05   ` Williams, Mitch A
  2007-03-29 22:14     ` Chuck Ebbert
@ 2007-03-30  5:02     ` Eric W. Biederman
  2007-03-30  5:03     ` Eric W. Biederman
  2 siblings, 0 replies; 9+ messages in thread
From: Eric W. Biederman @ 2007-03-30  5:02 UTC (permalink / raw)
  To: Williams, Mitch A
  Cc: Chuck Ebbert, linux-pci, gregkh, linux-kernel, akpm,
	Kok, Auke-jan H

"Williams, Mitch A" <mitch.a.williams@intel.com> writes:

> Chuck Ebbert wrote:
>>Are you going to post one for 2.6.20 as well? Some people might be
>>interested...
>
> The first time I posted this patch, Greg KH indicated that he thought
> it was too intrusive to add to -stable, especially considering that
> our MSI-X capable hardware isn't in the field yet.

There is MSI-X capable hardware supported by the kernel in 2.6.20.

The last version of your patch with the code removed from the set_affinity
path is not very intrusive at all, as it just touches msi.c

Eric

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2)
  2007-03-29 22:05   ` Williams, Mitch A
  2007-03-29 22:14     ` Chuck Ebbert
  2007-03-30  5:02     ` Eric W. Biederman
@ 2007-03-30  5:03     ` Eric W. Biederman
  2 siblings, 0 replies; 9+ messages in thread
From: Eric W. Biederman @ 2007-03-30  5:03 UTC (permalink / raw)
  To: Williams, Mitch A
  Cc: Chuck Ebbert, linux-pci, gregkh, linux-kernel, akpm,
	Kok, Auke-jan H

"Williams, Mitch A" <mitch.a.williams@intel.com> writes:

> Chuck Ebbert wrote:
>>Are you going to post one for 2.6.20 as well? Some people might be
>>interested...
>
> The first time I posted this patch, Greg KH indicated that he thought
> it was too intrusive to add to -stable, especially considering that
> our MSI-X capable hardware isn't in the field yet.

There is MSI-X capable hardware supported by the kernel in 2.6.20.

The last version of your patch with the code removed from the set_affinity
path is not very intrusive at all, as it just touches msi.c

Eric

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2007-03-30  5:03 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-03-29 16:41 [PATCH 2.6.21-rc5] MSI: read-flush MSI-X table (rev 2) Mitch Williams
2007-03-29 16:59 ` Eric W. Biederman
2007-03-29 22:01   ` Williams, Mitch A
2007-03-29 17:25 ` Chuck Ebbert
2007-03-29 17:31   ` Randy Dunlap
2007-03-29 22:05   ` Williams, Mitch A
2007-03-29 22:14     ` Chuck Ebbert
2007-03-30  5:02     ` Eric W. Biederman
2007-03-30  5:03     ` Eric W. Biederman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.