* linux-next: OOPS at bot time @ 2010-07-23 0:22 Stephen Rothwell 2010-07-23 1:19 ` Ben Hutchings 0 siblings, 1 reply; 9+ messages in thread From: Stephen Rothwell @ 2010-07-23 0:22 UTC (permalink / raw) To: ppc-dev; +Cc: Ben Hutchings, LKML, Jesse Barnes [-- Attachment #1: Type: text/plain, Size: 3532 bytes --] Hi all, My Power7 boot test paniced like this: (next-20100722) %GQLogic Fibre Channel HBA Driver: 8.03.03-k0 qla2xxx 0002:01:00.2: enabling device (0144 -> 0146) qla2xxx 0002:01:00.2: Found an ISP8001, irq 35, iobase 0xd000080080014000 ------------[ cut here ]------------ kernel BUG at drivers/pci/msi.c:205! Oops: Exception in kernel mode, sig: 5 [#1] SMP NR_CPUS=128 NUMA pSeries last sysfs file: /sys/devices/virtual/tty/ptyz8/uevent Modules linked in: qla2xxx(+) NIP: c0000000002fcd54 LR: c000000000048d9c CTR: 0000000000000001 REGS: c00000000278aff0 TRAP: 0700 Not tainted (2.6.35-rc5-autokern1-next-20100721) MSR: 8000000000029032 <EE,ME,CE,IR,DR> CR: 28422488 XER: 20000008 TASK = c000000002008000[2226] 'modprobe' THREAD: c000000002788000 CPU: 12 GPR00: 0000000000000001 c00000000278b270 c0000000009a36d0 c0000000009b8900 GPR04: c00000000278b2e8 ffffffffffffffff 0000000000000000 0000000000020000 GPR08: 00000000000033e7 c00000000a38b280 0000000000000000 0000000000000000 GPR12: 0000000088422488 c00000000f331800 00000fff921750a0 0000000000000000 GPR16: 0000000010033110 00000000100334b8 0000000000000000 0000000000000000 GPR20: d000080080018000 0000000000022225 c0000000009f7bb4 0000000000010200 GPR24: 000000002000020d 0000000000000025 c00000000278b2e0 c00000000278b2e8 GPR28: 0000000000000001 c00000000d0ac5f8 c000000000af8f00 c00000000a38b280 NIP [c0000000002fcd54] .read_msi_msg_desc+0x24/0x3c LR [c000000000048d9c] .rtas_setup_msi_irqs+0x1d8/0x254 Call Trace: [c00000000278b270] [c000000000048d9c] .rtas_setup_msi_irqs+0x1d8/0x254 (unreliable) [c00000000278b360] [c00000000002a9cc] .arch_setup_msi_irqs+0x34/0x4c [c00000000278b3e0] [c0000000002fd3fc] .pci_enable_msix+0x49c/0x4ac [c00000000278b4c0] [d0000000001a5e30] .qla2x00_request_irqs+0x158/0x5b4 [qla2xxx] [c00000000278b580] [d0000000001cb41c] .qla2x00_probe_one+0xeac/0x63b0 [qla2xxx] [c00000000278b6f0] [c0000000002f5c4c] .local_pci_probe+0x34/0x48 [c00000000278b760] [c0000000002f6078] .pci_device_probe+0xe8/0x130 [c00000000278b810] [c00000000036e648] .driver_probe_device+0xdc/0x1a4 [c00000000278b8a0] [c00000000036e7a4] .__driver_attach+0x94/0xd8 [c00000000278b930] [c00000000036dabc] .bus_for_each_dev+0x7c/0xe0 [c00000000278b9e0] [c00000000036e410] .driver_attach+0x28/0x40 [c00000000278ba60] [c00000000036d134] .bus_add_driver+0x144/0x310 [c00000000278bb10] [c00000000036ec28] .driver_register+0xd8/0x198 [c00000000278bbb0] [c0000000002f63d0] .__pci_register_driver+0x60/0x10c [c00000000278bc50] [d0000000001ca520] .qla2x00_module_init+0x150/0x1a0 [qla2xxx] [c00000000278bce0] [c00000000000947c] .do_one_initcall+0x80/0x1a8 [c00000000278bd90] [c0000000000a4364] .SyS_init_module+0xd8/0x244 [c00000000278be30] [c00000000000852c] syscall_exit+0x0/0x40 Instruction dump: ebe1fff8 7c0803a6 4e800020 e9230028 81490030 80090034 81690038 7d400378 7c005b78 7c000034 5400d97e 78000020 <0b000000> 81690038 e8090030 91640008 ---[ end trace f67a78811ed47c60 ]--- %Gudevd-work[1379]: '/sbin/modprobe -b pci:v00001077d00008001sv00001077sd0000017Fbc0Csc04i00' unexpected exit with status 0x0005 That line number is this: BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo | entry->msg.data)); in read_msi_msg_desc(). That BUG_ON was added by commit 2ca1af9aa3285c6a5f103ed31ad09f7399fc65d7 ("PCI: MSI: Remove unsafe and unnecessary hardware access") from the pci tree. -- Cheers, Stephen Rothwell sfr@canb.auug.org.au http://www.canb.auug.org.au/~sfr/ [-- Attachment #2: Type: application/pgp-signature, Size: 490 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: linux-next: OOPS at bot time 2010-07-23 0:22 linux-next: OOPS at bot time Stephen Rothwell @ 2010-07-23 1:19 ` Ben Hutchings 2010-07-23 2:05 ` Michael Ellerman 0 siblings, 1 reply; 9+ messages in thread From: Ben Hutchings @ 2010-07-23 1:19 UTC (permalink / raw) To: Stephen Rothwell; +Cc: ppc-dev, LKML, Jesse Barnes On Fri, 2010-07-23 at 10:22 +1000, Stephen Rothwell wrote: > Hi all, > > My Power7 boot test paniced like this: (next-20100722) > > %GQLogic Fibre Channel HBA Driver: 8.03.03-k0 > qla2xxx 0002:01:00.2: enabling device (0144 -> 0146) > qla2xxx 0002:01:00.2: Found an ISP8001, irq 35, iobase 0xd000080080014000 > ------------[ cut here ]------------ > kernel BUG at drivers/pci/msi.c:205! [...] > Call Trace: > [c00000000278b270] [c000000000048d9c] .rtas_setup_msi_irqs+0x1d8/0x254 (unreliable) > [c00000000278b360] [c00000000002a9cc] .arch_setup_msi_irqs+0x34/0x4c > [c00000000278b3e0] [c0000000002fd3fc] .pci_enable_msix+0x49c/0x4ac [...] > That line number is this: > > BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo | > entry->msg.data)); > > in read_msi_msg_desc(). That BUG_ON was added by commit > 2ca1af9aa3285c6a5f103ed31ad09f7399fc65d7 ("PCI: MSI: Remove unsafe and > unnecessary hardware access") from the pci tree. I wanted to assert that read_msi_msg_desc() is only used to update MSI/MSI-X descriptors that have already been generated by Linux. It looks like you found an exception. We could make read_msi_msg() fall back to reading from the hardware, but I think that what the pSeries code is trying to do - save an MSI message generated by firmware - is different from what the other callers want. Instead we could add: void save_msi_msg(unsigned int irq) { struct irq_desc *desc = irq_to_desc(irq); struct msi_desc *entry = get_irq_desc_msi(desc); struct msi_msg *msg = &entry->msg; /* ...followed by the old implementation of read_msi_msg_desc() */ } Possibly conditional on something like CONFIG_ARCH_NEEDS_SAVE_MSI_MSG. Ben. -- Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: linux-next: OOPS at bot time 2010-07-23 1:19 ` Ben Hutchings @ 2010-07-23 2:05 ` Michael Ellerman 2010-07-23 13:56 ` [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() Ben Hutchings 0 siblings, 1 reply; 9+ messages in thread From: Michael Ellerman @ 2010-07-23 2:05 UTC (permalink / raw) To: Ben Hutchings; +Cc: Stephen Rothwell, ppc-dev, LKML, Jesse Barnes [-- Attachment #1: Type: text/plain, Size: 2133 bytes --] On Fri, 2010-07-23 at 02:19 +0100, Ben Hutchings wrote: > On Fri, 2010-07-23 at 10:22 +1000, Stephen Rothwell wrote: > > Hi all, > > > > My Power7 boot test paniced like this: (next-20100722) > > > > %GQLogic Fibre Channel HBA Driver: 8.03.03-k0 > > qla2xxx 0002:01:00.2: enabling device (0144 -> 0146) > > qla2xxx 0002:01:00.2: Found an ISP8001, irq 35, iobase 0xd000080080014000 > > ------------[ cut here ]------------ > > kernel BUG at drivers/pci/msi.c:205! > [...] > > Call Trace: > > [c00000000278b270] [c000000000048d9c] .rtas_setup_msi_irqs+0x1d8/0x254 (unreliable) > > [c00000000278b360] [c00000000002a9cc] .arch_setup_msi_irqs+0x34/0x4c > > [c00000000278b3e0] [c0000000002fd3fc] .pci_enable_msix+0x49c/0x4ac > [...] > > That line number is this: > > > > BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo | > > entry->msg.data)); > > > > in read_msi_msg_desc(). That BUG_ON was added by commit > > 2ca1af9aa3285c6a5f103ed31ad09f7399fc65d7 ("PCI: MSI: Remove unsafe and > > unnecessary hardware access") from the pci tree. > > I wanted to assert that read_msi_msg_desc() is only used to update > MSI/MSI-X descriptors that have already been generated by Linux. It > looks like you found an exception. > > We could make read_msi_msg() fall back to reading from the hardware, but > I think that what the pSeries code is trying to do - save an MSI message > generated by firmware - is different from what the other callers want. > Instead we could add: > > void save_msi_msg(unsigned int irq) > { > struct irq_desc *desc = irq_to_desc(irq); > struct msi_desc *entry = get_irq_desc_msi(desc); > struct msi_msg *msg = &entry->msg; > > /* ...followed by the old implementation of read_msi_msg_desc() */ > } > > Possibly conditional on something like CONFIG_ARCH_NEEDS_SAVE_MSI_MSG. Maybe. But then you end up with read_msi_msg(), which doesn't actually read anything, which I think is confusing. I'd rather read_msi_msg() read the message, from the device, and we have another routine which returns the previously saved msg from the msi_desc. cheers [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 198 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() 2010-07-23 2:05 ` Michael Ellerman @ 2010-07-23 13:56 ` Ben Hutchings 2010-07-26 11:20 ` Michael Ellerman ` (2 more replies) 0 siblings, 3 replies; 9+ messages in thread From: Ben Hutchings @ 2010-07-23 13:56 UTC (permalink / raw) To: Jesse Barnes; +Cc: Stephen Rothwell, ppc-dev, LKML, linux-pci commit 2ca1af9aa3285c6a5f103ed31ad09f7399fc65d7 "PCI: MSI: Remove unsafe and unnecessary hardware access" changed read_msi_msg_desc() to return the last MSI message written instead of reading it from the device, since it may be called while the device is in a reduced power state. However, the pSeries platform code really does need to read messages from the device, since they are initially written by firmware. Therefore: - Restore the previous behaviour of read_msi_msg_desc() - Add new functions get_cached_msi_msg{,_desc}() which return the last MSI message written - Use the new functions where appropriate Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> --- Compile-tested only. Ben. arch/ia64/kernel/msi_ia64.c | 2 +- arch/ia64/sn/kernel/msi_sn.c | 2 +- arch/x86/kernel/apic/io_apic.c | 2 +- drivers/pci/msi.c | 47 +++++++++++++++++++++++++++++++++++---- include/linux/msi.h | 2 + 5 files changed, 47 insertions(+), 8 deletions(-) diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c index 6c89228..4a746ea 100644 --- a/arch/ia64/kernel/msi_ia64.c +++ b/arch/ia64/kernel/msi_ia64.c @@ -25,7 +25,7 @@ static int ia64_set_msi_irq_affinity(unsigned int irq, if (irq_prepare_move(irq, cpu)) return -1; - read_msi_msg(irq, &msg); + get_cached_msi_msg(irq, &msg); addr = msg.address_lo; addr &= MSI_ADDR_DEST_ID_MASK; diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index ebfdd6a..0c72dd4 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -175,7 +175,7 @@ static int sn_set_msi_irq_affinity(unsigned int irq, * Release XIO resources for the old MSI PCI address */ - read_msi_msg(irq, &msg); + get_cached_msi_msg(irq, &msg); sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; pdev = sn_pdev->pdi_linux_pcidev; provider = SN_PCIDEV_BUSPROVIDER(pdev); diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index e41ed24..4dc0084 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -3397,7 +3397,7 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) cfg = desc->chip_data; - read_msi_msg_desc(desc, &msg); + get_cached_msi_msg_desc(desc, &msg); msg.data &= ~MSI_DATA_VECTOR_MASK; msg.data |= MSI_DATA_VECTOR(cfg->vector); diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 4c14f31..69b7be3 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -197,9 +197,46 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) { struct msi_desc *entry = get_irq_desc_msi(desc); - /* We do not touch the hardware (which may not even be - * accessible at the moment) but return the last message - * written. Assert that this is valid, assuming that + BUG_ON(entry->dev->current_state != PCI_D0); + + if (entry->msi_attrib.is_msix) { + void __iomem *base = entry->mask_base + + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; + + msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); + msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); + msg->data = readl(base + PCI_MSIX_ENTRY_DATA); + } else { + struct pci_dev *dev = entry->dev; + int pos = entry->msi_attrib.pos; + u16 data; + + pci_read_config_dword(dev, msi_lower_address_reg(pos), + &msg->address_lo); + if (entry->msi_attrib.is_64) { + pci_read_config_dword(dev, msi_upper_address_reg(pos), + &msg->address_hi); + pci_read_config_word(dev, msi_data_reg(pos, 1), &data); + } else { + msg->address_hi = 0; + pci_read_config_word(dev, msi_data_reg(pos, 0), &data); + } + msg->data = data; + } +} + +void read_msi_msg(unsigned int irq, struct msi_msg *msg) +{ + struct irq_desc *desc = irq_to_desc(irq); + + read_msi_msg_desc(desc, msg); +} + +void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) +{ + struct msi_desc *entry = get_irq_desc_msi(desc); + + /* Assert that the cache is valid, assuming that * valid messages are not all-zeroes. */ BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo | entry->msg.data)); @@ -207,11 +244,11 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) *msg = entry->msg; } -void read_msi_msg(unsigned int irq, struct msi_msg *msg) +void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg) { struct irq_desc *desc = irq_to_desc(irq); - read_msi_msg_desc(desc, msg); + get_cached_msi_msg_desc(desc, msg); } void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) diff --git a/include/linux/msi.h b/include/linux/msi.h index 6991ab5..91b05c1 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -14,8 +14,10 @@ struct irq_desc; extern void mask_msi_irq(unsigned int irq); extern void unmask_msi_irq(unsigned int irq); extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); +extern void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); extern void read_msi_msg(unsigned int irq, struct msi_msg *msg); +extern void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); extern void write_msi_msg(unsigned int irq, struct msi_msg *msg); struct msi_desc { -- 1.6.2.5 -- Ben Hutchings, Senior Software Engineer, Solarflare Communications Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked. ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() 2010-07-23 13:56 ` [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() Ben Hutchings @ 2010-07-26 11:20 ` Michael Ellerman 2010-07-30 16:42 ` Jesse Barnes 2012-11-20 7:20 ` Benjamin Herrenschmidt 2 siblings, 0 replies; 9+ messages in thread From: Michael Ellerman @ 2010-07-26 11:20 UTC (permalink / raw) To: Ben Hutchings; +Cc: Stephen Rothwell, ppc-dev, LKML, Jesse Barnes, linux-pci [-- Attachment #1: Type: text/plain, Size: 809 bytes --] On Fri, 2010-07-23 at 14:56 +0100, Ben Hutchings wrote: > commit 2ca1af9aa3285c6a5f103ed31ad09f7399fc65d7 "PCI: MSI: Remove > unsafe and unnecessary hardware access" changed read_msi_msg_desc() to > return the last MSI message written instead of reading it from the > device, since it may be called while the device is in a reduced > power state. > > However, the pSeries platform code really does need to read messages > from the device, since they are initially written by firmware. > Therefore: > - Restore the previous behaviour of read_msi_msg_desc() > - Add new functions get_cached_msi_msg{,_desc}() which return the > last MSI message written > - Use the new functions where appropriate > > Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Looks good to me. cheers [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 198 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() 2010-07-23 13:56 ` [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() Ben Hutchings 2010-07-26 11:20 ` Michael Ellerman @ 2010-07-30 16:42 ` Jesse Barnes 2010-08-01 6:23 ` Michael Ellerman 2012-11-20 7:20 ` Benjamin Herrenschmidt 2 siblings, 1 reply; 9+ messages in thread From: Jesse Barnes @ 2010-07-30 16:42 UTC (permalink / raw) To: Ben Hutchings; +Cc: Stephen Rothwell, ppc-dev, LKML, linux-pci On Fri, 23 Jul 2010 14:56:28 +0100 Ben Hutchings <bhutchings@solarflare.com> wrote: > commit 2ca1af9aa3285c6a5f103ed31ad09f7399fc65d7 "PCI: MSI: Remove > unsafe and unnecessary hardware access" changed read_msi_msg_desc() to > return the last MSI message written instead of reading it from the > device, since it may be called while the device is in a reduced > power state. > > However, the pSeries platform code really does need to read messages > from the device, since they are initially written by firmware. > Therefore: > - Restore the previous behaviour of read_msi_msg_desc() > - Add new functions get_cached_msi_msg{,_desc}() which return the > last MSI message written > - Use the new functions where appropriate > > Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> > --- > Compile-tested only. > Applied to linux-next with Michael's ack, thanks. I hope it actually works, I didn't see a tested-by! -- Jesse Barnes, Intel Open Source Technology Center ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() 2010-07-30 16:42 ` Jesse Barnes @ 2010-08-01 6:23 ` Michael Ellerman 0 siblings, 0 replies; 9+ messages in thread From: Michael Ellerman @ 2010-08-01 6:23 UTC (permalink / raw) To: Jesse Barnes; +Cc: Ben Hutchings, Stephen Rothwell, ppc-dev, LKML, linux-pci [-- Attachment #1: Type: text/plain, Size: 1234 bytes --] On Fri, 2010-07-30 at 09:42 -0700, Jesse Barnes wrote: > On Fri, 23 Jul 2010 14:56:28 +0100 > Ben Hutchings <bhutchings@solarflare.com> wrote: > > > commit 2ca1af9aa3285c6a5f103ed31ad09f7399fc65d7 "PCI: MSI: Remove > > unsafe and unnecessary hardware access" changed read_msi_msg_desc() to > > return the last MSI message written instead of reading it from the > > device, since it may be called while the device is in a reduced > > power state. > > > > However, the pSeries platform code really does need to read messages > > from the device, since they are initially written by firmware. > > Therefore: > > - Restore the previous behaviour of read_msi_msg_desc() > > - Add new functions get_cached_msi_msg{,_desc}() which return the > > last MSI message written > > - Use the new functions where appropriate > > > > Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> > > --- > > Compile-tested only. > > > > Applied to linux-next with Michael's ack, thanks. I hope it actually > works, I didn't see a tested-by! I assume Stephen has been using it, otherwise his linux-next boot tests will all have been failing. Either way he'll test it when it gets into linux-next proper. cheers [-- Attachment #2: This is a digitally signed message part --] [-- Type: application/pgp-signature, Size: 198 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() 2010-07-23 13:56 ` [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() Ben Hutchings 2010-07-26 11:20 ` Michael Ellerman 2010-07-30 16:42 ` Jesse Barnes @ 2012-11-20 7:20 ` Benjamin Herrenschmidt 2012-11-20 12:36 ` Ben Hutchings 2 siblings, 1 reply; 9+ messages in thread From: Benjamin Herrenschmidt @ 2012-11-20 7:20 UTC (permalink / raw) To: Ben Hutchings Cc: Stephen Rothwell, linux-pci, LKML, Jesse Barnes, Bjorn Helgaas, ppc-dev On Fri, 2010-07-23 at 14:56 +0100, Ben Hutchings wrote: > commit 2ca1af9aa3285c6a5f103ed31ad09f7399fc65d7 "PCI: MSI: Remove > unsafe and unnecessary hardware access" changed read_msi_msg_desc() to > return the last MSI message written instead of reading it from the > device, since it may be called while the device is in a reduced > power state. Looks reasonable... Jesse ? Cheers, Ben. > However, the pSeries platform code really does need to read messages > from the device, since they are initially written by firmware. > Therefore: > - Restore the previous behaviour of read_msi_msg_desc() > - Add new functions get_cached_msi_msg{,_desc}() which return the > last MSI message written > - Use the new functions where appropriate > > Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> > --- > Compile-tested only. > > Ben. > > arch/ia64/kernel/msi_ia64.c | 2 +- > arch/ia64/sn/kernel/msi_sn.c | 2 +- > arch/x86/kernel/apic/io_apic.c | 2 +- > drivers/pci/msi.c | 47 +++++++++++++++++++++++++++++++++++---- > include/linux/msi.h | 2 + > 5 files changed, 47 insertions(+), 8 deletions(-) > > diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c > index 6c89228..4a746ea 100644 > --- a/arch/ia64/kernel/msi_ia64.c > +++ b/arch/ia64/kernel/msi_ia64.c > @@ -25,7 +25,7 @@ static int ia64_set_msi_irq_affinity(unsigned int irq, > if (irq_prepare_move(irq, cpu)) > return -1; > > - read_msi_msg(irq, &msg); > + get_cached_msi_msg(irq, &msg); > > addr = msg.address_lo; > addr &= MSI_ADDR_DEST_ID_MASK; > diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c > index ebfdd6a..0c72dd4 100644 > --- a/arch/ia64/sn/kernel/msi_sn.c > +++ b/arch/ia64/sn/kernel/msi_sn.c > @@ -175,7 +175,7 @@ static int sn_set_msi_irq_affinity(unsigned int irq, > * Release XIO resources for the old MSI PCI address > */ > > - read_msi_msg(irq, &msg); > + get_cached_msi_msg(irq, &msg); > sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; > pdev = sn_pdev->pdi_linux_pcidev; > provider = SN_PCIDEV_BUSPROVIDER(pdev); > diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c > index e41ed24..4dc0084 100644 > --- a/arch/x86/kernel/apic/io_apic.c > +++ b/arch/x86/kernel/apic/io_apic.c > @@ -3397,7 +3397,7 @@ static int set_msi_irq_affinity(unsigned int irq, const struct cpumask *mask) > > cfg = desc->chip_data; > > - read_msi_msg_desc(desc, &msg); > + get_cached_msi_msg_desc(desc, &msg); > > msg.data &= ~MSI_DATA_VECTOR_MASK; > msg.data |= MSI_DATA_VECTOR(cfg->vector); > diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c > index 4c14f31..69b7be3 100644 > --- a/drivers/pci/msi.c > +++ b/drivers/pci/msi.c > @@ -197,9 +197,46 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) > { > struct msi_desc *entry = get_irq_desc_msi(desc); > > - /* We do not touch the hardware (which may not even be > - * accessible at the moment) but return the last message > - * written. Assert that this is valid, assuming that > + BUG_ON(entry->dev->current_state != PCI_D0); > + > + if (entry->msi_attrib.is_msix) { > + void __iomem *base = entry->mask_base + > + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; > + > + msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); > + msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); > + msg->data = readl(base + PCI_MSIX_ENTRY_DATA); > + } else { > + struct pci_dev *dev = entry->dev; > + int pos = entry->msi_attrib.pos; > + u16 data; > + > + pci_read_config_dword(dev, msi_lower_address_reg(pos), > + &msg->address_lo); > + if (entry->msi_attrib.is_64) { > + pci_read_config_dword(dev, msi_upper_address_reg(pos), > + &msg->address_hi); > + pci_read_config_word(dev, msi_data_reg(pos, 1), &data); > + } else { > + msg->address_hi = 0; > + pci_read_config_word(dev, msi_data_reg(pos, 0), &data); > + } > + msg->data = data; > + } > +} > + > +void read_msi_msg(unsigned int irq, struct msi_msg *msg) > +{ > + struct irq_desc *desc = irq_to_desc(irq); > + > + read_msi_msg_desc(desc, msg); > +} > + > +void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) > +{ > + struct msi_desc *entry = get_irq_desc_msi(desc); > + > + /* Assert that the cache is valid, assuming that > * valid messages are not all-zeroes. */ > BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo | > entry->msg.data)); > @@ -207,11 +244,11 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) > *msg = entry->msg; > } > > -void read_msi_msg(unsigned int irq, struct msi_msg *msg) > +void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg) > { > struct irq_desc *desc = irq_to_desc(irq); > > - read_msi_msg_desc(desc, msg); > + get_cached_msi_msg_desc(desc, msg); > } > > void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) > diff --git a/include/linux/msi.h b/include/linux/msi.h > index 6991ab5..91b05c1 100644 > --- a/include/linux/msi.h > +++ b/include/linux/msi.h > @@ -14,8 +14,10 @@ struct irq_desc; > extern void mask_msi_irq(unsigned int irq); > extern void unmask_msi_irq(unsigned int irq); > extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); > +extern void get_cached_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); > extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); > extern void read_msi_msg(unsigned int irq, struct msi_msg *msg); > +extern void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg); > extern void write_msi_msg(unsigned int irq, struct msi_msg *msg); > > struct msi_desc { > -- > 1.6.2.5 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() 2012-11-20 7:20 ` Benjamin Herrenschmidt @ 2012-11-20 12:36 ` Ben Hutchings 0 siblings, 0 replies; 9+ messages in thread From: Ben Hutchings @ 2012-11-20 12:36 UTC (permalink / raw) To: Benjamin Herrenschmidt Cc: Stephen Rothwell, linux-pci, LKML, Jesse Barnes, Bjorn Helgaas, ppc-dev On Tue, 2012-11-20 at 18:20 +1100, Benjamin Herrenschmidt wrote: > On Fri, 2010-07-23 at 14:56 +0100, Ben Hutchings wrote: > > commit 2ca1af9aa3285c6a5f103ed31ad09f7399fc65d7 "PCI: MSI: Remove > > unsafe and unnecessary hardware access" changed read_msi_msg_desc() to > > return the last MSI message written instead of reading it from the > > device, since it may be called while the device is in a reduced > > power state. > > Looks reasonable... Jesse ? [...] So reasonable that it was committed a couple of years ago! Where did you dredge this from? Ben. -- Ben Hutchings, Staff Engineer, Solarflare Not speaking for my employer; that's the marketing department's job. They asked us to note that Solarflare product names are trademarked. ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2012-11-20 12:42 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-07-23 0:22 linux-next: OOPS at bot time Stephen Rothwell 2010-07-23 1:19 ` Ben Hutchings 2010-07-23 2:05 ` Michael Ellerman 2010-07-23 13:56 ` [PATCH] PCI: MSI: Restore read_msi_msg_desc(); add get_cached_msi_msg_desc() Ben Hutchings 2010-07-26 11:20 ` Michael Ellerman 2010-07-30 16:42 ` Jesse Barnes 2010-08-01 6:23 ` Michael Ellerman 2012-11-20 7:20 ` Benjamin Herrenschmidt 2012-11-20 12:36 ` Ben Hutchings
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).