* [RFC PATCH 1/2] pci: determine CLS more intelligently
@ 2009-06-25 7:12 Tejun Heo
2009-06-25 7:12 ` [RFC PATCH 2/2] pccard: configure CLS on attach Tejun Heo
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Tejun Heo @ 2009-06-25 7:12 UTC (permalink / raw)
To: Greg KH, Robert Hancock, Alan Cox, linux-pci, Linux Kernel,
Daniel Ritz, Dominik Brodowski, Kenji Kaneshige, Axel Birndt,
Benjamin Herrenschmidt, Ingo Molnar, Thomas Gleixner, Tony Luck,
David Miller, Ingo Molnar
Till now, CLS has been determined either by arch code or as
L1_CACHE_BYTES. Only x86 and ia64 set CLS explicitly and x86 doesn't
always get it right. On most configurations, the chance is that
firmware configures the correct value during boot.
This patch makes pci_init() determine CLS by looking at what firmware
has configured. It scans all devices and if all non-zero values
agree, the value is used. If none is configured or there is a
disagreement, pci_dfl_cache_line_size is used. arch can set the dfl
value (via PCI_CACHE_LINE_BYTES or pci_dfl_cache_line_size) or
override the actual one.
ia64, x86 and sparc64 updated to set the default cls instead of the
actual one. sparc64 is currently the only one using
PCI_CACHE_LINE_BYTES. It would be nice to update it to set the
default variable instead.
RFC PATCH, PLEASE DON'T APPLY YET.
Cc: Greg KH <gregkh@suse.de>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Tony Luck <tony.luck@intel.com>
Cc: David Miller <davem@davemloft.net>
---
These two patches are refreshed version of the following patch.
http://thread.gmane.org/gmane.linux.kernel.pci/4418/focus=4431
This patch improves how CLS is determined and was written mainly
because the original code didn't get it right on my laptop (lenovo
x61s, the determined value was 32 but the value bios used for other
devices was 64). For x86, maybe we can remove the arch specific
configuration codes in the long run?
Seems to work fine on my test machine and laptop. Also builds fine
for powerpc64 and sparc64.
Axel, to test, you'll need to build a vanialla kernel with the patches
applied. There are pretty good docs about doing that on the web.
Thanks.
arch/ia64/pci/pci.c | 8 ++++----
arch/x86/pci/common.c | 8 ++++----
drivers/pci/pci.c | 49 +++++++++++++++++++++++++++++++++++++++++--------
3 files changed, 49 insertions(+), 16 deletions(-)
Index: work/arch/ia64/pci/pci.c
===================================================================
--- work.orig/arch/ia64/pci/pci.c
+++ work/arch/ia64/pci/pci.c
@@ -716,7 +716,7 @@ int ia64_pci_legacy_write(struct pci_bus
}
/* It's defined in drivers/pci/pci.c */
-extern u8 pci_cache_line_size;
+extern u8 pci_dfl_cache_line_size;
/**
* set_pci_cacheline_size - determine cacheline size for PCI devices
@@ -726,7 +726,7 @@ extern u8 pci_cache_line_size;
*
* Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
*/
-static void __init set_pci_cacheline_size(void)
+static void __init set_pci_dfl_cacheline_size(void)
{
unsigned long levels, unique_caches;
long status;
@@ -746,7 +746,7 @@ static void __init set_pci_cacheline_siz
"(status=%ld)\n", __func__, status);
return;
}
- pci_cache_line_size = (1 << cci.pcci_line_size) / 4;
+ pci_dfl_cache_line_size = (1 << cci.pcci_line_size) / 4;
}
u64 ia64_dma_get_required_mask(struct device *dev)
@@ -777,7 +777,7 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask)
static int __init pcibios_init(void)
{
- set_pci_cacheline_size();
+ set_pci_dfl_cacheline_size();
return 0;
}
Index: work/arch/x86/pci/common.c
===================================================================
--- work.orig/arch/x86/pci/common.c
+++ work/arch/x86/pci/common.c
@@ -410,7 +410,7 @@ struct pci_bus * __devinit pcibios_scan_
return bus;
}
-extern u8 pci_cache_line_size;
+extern u8 pci_dfl_cache_line_size;
int __init pcibios_init(void)
{
@@ -426,11 +426,11 @@ int __init pcibios_init(void)
* and P4. It's also good for 386/486s (which actually have 16)
* as quite a few PCI devices do not support smaller values.
*/
- pci_cache_line_size = 32 >> 2;
+ pci_dfl_cache_line_size = 32 >> 2;
if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
- pci_cache_line_size = 64 >> 2; /* K7 & K8 */
+ pci_dfl_cache_line_size = 64 >> 2; /* K7 & K8 */
else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL)
- pci_cache_line_size = 128 >> 2; /* P4 */
+ pci_dfl_cache_line_size = 128 >> 2; /* P4 */
pcibios_resource_survey();
Index: work/drivers/pci/pci.c
===================================================================
--- work.orig/drivers/pci/pci.c
+++ work/drivers/pci/pci.c
@@ -41,6 +41,19 @@ int pci_domains_supported = 1;
unsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE;
unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
+#ifndef PCI_CACHE_LINE_BYTES
+#define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES
+#endif
+
+/*
+ * The default CLS is used if arch didn't set CLS explicitly and not
+ * all pci devices agree on the same value. Arch can override either
+ * the dfl or actual value as it sees fit. Don't forget this is
+ * measured in 32-bit words, not bytes.
+ */
+u8 pci_dfl_cache_line_size __initdata = PCI_CACHE_LINE_BYTES >> 2;
+u8 pci_cache_line_size;
+
/**
* pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
* @bus: pointer to PCI bus structure to search
@@ -1848,14 +1861,6 @@ void pci_clear_mwi(struct pci_dev *dev)
#else
-#ifndef PCI_CACHE_LINE_BYTES
-#define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES
-#endif
-
-/* This can be overridden by arch code. */
-/* Don't forget this is measured in 32-bit words, not bytes */
-u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4;
-
/**
* pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed
* @dev: the PCI device for which MWI is to be enabled
@@ -2631,9 +2636,37 @@ int __attribute__ ((weak)) pci_ext_cfg_a
static int __devinit pci_init(void)
{
struct pci_dev *dev = NULL;
+ u8 cls = 0;
+ u8 tmp;
+
+ if (pci_cache_line_size)
+ printk(KERN_DEBUG "PCI: CLS %u bytes\n",
+ pci_cache_line_size << 2);
while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
pci_fixup_device(pci_fixup_final, dev);
+ /*
+ * If arch hasn't set it explicitly yet, use the CLS
+ * value shared by all PCI devices. If there's a
+ * mismatch, fall back to the default value.
+ */
+ if (!pci_cache_line_size) {
+ pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp);
+ if (!cls)
+ cls = tmp;
+ if (!tmp || cls == tmp)
+ continue;
+
+ printk(KERN_DEBUG "PCI: CLS mismatch (%u != %u), "
+ "using %u bytes\n", cls << 2, tmp << 2,
+ pci_dfl_cache_line_size << 2);
+ pci_cache_line_size = pci_dfl_cache_line_size;
+ }
+ }
+ if (!pci_cache_line_size) {
+ printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n",
+ cls << 2, pci_dfl_cache_line_size << 2);
+ pci_cache_line_size = cls;
}
return 0;
^ permalink raw reply [flat|nested] 7+ messages in thread* [RFC PATCH 2/2] pccard: configure CLS on attach
2009-06-25 7:12 [RFC PATCH 1/2] pci: determine CLS more intelligently Tejun Heo
@ 2009-06-25 7:12 ` Tejun Heo
2009-06-25 9:05 ` [RFC PATCH 1/2] pci: determine CLS more intelligently David Miller
2009-06-25 10:07 ` Benjamin Herrenschmidt
2 siblings, 0 replies; 7+ messages in thread
From: Tejun Heo @ 2009-06-25 7:12 UTC (permalink / raw)
To: Greg KH, Robert Hancock, Alan Cox, linux-pci, Linux Kernel,
Daniel Ritz, Dominik Brodowski, Kenji Kaneshige, Axel Birndt,
Benjamin Herrenschmidt, Ingo Molnar, Thomas Gleixner, Tony Luck,
David Miller, Ingo Molnar
For non hotplug PCI devices, the system firmware usually configures
CLS correctly. For pccard devices system firmware can't do it and
Linux PCI layer doesn't do it either. Unfortunately this leads to
poor performance for certain devices (sata_sil). Unless MWI, which
requires separate configuration, is to be used, CLS doesn't affect
correctness, so the configuration should be harmless.
This patch makes pci_set_cacheline_size() always built and export it
and make pccard call it during attach.
Please note that some other PCI hotplug drivers (shpchp and pciehp)
also configure CLS on hotplug.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Daniel Ritz <daniel.ritz@gmx.ch>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Greg KH <greg@kroah.com>
Cc: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Cc: Axel Birndt <towerlexa@gmx.de>
---
drivers/pci/pci.c | 39 +++++++++++++++++++--------------------
drivers/pcmcia/cardbus.c | 23 +++++++++++++++--------
include/linux/pci.h | 1 +
3 files changed, 35 insertions(+), 28 deletions(-)
Index: work/drivers/pcmcia/cardbus.c
===================================================================
--- work.orig/drivers/pcmcia/cardbus.c
+++ work/drivers/pcmcia/cardbus.c
@@ -184,26 +184,33 @@ fail:
=====================================================================*/
-/*
- * Since there is only one interrupt available to CardBus
- * devices, all devices downstream of this device must
- * be using this IRQ.
- */
-static void cardbus_assign_irqs(struct pci_bus *bus, int irq)
+static void cardbus_config_irq_and_cls(struct pci_bus *bus, int irq)
{
struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) {
u8 irq_pin;
+ /*
+ * Since there is only one interrupt available to
+ * CardBus devices, all devices downstream of this
+ * device must be using this IRQ.
+ */
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin);
if (irq_pin) {
dev->irq = irq;
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
}
+ /*
+ * Some controllers transfer very slowly with 0 CLS.
+ * Configure it. This may fail as CLS configuration
+ * is mandatory only for MWI.
+ */
+ pci_set_cacheline_size(dev);
+
if (dev->subordinate)
- cardbus_assign_irqs(dev->subordinate, irq);
+ cardbus_config_irq_and_cls(dev->subordinate, irq);
}
}
@@ -228,7 +235,7 @@ int __ref cb_alloc(struct pcmcia_socket
*/
pci_bus_size_bridges(bus);
pci_bus_assign_resources(bus);
- cardbus_assign_irqs(bus, s->pci_irq);
+ cardbus_config_irq_and_cls(bus, s->pci_irq);
/* socket specific tune function */
if (s->tune_bridge)
Index: work/drivers/pci/pci.c
===================================================================
--- work.orig/drivers/pci/pci.c
+++ work/drivers/pci/pci.c
@@ -1844,23 +1844,6 @@ void pci_clear_master(struct pci_dev *de
__pci_set_master(dev, false);
}
-#ifdef PCI_DISABLE_MWI
-int pci_set_mwi(struct pci_dev *dev)
-{
- return 0;
-}
-
-int pci_try_set_mwi(struct pci_dev *dev)
-{
- return 0;
-}
-
-void pci_clear_mwi(struct pci_dev *dev)
-{
-}
-
-#else
-
/**
* pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed
* @dev: the PCI device for which MWI is to be enabled
@@ -1871,13 +1854,12 @@ void pci_clear_mwi(struct pci_dev *dev)
*
* RETURNS: An appropriate -ERRNO error value on error, or zero for success.
*/
-static int
-pci_set_cacheline_size(struct pci_dev *dev)
+int pci_set_cacheline_size(struct pci_dev *dev)
{
u8 cacheline_size;
if (!pci_cache_line_size)
- return -EINVAL; /* The system doesn't support MWI. */
+ return -EINVAL;
/* Validate current setting: the PCI_CACHE_LINE_SIZE must be
equal to or multiple of the right value. */
@@ -1899,6 +1881,23 @@ pci_set_cacheline_size(struct pci_dev *d
return -EINVAL;
}
+#ifdef PCI_DISABLE_MWI
+int pci_set_mwi(struct pci_dev *dev)
+{
+ return 0;
+}
+
+int pci_try_set_mwi(struct pci_dev *dev)
+{
+ return 0;
+}
+
+void pci_clear_mwi(struct pci_dev *dev)
+{
+}
+
+#else
+
/**
* pci_set_mwi - enables memory-write-invalidate PCI transaction
* @dev: the PCI device for which MWI is enabled
Index: work/include/linux/pci.h
===================================================================
--- work.orig/include/linux/pci.h
+++ work/include/linux/pci.h
@@ -697,6 +697,7 @@ void pci_disable_device(struct pci_dev *
void pci_set_master(struct pci_dev *dev);
void pci_clear_master(struct pci_dev *dev);
int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state);
+int pci_set_cacheline_size(struct pci_dev *dev);
#define HAVE_PCI_SET_MWI
int __must_check pci_set_mwi(struct pci_dev *dev);
int pci_try_set_mwi(struct pci_dev *dev);
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [RFC PATCH 1/2] pci: determine CLS more intelligently
2009-06-25 7:12 [RFC PATCH 1/2] pci: determine CLS more intelligently Tejun Heo
2009-06-25 7:12 ` [RFC PATCH 2/2] pccard: configure CLS on attach Tejun Heo
@ 2009-06-25 9:05 ` David Miller
2009-06-25 17:33 ` Greg KH
2009-06-25 10:07 ` Benjamin Herrenschmidt
2 siblings, 1 reply; 7+ messages in thread
From: David Miller @ 2009-06-25 9:05 UTC (permalink / raw)
To: tj
Cc: greg, hancockr, alan, linux-pci, linux-kernel, daniel.ritz, linux,
kaneshige.kenji, towerlexa, benh, mingo, tglx, tony.luck
From: Tejun Heo <tj@kernel.org>
Date: Thu, 25 Jun 2009 16:12:13 +0900
> sparc64 is currently the only one using PCI_CACHE_LINE_BYTES.
Feel free to add the patch below and:
Acked-by: David S. Miller <davem@davemloft.net>
Although I think it's better to declare pci_dfl_cache_line_size in
linux/pci.h instead of making every arch do the extern decl.
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 57859ad..511a592 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -1081,3 +1081,12 @@ void pci_resource_to_user(const struct pci_dev *pdev, int bar,
*start = rp->start - offset;
*end = rp->end - offset;
}
+
+extern u8 pci_dfl_cache_line_size;
+
+static int __init pcibios_init(void)
+{
+ pci_dfl_cache_line_size = 64 >> 2;
+ return 0;
+}
+subsys_initcall(pcibios_init);
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [RFC PATCH 1/2] pci: determine CLS more intelligently
2009-06-25 9:05 ` [RFC PATCH 1/2] pci: determine CLS more intelligently David Miller
@ 2009-06-25 17:33 ` Greg KH
2009-06-30 3:07 ` Tejun Heo
0 siblings, 1 reply; 7+ messages in thread
From: Greg KH @ 2009-06-25 17:33 UTC (permalink / raw)
To: David Miller, tj, hancockr, alan, linux-pci, linux-kernel,
daniel.ritz, linux, kaneshige.kenji, towerlexa, benh, mingo, tglx,
tony.luck
On Thu, Jun 25, 2009 at 02:05:07AM -0700, David Miller wrote:
> From: Tejun Heo <tj@kernel.org>
> Date: Thu, 25 Jun 2009 16:12:13 +0900
>
> > sparc64 is currently the only one using PCI_CACHE_LINE_BYTES.
>
> Feel free to add the patch below and:
>
> Acked-by: David S. Miller <davem@davemloft.net>
>
> Although I think it's better to declare pci_dfl_cache_line_size in
> linux/pci.h instead of making every arch do the extern decl.
I agree, that would make more sense.
Otherwise it looks good to me:
Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
thanks,
greg k-h
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC PATCH 1/2] pci: determine CLS more intelligently
2009-06-25 17:33 ` Greg KH
@ 2009-06-30 3:07 ` Tejun Heo
2009-06-30 10:22 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 7+ messages in thread
From: Tejun Heo @ 2009-06-30 3:07 UTC (permalink / raw)
To: Greg KH
Cc: David Miller, hancockr, alan, linux-pci, linux-kernel,
daniel.ritz, linux, kaneshige.kenji, towerlexa, benh, mingo, tglx,
tony.luck
Greg KH wrote:
> On Thu, Jun 25, 2009 at 02:05:07AM -0700, David Miller wrote:
>> From: Tejun Heo <tj@kernel.org>
>> Date: Thu, 25 Jun 2009 16:12:13 +0900
>>
>>> sparc64 is currently the only one using PCI_CACHE_LINE_BYTES.
>> Feel free to add the patch below and:
>>
>> Acked-by: David S. Miller <davem@davemloft.net>
>>
>> Although I think it's better to declare pci_dfl_cache_line_size in
>> linux/pci.h instead of making every arch do the extern decl.
>
> I agree, that would make more sense.
>
> Otherwise it looks good to me:
> Acked-by: Greg Kroah-Hartman <gregkh@suse.de>
Great, I'll incorporate both comments and repost the patchset after
Benjamin's testing or before the end of this week.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC PATCH 1/2] pci: determine CLS more intelligently
2009-06-30 3:07 ` Tejun Heo
@ 2009-06-30 10:22 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2009-06-30 10:22 UTC (permalink / raw)
To: Tejun Heo
Cc: Greg KH, David Miller, hancockr, alan, linux-pci, linux-kernel,
daniel.ritz, linux, kaneshige.kenji, towerlexa, mingo, tglx,
tony.luck
On Tue, 2009-06-30 at 12:07 +0900, Tejun Heo wrote:
>
> Great, I'll incorporate both comments and repost the patchset after
> Benjamin's testing or before the end of this week.
Just go ahead if you can test build powerpc. I'm on vacation on the
coast and won't be able to do much testing :-)
In any case, it shouldn't affect us (hopefully).
Cheers,
Ben.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [RFC PATCH 1/2] pci: determine CLS more intelligently
2009-06-25 7:12 [RFC PATCH 1/2] pci: determine CLS more intelligently Tejun Heo
2009-06-25 7:12 ` [RFC PATCH 2/2] pccard: configure CLS on attach Tejun Heo
2009-06-25 9:05 ` [RFC PATCH 1/2] pci: determine CLS more intelligently David Miller
@ 2009-06-25 10:07 ` Benjamin Herrenschmidt
2 siblings, 0 replies; 7+ messages in thread
From: Benjamin Herrenschmidt @ 2009-06-25 10:07 UTC (permalink / raw)
To: Tejun Heo
Cc: Greg KH, Robert Hancock, Alan Cox, linux-pci, Linux Kernel,
Daniel Ritz, Dominik Brodowski, Kenji Kaneshige, Axel Birndt,
Ingo Molnar, Thomas Gleixner, Tony Luck, David Miller
On Thu, 2009-06-25 at 16:12 +0900, Tejun Heo wrote:
> Till now, CLS has been determined either by arch code or as
> L1_CACHE_BYTES. Only x86 and ia64 set CLS explicitly and x86 doesn't
> always get it right. On most configurations, the chance is that
> firmware configures the correct value during boot.
>
> This patch makes pci_init() determine CLS by looking at what firmware
> has configured. It scans all devices and if all non-zero values
> agree, the value is used. If none is configured or there is a
> disagreement, pci_dfl_cache_line_size is used. arch can set the dfl
> value (via PCI_CACHE_LINE_BYTES or pci_dfl_cache_line_size) or
> override the actual one.
>
> ia64, x86 and sparc64 updated to set the default cls instead of the
> actual one. sparc64 is currently the only one using
> PCI_CACHE_LINE_BYTES. It would be nice to update it to set the
> default variable instead.
Looks ok, I'll have a quick look through though, as we have some weirdo
stuff on some PowerMacs with both PCI/PCI-E and HT off the north bridge
who need different values behind those different segments (for strange
reasons). IIRC, We get away because we never enable MWI on these (ie, I
don't think your patch can cause a regression either way), but I suppose
it would be good if I double checked.
If you don't hear from me mid next week, assume I forgot and merge it,
I'll deal with the consequences :-)
Cheers,
Ben.
> RFC PATCH, PLEASE DON'T APPLY YET.
> Cc: Greg KH <gregkh@suse.de>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Tony Luck <tony.luck@intel.com>
> Cc: David Miller <davem@davemloft.net>
> ---
> These two patches are refreshed version of the following patch.
>
> http://thread.gmane.org/gmane.linux.kernel.pci/4418/focus=4431
>
> This patch improves how CLS is determined and was written mainly
> because the original code didn't get it right on my laptop (lenovo
> x61s, the determined value was 32 but the value bios used for other
> devices was 64). For x86, maybe we can remove the arch specific
> configuration codes in the long run?
>
> Seems to work fine on my test machine and laptop. Also builds fine
> for powerpc64 and sparc64.
>
> Axel, to test, you'll need to build a vanialla kernel with the patches
> applied. There are pretty good docs about doing that on the web.
>
> Thanks.
>
> arch/ia64/pci/pci.c | 8 ++++----
> arch/x86/pci/common.c | 8 ++++----
> drivers/pci/pci.c | 49 +++++++++++++++++++++++++++++++++++++++++--------
> 3 files changed, 49 insertions(+), 16 deletions(-)
>
> Index: work/arch/ia64/pci/pci.c
> ===================================================================
> --- work.orig/arch/ia64/pci/pci.c
> +++ work/arch/ia64/pci/pci.c
> @@ -716,7 +716,7 @@ int ia64_pci_legacy_write(struct pci_bus
> }
>
> /* It's defined in drivers/pci/pci.c */
> -extern u8 pci_cache_line_size;
> +extern u8 pci_dfl_cache_line_size;
>
> /**
> * set_pci_cacheline_size - determine cacheline size for PCI devices
> @@ -726,7 +726,7 @@ extern u8 pci_cache_line_size;
> *
> * Code mostly taken from arch/ia64/kernel/palinfo.c:cache_info().
> */
> -static void __init set_pci_cacheline_size(void)
> +static void __init set_pci_dfl_cacheline_size(void)
> {
> unsigned long levels, unique_caches;
> long status;
> @@ -746,7 +746,7 @@ static void __init set_pci_cacheline_siz
> "(status=%ld)\n", __func__, status);
> return;
> }
> - pci_cache_line_size = (1 << cci.pcci_line_size) / 4;
> + pci_dfl_cache_line_size = (1 << cci.pcci_line_size) / 4;
> }
>
> u64 ia64_dma_get_required_mask(struct device *dev)
> @@ -777,7 +777,7 @@ EXPORT_SYMBOL_GPL(dma_get_required_mask)
>
> static int __init pcibios_init(void)
> {
> - set_pci_cacheline_size();
> + set_pci_dfl_cacheline_size();
> return 0;
> }
>
> Index: work/arch/x86/pci/common.c
> ===================================================================
> --- work.orig/arch/x86/pci/common.c
> +++ work/arch/x86/pci/common.c
> @@ -410,7 +410,7 @@ struct pci_bus * __devinit pcibios_scan_
> return bus;
> }
>
> -extern u8 pci_cache_line_size;
> +extern u8 pci_dfl_cache_line_size;
>
> int __init pcibios_init(void)
> {
> @@ -426,11 +426,11 @@ int __init pcibios_init(void)
> * and P4. It's also good for 386/486s (which actually have 16)
> * as quite a few PCI devices do not support smaller values.
> */
> - pci_cache_line_size = 32 >> 2;
> + pci_dfl_cache_line_size = 32 >> 2;
> if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD)
> - pci_cache_line_size = 64 >> 2; /* K7 & K8 */
> + pci_dfl_cache_line_size = 64 >> 2; /* K7 & K8 */
> else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL)
> - pci_cache_line_size = 128 >> 2; /* P4 */
> + pci_dfl_cache_line_size = 128 >> 2; /* P4 */
>
> pcibios_resource_survey();
>
> Index: work/drivers/pci/pci.c
> ===================================================================
> --- work.orig/drivers/pci/pci.c
> +++ work/drivers/pci/pci.c
> @@ -41,6 +41,19 @@ int pci_domains_supported = 1;
> unsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE;
> unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
>
> +#ifndef PCI_CACHE_LINE_BYTES
> +#define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES
> +#endif
> +
> +/*
> + * The default CLS is used if arch didn't set CLS explicitly and not
> + * all pci devices agree on the same value. Arch can override either
> + * the dfl or actual value as it sees fit. Don't forget this is
> + * measured in 32-bit words, not bytes.
> + */
> +u8 pci_dfl_cache_line_size __initdata = PCI_CACHE_LINE_BYTES >> 2;
> +u8 pci_cache_line_size;
> +
> /**
> * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
> * @bus: pointer to PCI bus structure to search
> @@ -1848,14 +1861,6 @@ void pci_clear_mwi(struct pci_dev *dev)
>
> #else
>
> -#ifndef PCI_CACHE_LINE_BYTES
> -#define PCI_CACHE_LINE_BYTES L1_CACHE_BYTES
> -#endif
> -
> -/* This can be overridden by arch code. */
> -/* Don't forget this is measured in 32-bit words, not bytes */
> -u8 pci_cache_line_size = PCI_CACHE_LINE_BYTES / 4;
> -
> /**
> * pci_set_cacheline_size - ensure the CACHE_LINE_SIZE register is programmed
> * @dev: the PCI device for which MWI is to be enabled
> @@ -2631,9 +2636,37 @@ int __attribute__ ((weak)) pci_ext_cfg_a
> static int __devinit pci_init(void)
> {
> struct pci_dev *dev = NULL;
> + u8 cls = 0;
> + u8 tmp;
> +
> + if (pci_cache_line_size)
> + printk(KERN_DEBUG "PCI: CLS %u bytes\n",
> + pci_cache_line_size << 2);
>
> while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
> pci_fixup_device(pci_fixup_final, dev);
> + /*
> + * If arch hasn't set it explicitly yet, use the CLS
> + * value shared by all PCI devices. If there's a
> + * mismatch, fall back to the default value.
> + */
> + if (!pci_cache_line_size) {
> + pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &tmp);
> + if (!cls)
> + cls = tmp;
> + if (!tmp || cls == tmp)
> + continue;
> +
> + printk(KERN_DEBUG "PCI: CLS mismatch (%u != %u), "
> + "using %u bytes\n", cls << 2, tmp << 2,
> + pci_dfl_cache_line_size << 2);
> + pci_cache_line_size = pci_dfl_cache_line_size;
> + }
> + }
> + if (!pci_cache_line_size) {
> + printk(KERN_DEBUG "PCI: CLS %u bytes, default %u\n",
> + cls << 2, pci_dfl_cache_line_size << 2);
> + pci_cache_line_size = cls;
> }
>
> return 0;
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-06-30 10:24 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-06-25 7:12 [RFC PATCH 1/2] pci: determine CLS more intelligently Tejun Heo
2009-06-25 7:12 ` [RFC PATCH 2/2] pccard: configure CLS on attach Tejun Heo
2009-06-25 9:05 ` [RFC PATCH 1/2] pci: determine CLS more intelligently David Miller
2009-06-25 17:33 ` Greg KH
2009-06-30 3:07 ` Tejun Heo
2009-06-30 10:22 ` Benjamin Herrenschmidt
2009-06-25 10:07 ` Benjamin Herrenschmidt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox