Messages in this thread Patch in this message | | | From | Jesse Barnes <> | Subject | Re: PCI MSI breaks when booting with nosmp | Date | Mon, 21 Apr 2008 12:35:23 -0700 |
| |
On Monday, April 21, 2008 12:06 pm Jesse Barnes wrote: > On Monday, April 21, 2008 11:45 am Andi Kleen wrote: > > Jesse Barnes <jbarnes@virtuousgeek.org> writes: > > > Ok, I see this too on my desktop machine. It looks like we're not > > > getting interrupts setup correctly in the nosmp case. Still digging > > > through to see why though... > > > > NoSMP disables the io-apic and a lot of modern systems don't work without > > APIC. > > > > If you just want to run with a single cpu for testing etc. always use > > maxcpus=1 (not 0, that will disable the APIC too) > > Right... but it looks like the MSI code is buggy when noapic is specified > via nosmp or maxcpus=0. We should either fix it to work with noapic or > disable it like we do the ioapic when nosmp or maxcpus=0:
Or if you want something that compiles & works (at least on my machine) here it is. But the fact that noapic alone doesn't cause the bug means there's probably something depending on !setup_max_cpus that needs fixing instead.
Jesse
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index eabeb1f..9170589 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -39,14 +39,6 @@ extern struct rw_semaphore pci_bus_sem; extern unsigned int pci_pm_d3_delay; -#ifdef CONFIG_PCI_MSI -void pci_no_msi(void); -extern void pci_msi_init_pci_dev(struct pci_dev *dev); -#else -static inline void pci_no_msi(void) { } -static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } -#endif - #ifdef CONFIG_PCIEAER void pci_no_aer(void); #else diff --git a/include/linux/pci.h b/include/linux/pci.h index ea760e5..0ed53d6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -590,6 +590,13 @@ int pci_try_set_mwi(struct pci_dev *dev); void pci_clear_mwi(struct pci_dev *dev); void pci_intx(struct pci_dev *dev, int enable); void pci_msi_off(struct pci_dev *dev); +#ifdef CONFIG_PCI_MSI +void pci_no_msi(void); +extern void pci_msi_init_pci_dev(struct pci_dev *dev); +#else +static inline void pci_no_msi(void) { } +static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } +#endif int pci_set_dma_mask(struct pci_dev *dev, u64 mask); int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size); diff --git a/init/main.c b/init/main.c index 99ce949..a9436b7 100644 --- a/init/main.c +++ b/init/main.c @@ -58,6 +58,7 @@ #include <linux/kthread.h> #include <linux/sched.h> #include <linux/signal.h> +#include <linux/pci.h> #include <asm/io.h> #include <asm/bugs.h> @@ -148,6 +149,7 @@ static int __init nosmp(char *str) { setup_max_cpus = 0; disable_ioapic_setup(); + pci_no_msi(); return 0; } @@ -156,9 +158,10 @@ early_param("nosmp", nosmp); static int __init maxcpus(char *str) { get_option(&str, &setup_max_cpus); - if (setup_max_cpus == 0) + if (setup_max_cpus == 0) { disable_ioapic_setup(); - + pci_no_msi(); + } return 0; }
| |