From: Yinghai Lu <yinghai@kernel.org>
To: Bjorn Helgaas <bhelgaas@google.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
Yinghai Lu <yinghai@kernel.org>
Subject: [PATCH 07/11] PCI: Don't allocate small resource in big empty space.
Date: Tue, 22 May 2012 23:34:33 -0700 [thread overview]
Message-ID: <1337754877-19759-8-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1337754877-19759-1-git-send-email-yinghai@kernel.org>
Use updated find_resource to return matched resource instead using head
of bigger range.
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
drivers/pci/bus.c | 22 ++++++++++++++++++----
drivers/pci/setup-bus.c | 12 ++++++++----
drivers/pci/setup-res.c | 28 ++++++++++++++++++----------
include/linux/ioport.h | 8 ++++++++
include/linux/pci.h | 10 ++++++++++
kernel/resource.c | 22 +++++++++++++++++++---
6 files changed, 81 insertions(+), 21 deletions(-)
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 2429f1f..a7ba102 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -110,14 +110,14 @@ void pci_bus_remove_resources(struct pci_bus *bus)
* for a specific device resource.
*/
int
-pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
+pci_bus_alloc_resource_fit(struct pci_bus *bus, struct resource *res,
resource_size_t size, resource_size_t align,
resource_size_t min, unsigned int type_mask,
resource_size_t (*alignf)(void *,
const struct resource *,
resource_size_t,
resource_size_t),
- void *alignf_data)
+ void *alignf_data, bool fit)
{
int i, ret = -ENOMEM;
struct resource *r;
@@ -148,10 +148,10 @@ again:
continue;
/* Ok, try it out.. */
- ret = allocate_resource(r, res, size,
+ ret = allocate_resource_fit(r, res, size,
max(bottom, r->start ? : min),
max, align,
- alignf, alignf_data);
+ alignf, alignf_data, fit);
if (ret == 0)
return 0;
}
@@ -164,6 +164,20 @@ again:
return ret;
}
+int
+pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res,
+ resource_size_t size, resource_size_t align,
+ resource_size_t min, unsigned int type_mask,
+ resource_size_t (*alignf)(void *,
+ const struct resource *,
+ resource_size_t,
+ resource_size_t),
+ void *alignf_data)
+{
+ return pci_bus_alloc_resource_fit(bus, res, size, align, min, type_mask,
+ alignf, alignf_data, false);
+}
+
/**
* pci_bus_add_device - add a single device
* @dev: device to add
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 0568f29..4d6823f 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -275,7 +275,7 @@ out:
* requests that could not satisfied to the failed_list.
*/
static void assign_requested_resources_sorted(struct list_head *head,
- struct list_head *fail_head)
+ struct list_head *fail_head, bool fit)
{
struct resource *res;
struct pci_dev_resource *dev_res;
@@ -285,7 +285,7 @@ static void assign_requested_resources_sorted(struct list_head *head,
res = dev_res->res;
idx = res - &dev_res->dev->resource[0];
if (resource_size(res) &&
- pci_assign_resource(dev_res->dev, idx)) {
+ pci_assign_resource_fit(dev_res->dev, idx, fit)) {
if (fail_head) {
/*
* if the failed res is for ROM BAR, and it will
@@ -320,6 +320,7 @@ static void __assign_resources_sorted(struct list_head *head,
LIST_HEAD(local_fail_head);
struct pci_dev_resource *save_res;
struct pci_dev_resource *dev_res;
+ bool fit = true;
/* Check if optional add_size is there */
if (!realloc_head || list_empty(realloc_head))
@@ -339,7 +340,7 @@ static void __assign_resources_sorted(struct list_head *head,
dev_res->res);
/* Try updated head list with add_size added */
- assign_requested_resources_sorted(head, &local_fail_head);
+ assign_requested_resources_sorted(head, &local_fail_head, fit);
/* all assigned with add_size ? */
if (list_empty(&local_fail_head)) {
@@ -366,9 +367,12 @@ static void __assign_resources_sorted(struct list_head *head,
}
free_list(&save_head);
+ /* will need to expand later, so not use fit */
+ fit = false;
+
requested_and_reassign:
/* Satisfy the must-have resource requests */
- assign_requested_resources_sorted(head, fail_head);
+ assign_requested_resources_sorted(head, fail_head, fit);
/* Try to satisfy any additional optional resource
requests */
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index eea85da..7010ad9 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -128,7 +128,8 @@ void pci_disable_bridge_window(struct pci_dev *dev)
}
static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
- int resno, resource_size_t size, resource_size_t align)
+ int resno, resource_size_t size, resource_size_t align,
+ bool fit)
{
struct resource *res = dev->resource + resno;
resource_size_t min;
@@ -137,9 +138,9 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
/* First, try exact prefetching match.. */
- ret = pci_bus_alloc_resource(bus, res, size, align, min,
+ ret = pci_bus_alloc_resource_fit(bus, res, size, align, min,
IORESOURCE_PREFETCH,
- pcibios_align_resource, dev);
+ pcibios_align_resource, dev, fit);
if (ret < 0 && (res->flags & IORESOURCE_PREFETCH)) {
/*
@@ -148,8 +149,8 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
* But a prefetching area can handle a non-prefetching
* window (it will just not perform as well).
*/
- ret = pci_bus_alloc_resource(bus, res, size, align, min, 0,
- pcibios_align_resource, dev);
+ ret = pci_bus_alloc_resource_fit(bus, res, size, align, min, 0,
+ pcibios_align_resource, dev, fit);
}
return ret;
}
@@ -206,7 +207,8 @@ static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev,
return ret;
}
-static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resource_size_t min_align)
+static int _pci_assign_resource(struct pci_dev *dev, int resno, int size,
+ resource_size_t min_align, bool fit)
{
struct resource *res = dev->resource + resno;
struct pci_bus *bus;
@@ -214,7 +216,8 @@ static int _pci_assign_resource(struct pci_dev *dev, int resno, int size, resour
char *type;
bus = dev->bus;
- while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
+ while ((ret = __pci_assign_resource(bus, dev, resno, size,
+ min_align, fit))) {
if (!bus->parent || !bus->self->transparent)
break;
bus = bus->parent;
@@ -253,7 +256,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
/* already aligned with min_align */
new_size = resource_size(res) + addsize;
- ret = _pci_assign_resource(dev, resno, new_size, min_align);
+ ret = _pci_assign_resource(dev, resno, new_size, min_align, false);
if (!ret) {
res->flags &= ~IORESOURCE_STARTALIGN;
dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res);
@@ -263,7 +266,7 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz
return ret;
}
-int pci_assign_resource(struct pci_dev *dev, int resno)
+int pci_assign_resource_fit(struct pci_dev *dev, int resno, bool fit)
{
struct resource *res = dev->resource + resno;
resource_size_t align, size;
@@ -279,7 +282,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
bus = dev->bus;
size = resource_size(res);
- ret = _pci_assign_resource(dev, resno, size, align);
+ ret = _pci_assign_resource(dev, resno, size, align, fit);
/*
* If we failed to assign anything, let's try the address
@@ -298,6 +301,11 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
return ret;
}
+int pci_assign_resource(struct pci_dev *dev, int resno)
+{
+ return pci_assign_resource_fit(dev, resno, false);
+}
+
int pci_enable_resources(struct pci_dev *dev, int mask)
{
u16 cmd, old_cmd;
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 589e0e7..255852e 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -148,6 +148,14 @@ extern struct resource *insert_resource_conflict(struct resource *parent, struct
extern int insert_resource(struct resource *parent, struct resource *new);
extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new);
extern void arch_remove_reservations(struct resource *avail);
+int allocate_resource_fit(struct resource *root, struct resource *new,
+ resource_size_t size, resource_size_t min,
+ resource_size_t max, resource_size_t align,
+ resource_size_t (*alignf)(void *,
+ const struct resource *,
+ resource_size_t,
+ resource_size_t),
+ void *alignf_data, bool fit);
extern int allocate_resource(struct resource *root, struct resource *new,
resource_size_t size, resource_size_t min,
resource_size_t max, resource_size_t align,
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a0e2d7f..c0704a0 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -827,6 +827,7 @@ int __pci_reset_function_locked(struct pci_dev *dev);
int pci_reset_function(struct pci_dev *dev);
void pci_update_resource(struct pci_dev *dev, int resno);
int __must_check pci_assign_resource(struct pci_dev *dev, int i);
+int __must_check pci_assign_resource_fit(struct pci_dev *dev, int i, bool fit);
int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align);
int pci_select_bars(struct pci_dev *dev, unsigned long flags);
@@ -943,6 +944,15 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
resource_size_t,
resource_size_t),
void *alignf_data);
+int __must_check pci_bus_alloc_resource_fit(struct pci_bus *bus,
+ struct resource *res, resource_size_t size,
+ resource_size_t align, resource_size_t min,
+ unsigned int type_mask,
+ resource_size_t (*alignf)(void *,
+ const struct resource *,
+ resource_size_t,
+ resource_size_t),
+ void *alignf_data, bool fit);
void pci_enable_bridges(struct pci_bus *bus);
/* Proper probing supporting hot-pluggable devices */
diff --git a/kernel/resource.c b/kernel/resource.c
index 45ab24d..b4dae55 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -580,7 +580,7 @@ static int __allocate_resource(struct resource *root, struct resource *new,
const struct resource *,
resource_size_t,
resource_size_t),
- void *alignf_data, bool lock)
+ void *alignf_data, bool lock, bool fit)
{
int err;
struct resource_constraint constraint;
@@ -602,13 +602,28 @@ static int __allocate_resource(struct resource *root, struct resource *new,
if (lock)
write_lock(&resource_lock);
- err = find_resource(root, new, size, &constraint, false);
+ err = find_resource(root, new, size, &constraint, fit);
if (err >= 0 && __request_resource(root, new))
err = -EBUSY;
if (lock)
write_unlock(&resource_lock);
return err;
}
+int allocate_resource_fit(struct resource *root, struct resource *new,
+ resource_size_t size, resource_size_t min,
+ resource_size_t max, resource_size_t align,
+ resource_size_t (*alignf)(void *,
+ const struct resource *,
+ resource_size_t,
+ resource_size_t),
+ void *alignf_data, bool fit)
+{
+ bool lock = true;
+
+ return __allocate_resource(root, new, size, min, max, align,
+ alignf, alignf_data, lock, fit);
+}
+
int allocate_resource(struct resource *root, struct resource *new,
resource_size_t size, resource_size_t min,
resource_size_t max, resource_size_t align,
@@ -619,9 +634,10 @@ int allocate_resource(struct resource *root, struct resource *new,
void *alignf_data)
{
bool lock = true;
+ bool fit = false;
return __allocate_resource(root, new, size, min, max, align,
- alignf, alignf_data, lock);
+ alignf, alignf_data, lock, fit);
}
EXPORT_SYMBOL(allocate_resource);
--
1.7.7
next prev parent reply other threads:[~2012-05-23 6:34 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-23 6:34 [PATCH 00/11] PCI: resource allocation related Yinghai Lu
2012-05-23 6:34 ` [PATCH 01/11] PCI: Should add children device res to fail list Yinghai Lu
2012-05-23 6:34 ` [PATCH 02/11] PCI: Try to allocate mem64 above 4G at first Yinghai Lu
2012-05-23 15:57 ` Linus Torvalds
2012-05-23 17:30 ` Yinghai Lu
2012-05-23 18:40 ` Yinghai Lu
2012-05-25 4:36 ` Bjorn Helgaas
2012-05-25 17:53 ` Yinghai Lu
2012-05-25 18:39 ` Yinghai Lu
2012-05-25 19:37 ` Bjorn Helgaas
2012-05-25 20:18 ` H. Peter Anvin
2012-05-25 20:19 ` Yinghai Lu
2012-05-25 21:55 ` Bjorn Helgaas
2012-05-25 21:58 ` H. Peter Anvin
2012-05-25 22:14 ` Bjorn Helgaas
2012-05-25 23:10 ` Yinghai Lu
2012-05-26 0:12 ` Bjorn Helgaas
2012-05-26 15:01 ` Bjorn Helgaas
2012-05-29 17:56 ` Yinghai Lu
2012-05-29 17:55 ` Yinghai Lu
2012-05-29 17:57 ` H. Peter Anvin
2012-05-29 18:17 ` Yinghai Lu
2012-05-29 19:03 ` H. Peter Anvin
2012-05-29 20:46 ` Yinghai Lu
2012-05-29 20:50 ` H. Peter Anvin
2012-06-01 23:30 ` Yinghai Lu
2012-06-04 1:05 ` Bjorn Helgaas
2012-06-05 2:37 ` Yinghai Lu
2012-06-05 4:50 ` Bjorn Helgaas
2012-06-05 5:04 ` Yinghai Lu
2012-06-06 9:44 ` Steven Newbury
2012-06-06 16:18 ` Bjorn Helgaas
[not found] ` <CAGLnvc_ejMWiiubVMo7DLz5ZVn1iMbf67FB4H7crRCCTRRqt2A@mail.gmail.com>
2012-07-04 3:00 ` joeyli
2012-05-29 20:53 ` David Miller
2012-05-29 19:23 ` Bjorn Helgaas
2012-05-29 20:40 ` Yinghai Lu
2012-05-29 23:24 ` Bjorn Helgaas
2012-05-29 23:27 ` Bjorn Helgaas
2012-05-29 23:33 ` Yinghai Lu
2012-05-29 23:47 ` Bjorn Helgaas
2012-05-30 7:40 ` Steven Newbury
2012-05-30 16:27 ` Bjorn Helgaas
2012-05-30 16:30 ` H. Peter Anvin
2012-05-30 16:33 ` Linus Torvalds
2012-05-23 6:34 ` [PATCH 03/11] intel-gtt: Read 64bit for gmar_bus_addr Yinghai Lu
2012-05-23 7:21 ` Dave Airlie
2012-05-23 7:44 ` Daniel Vetter
2012-05-23 6:34 ` [PATCH 04/11] PCI: Make sure assign same align with large size resource at first Yinghai Lu
2012-05-23 6:34 ` [PATCH 05/11] resources: Split out __allocate_resource() Yinghai Lu
2012-05-23 6:34 ` [PATCH 06/11] resource: make find_resource could return just fit resource Yinghai Lu
2012-05-23 6:34 ` Yinghai Lu [this message]
2012-05-23 6:34 ` [PATCH 08/11] resource: only return range with needed align Yinghai Lu
2012-05-23 6:34 ` [PATCH 09/11] PCI: Add is_pci_iov_resource_idx() Yinghai Lu
2012-05-23 6:34 ` [PATCH 10/11] PCI: Sort unassigned resources with correct alignment Yinghai Lu
2012-05-23 6:34 ` [PATCH 11/11] PCI: Treat ROM resource as optional during assigning Yinghai Lu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1337754877-19759-8-git-send-email-yinghai@kernel.org \
--to=yinghai@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=bhelgaas@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).