[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/3] dom0 linux: Sort PCI resource based on priority of allocation.



This patch add sorting PCI resource based on priority of allocation.

The priority is following.

1. I/O resource
2. Prefetchable high MMIO
3. Prefetchable low MMIO
4. high MMIO
5. low MMIO

This patch works when "pci=use_crs" boot parameter is specified.

Thanks,
--
Yuji Shimada


Signed-off-by: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx>

diff -r 13c0881b6f9d arch/i386/pci/acpi.c
--- a/arch/i386/pci/acpi.c      Mon Dec 01 21:04:16 2008 +0900
+++ b/arch/i386/pci/acpi.c      Mon Dec 01 21:05:35 2008 +0900
@@ -106,6 +106,75 @@ setup_resource(struct acpi_resource *acp
        return AE_OK;
 }
 
+static void __devinit sort_resources(struct pci_bus *bus)
+{
+       struct resource *res, *work;
+       int i, j;
+
+       for (i=0; i<(PCI_BUS_NUM_RESOURCES-1); i++) {
+               for (j=(PCI_BUS_NUM_RESOURCES-1); j>i; j--) {
+                       res = bus->resource[j];
+                       work = bus->resource[j-1];
+                       if (!res || !work)
+                               continue;
+
+                       /* res is MMIO resource and work is I/O resource
+                        * they should not be swapped */
+                       if ((res->flags & IORESOURCE_MEM) &&
+                           (work->flags & IORESOURCE_IO))
+                               continue;
+
+                       /* both is I/O resource */
+                       if ((res->flags & IORESOURCE_IO) &&
+                           (work->flags & IORESOURCE_IO))
+                               /* work's size is bigger than res's or equal
+                                * they should not be swapped */
+                               if ((work->end - work->start) >=
+                                   (res->end - res->start))
+                                       continue;
+
+                       /* both is MMIO resource */
+                       if ((res->flags & IORESOURCE_MEM) &&
+                           (work->flags & IORESOURCE_MEM)) {
+                               /* res isn't prefetchable and
+                                * work is prefetchable */
+                               if (!(res->flags & IORESOURCE_PREFETCH) &&
+                                   (work->flags & IORESOURCE_PREFETCH))
+                                       continue;
+
+                               /* both is prefetchable or 
+                                * both is not prefetchable */
+                               if (((res->flags & IORESOURCE_PREFETCH) &&
+                                    (work->flags & IORESOURCE_PREFETCH)) ||
+                                   (!(res->flags & IORESOURCE_PREFETCH) &&
+                                    !(work->flags & IORESOURCE_PREFETCH))) {
+
+                                       /* res is Low area and work is High area
+                                        * they should not be swapped */
+                                       if ((res->start >> 32) == 0 &&
+                                           (work->start >> 32) != 0)
+                                           continue;
+
+                                       /* both is same area (High or Low) */
+                                       if (((res->start >> 32) != 0 &&
+                                            (work->start >> 32) != 0) ||
+                                           ((res->start >> 32) == 0 &&
+                                            (work->start >> 32) == 0))
+                                               /* work's size is bigger or 
+                                                * equal than res's size
+                                                * they should not be swapped */
+                                               if ((work->end - work->start) 
>= 
+                                                   (res->end - res->start))
+                                                       continue;
+                               }
+                       }
+                       /* swap res and work */
+                       bus->resource[j-1] = res;
+                       bus->resource[j] = work;
+               }
+       }
+}
+
 /* This function is backported from 2.6.26 kernel */
 static void __devinit adjust_transparent_bridge_resources(struct pci_bus *bus)
 {
@@ -155,6 +224,7 @@ get_current_resources(struct acpi_device
        acpi_walk_resources(device->handle, METHOD_NAME__CRS,
                                setup_resource, &info);
        if (info.res_num) {
+               sort_resources(bus);
                adjust_transparent_bridge_resources(bus);
        }
 


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.