diff mbox

[v3,07/51] PCI: Reorder resources list for must/optional resources

Message ID 1438039809-24957-8-git-send-email-yinghai@kernel.org
State Superseded
Headers show

Commit Message

Yinghai Lu July 27, 2015, 11:29 p.m. UTC
After we update size and alignment for must+optional resource, we
reorder them with new alignment, but this is only for STARTALIGN.

For SIZEALIGN type resource, after add back add_size, the alignment
get changed, so need to do the sorting like STARTALIGN type resources.

Also we need to reorder the sorting back after we restore
resource to must only when must+optional fail to allocate for all.

So move out the reordering code from the loop to separated function,
and call it two times accordingly.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 drivers/pci/setup-bus.c | 62 +++++++++++++++++++++++++++++--------------------
 1 file changed, 37 insertions(+), 25 deletions(-)

Comments

Bjorn Helgaas Aug. 17, 2015, 11:52 p.m. UTC | #1
On Mon, Jul 27, 2015 at 04:29:25PM -0700, Yinghai Lu wrote:
> After we update size and alignment for must+optional resource, we
> reorder them with new alignment, but this is only for STARTALIGN.
> 
> For SIZEALIGN type resource, after add back add_size, the alignment
> get changed, so need to do the sorting like STARTALIGN type resources.
> 
> Also we need to reorder the sorting back after we restore
> resource to must only when must+optional fail to allocate for all.
> 
> So move out the reordering code from the loop to separated function,
> and call it two times accordingly.
> 
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/setup-bus.c | 62 +++++++++++++++++++++++++++++--------------------
>  1 file changed, 37 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
> index 7346bbf..6f2d508 100644
> --- a/drivers/pci/setup-bus.c
> +++ b/drivers/pci/setup-bus.c
> @@ -287,6 +287,31 @@ static inline void reset_resource(struct resource *res)
>  	res->flags = 0;
>  }
>  
> +static void __sort_resources(struct list_head *head)

Why did you add "__" before the function name?

> +{
> +	struct pci_dev_resource *res1, *tmp_res, *res2;
> +
> +	list_for_each_entry_safe(res1, tmp_res, head, list) {
> +		resource_size_t align1, size1, align2, size2;
> +
> +		align1 = pci_resource_alignment(res1->dev, res1->res);
> +		size1 = resource_size(res1->res);
> +
> +		/* reorder it */
> +		list_for_each_entry(res2, head, list) {
> +			if (res2 == res1)
> +				break;
> +
> +			align2 = pci_resource_alignment(res2->dev, res2->res);
> +			size2 = resource_size(res2->res);
> +			if (is_before(align1, size1, align2, size2)) {
> +				list_move_tail(&res1->list, &res2->list);
> +				break;
> +			}
> +		}
> +	}
> +}
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Yinghai Lu Aug. 18, 2015, 8:58 p.m. UTC | #2
On Mon, Aug 17, 2015 at 4:52 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
> On Mon, Jul 27, 2015 at 04:29:25PM -0700, Yinghai Lu wrote:
>> After we update size and alignment for must+optional resource, we
>> reorder them with new alignment, but this is only for STARTALIGN.
>>
>> For SIZEALIGN type resource, after add back add_size, the alignment
>> get changed, so need to do the sorting like STARTALIGN type resources.
>>
>> Also we need to reorder the sorting back after we restore
>> resource to must only when must+optional fail to allocate for all.
>>
>> So move out the reordering code from the loop to separated function,
>> and call it two times accordingly.
>>
>> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
>> ---
>>  drivers/pci/setup-bus.c | 62 +++++++++++++++++++++++++++++--------------------
>>  1 file changed, 37 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
>> index 7346bbf..6f2d508 100644
>> --- a/drivers/pci/setup-bus.c
>> +++ b/drivers/pci/setup-bus.c
>> @@ -287,6 +287,31 @@ static inline void reset_resource(struct resource *res)
>>       res->flags = 0;
>>  }
>>
>> +static void __sort_resources(struct list_head *head)
>
> Why did you add "__" before the function name?

