WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 2/3] dom0 linux: Sort PCI resource based on priority of allocation.
From: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx>
Date: Tue, 02 Dec 2008 15:35:36 +0900
Cc:
Delivery-date: Mon, 01 Dec 2008 22:36:21 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <20081202152033.08A3.SHIMADA-YXB@xxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20081202152033.08A3.SHIMADA-YXB@xxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
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