ok, will remove that.
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 7346bbf..6f2d508 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -287,6 +287,31 @@  static inline void reset_resource(struct resource *res)
 	res->flags = 0;
 }
 
+static void __sort_resources(struct list_head *head)
+{
+	struct pci_dev_resource *res1, *tmp_res, *res2;
+
+	list_for_each_entry_safe(res1, tmp_res, head, list) {
+		resource_size_t align1, size1, align2, size2;
+
+		align1 = pci_resource_alignment(res1->dev, res1->res);
+		size1 = resource_size(res1->res);
+
+		/* reorder it */
+		list_for_each_entry(res2, head, list) {
+			if (res2 == res1)
+				break;
+
+			align2 = pci_resource_alignment(res2->dev, res2->res);
+			size2 = resource_size(res2->res);
+			if (is_before(align1, size1, align2, size2)) {
+				list_move_tail(&res1->list, &res2->list);
+				break;
+			}
+		}
+	}
+}
+
 /**
  * reassign_resources_sorted() - satisfy any additional resource requests
  *
@@ -449,9 +474,9 @@  static void __assign_resources_sorted(struct list_head *head,
 	LIST_HEAD(save_head);
 	LIST_HEAD(local_fail_head);
 	struct pci_dev_resource *save_res;
-	struct pci_dev_resource *dev_res, *tmp_res, *dev_res2;
+	struct pci_dev_resource *dev_res, *tmp_res;
 	unsigned long fail_type;
-	resource_size_t add_align, align;
+	resource_size_t add_align;
 
 	/* Check if optional add_size is there */
 	if (!realloc_head || list_empty(realloc_head))
@@ -466,47 +491,32 @@  static void __assign_resources_sorted(struct list_head *head,
 	}
 
 	/* Update res in head list with add_size in realloc_head list */
-	list_for_each_entry_safe(dev_res, tmp_res, head, list) {
+	list_for_each_entry(dev_res, head, list) {
 		dev_res->res->end += get_res_add_size(realloc_head,
 							dev_res->res);
 
 		/*
 		 * There are two kinds of additional resources in the list:
-		 * 1. bridge resource  -- IORESOURCE_STARTALIGN
-		 * 2. SR-IOV resource   -- IORESOURCE_SIZEALIGN
-		 * Here just fix the additional alignment for bridge
+		 * 1. bridge resource with IORESOURCE_STARTALIGN
+		 *    need to update start to change alignment
+		 * 2. resource with IORESOURCE_SIZEALIGN
+		 *    update size above already change alignment.
 		 */
 		if (!(dev_res->res->flags & IORESOURCE_STARTALIGN))
 			continue;
 
 		add_align = get_res_add_align(realloc_head, dev_res->res);
 
-		/*
-		 * The "head" list is sorted by the alignment to make sure
-		 * resources with bigger alignment will be assigned first.
-		 * After we change the alignment of a dev_res in "head" list,
-		 * we need to reorder the list by alignment to make it
-		 * consistent.
-		 */
-		if (add_align > dev_res->res->start) {
+		if (add_align) {
 			resource_size_t r_size = resource_size(dev_res->res);
 
 			dev_res->res->start = add_align;
 			dev_res->res->end = add_align + r_size - 1;
-
-			list_for_each_entry(dev_res2, head, list) {
-				align = pci_resource_alignment(dev_res2->dev,
-							       dev_res2->res);
-				if (add_align > align) {
-					list_move_tail(&dev_res->list,
-						       &dev_res2->list);
-					break;
-				}
-			}
                }
-
 	}
 
+	__sort_resources(head);
+
 	/* Try updated head list with add_size added */
 	assign_requested_resources_sorted(head, &local_fail_head);
 
@@ -548,6 +558,8 @@  static void __assign_resources_sorted(struct list_head *head,
 	}
 	free_list(&save_head);
 
+	__sort_resources(head);
+
 requested_and_reassign:
 	/* Satisfy the must-have resource requests */
 	assign_requested_resources_sorted(head, fail_head);