* [PATCH 0/7] Add hostbridge resource release to support root bus hotplug in IA64
@ 2013-04-27 9:12 Yijing Wang
2013-04-27 9:12 ` [PATCH 1/7] PCI/X86: fix always use info->res[0] to store _CRS resource when pci=nocrs set Yijing Wang
` (6 more replies)
0 siblings, 7 replies; 8+ messages in thread
From: Yijing Wang @ 2013-04-27 9:12 UTC (permalink / raw)
To: Bjorn Helgaas; +Cc: linux-pci, Hanjun Guo, jiang.liu, Yijing Wang
Hi Bjron,
This patchset mainly to add hostbridge resource release to support root bus hotplug
in IA64. Just based your suggestion, link:http://marc.info/?l=linux-pci&m=134506155529536&w=2
I'm very sorry to send the new version patchset late. Currently, hotplug root bus code has been
in kernel, But in IA64, lack the hostbridge resource code. So we cannot hot add root bus because
resource confict report.
This patchset based your pci-next branch code.
Jiang Liu (1):
PCI/IA64: fix memleak for create pci root bus fail
Yijing Wang (6):
PCI/X86: fix always use info->res[0] to store _CRS resource when
pci=nocrs set
PCI/IA64: SN: remove sn_pci_window_fixup()
PCI/IA64: make pci_root_info holds pci hostbridge resources
PCI/IA64: Allocate pci_root_info instead of using stack
PCI/IA64: add host bridge resource release for _CRS path
PCI/IA64: introduce probe_pci_root_info() to manage _CRS resource
arch/ia64/include/asm/pci.h | 20 +++-
arch/ia64/pci/pci.c | 221 +++++++++++++++++++++++++++--------------
arch/ia64/sn/kernel/io_init.c | 106 +++++++-------------
arch/x86/pci/acpi.c | 7 +-
4 files changed, 199 insertions(+), 155 deletions(-)
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/7] PCI/X86: fix always use info->res[0] to store _CRS resource when pci=nocrs set
2013-04-27 9:12 [PATCH 0/7] Add hostbridge resource release to support root bus hotplug in IA64 Yijing Wang
@ 2013-04-27 9:12 ` Yijing Wang
2013-04-27 9:12 ` [PATCH 2/7] PCI/IA64: SN: remove sn_pci_window_fixup() Yijing Wang
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Yijing Wang @ 2013-04-27 9:12 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Hanjun Guo, jiang.liu, Yijing Wang, Yinghai Lu,
Jiang Liu, Rafael J. Wysocki, Feng Tang
We should increase info->res_num before checking pci_use_crs return, otherwise
only the res[0] of pci_root_info will be used during setup_resource() when
pci=nocrs set. And the old resource value will be overwritten by new resource item.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Jiang Liu <liuj97@gmail.com>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Feng Tang <feng.tang@intel.com>
---
arch/x86/pci/acpi.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 3e72425..662dfdf 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -324,14 +324,11 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
res->start = start;
res->end = end;
info->res_offset[info->res_num] = addr.translation_offset;
+ info->res_num++;
- if (!pci_use_crs) {
+ if (!pci_use_crs)
dev_printk(KERN_DEBUG, &info->bridge->dev,
"host bridge window %pR (ignored)\n", res);
- return AE_OK;
- }
-
- info->res_num++;
return AE_OK;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/7] PCI/IA64: SN: remove sn_pci_window_fixup()
2013-04-27 9:12 [PATCH 0/7] Add hostbridge resource release to support root bus hotplug in IA64 Yijing Wang
2013-04-27 9:12 ` [PATCH 1/7] PCI/X86: fix always use info->res[0] to store _CRS resource when pci=nocrs set Yijing Wang
@ 2013-04-27 9:12 ` Yijing Wang
2013-04-27 9:12 ` [PATCH 3/7] PCI/IA64: make pci_root_info holds pci hostbridge resources Yijing Wang
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Yijing Wang @ 2013-04-27 9:12 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Hanjun Guo, jiang.liu, Yijing Wang, Tony Luck,
Fenghua Yu, linux-ia64
Currently, pcibios_bus_to_resource() and pcibios_resource_to_bus()
functions use pci_host_bridge_window in pci_host_bridge to translate
bus side to/from cpu side addresses. Pci_window in pci_controller
under IA64 is no used again, so remove this function.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
---
arch/ia64/sn/kernel/io_init.c | 49 +----------------------------------------
1 files changed, 1 insertions(+), 48 deletions(-)
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 238e2c5..99710f5 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -149,48 +149,6 @@ sn_legacy_pci_window_fixup(struct pci_controller *controller,
}
/*
- * sn_pci_window_fixup() - Create a pci_window for each device resource.
- * It will setup pci_windows for use by
- * pcibios_bus_to_resource(), pcibios_resource_to_bus(),
- * etc.
- */
-static void
-sn_pci_window_fixup(struct pci_dev *dev, unsigned int count,
- s64 * pci_addrs)
-{
- struct pci_controller *controller = PCI_CONTROLLER(dev->bus);
- unsigned int i;
- unsigned int idx;
- unsigned int new_count;
- struct pci_window *new_window;
-
- if (count == 0)
- return;
- idx = controller->windows;
- new_count = controller->windows + count;
- new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL);
- BUG_ON(new_window == NULL);
- if (controller->window) {
- memcpy(new_window, controller->window,
- sizeof(struct pci_window) * controller->windows);
- kfree(controller->window);
- }
-
- /* Setup a pci_window for each device resource. */
- for (i = 0; i <= PCI_ROM_RESOURCE; i++) {
- if (pci_addrs[i] == -1)
- continue;
-
- new_window[idx].offset = dev->resource[i].start - pci_addrs[i];
- new_window[idx].resource = dev->resource[i];
- idx++;
- }
-
- controller->windows = new_count;
- controller->window = new_window;
-}
-
-/*
* sn_io_slot_fixup() - We are not running with an ACPI capable PROM,
* and need to convert the pci_dev->resource
* 'start' and 'end' addresses to mapped addresses,
@@ -276,12 +234,7 @@ sn_io_slot_fixup(struct pci_dev *dev)
IORESOURCE_ROM_BIOS_COPY;
}
}
- /* Create a pci_window in the pci_controller struct for
- * each device resource.
- */
- if (count > 0)
- sn_pci_window_fixup(dev, count, pci_addrs);
-
+
sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/7] PCI/IA64: make pci_root_info holds pci hostbridge resources
2013-04-27 9:12 [PATCH 0/7] Add hostbridge resource release to support root bus hotplug in IA64 Yijing Wang
2013-04-27 9:12 ` [PATCH 1/7] PCI/X86: fix always use info->res[0] to store _CRS resource when pci=nocrs set Yijing Wang
2013-04-27 9:12 ` [PATCH 2/7] PCI/IA64: SN: remove sn_pci_window_fixup() Yijing Wang
@ 2013-04-27 9:12 ` Yijing Wang
2013-04-27 9:12 ` [PATCH 4/7] PCI/IA64: Allocate pci_root_info instead of using stack Yijing Wang
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Yijing Wang @ 2013-04-27 9:12 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Hanjun Guo, jiang.liu, Yijing Wang, Tony Luck,
Fenghua Yu, Yinghai Lu, Greg Kroah-Hartman, Thierry Reding,
linux-ia64
Currently, pcibios_resource_to_bus() and pcibios_bus_to_resource()
functions use pci_host_bridge to translate bus side address from/to
cpu side address. The pci_window in pci_controller never be used again.
So we remove pci_window in pci_controller and make pci_root_info hold
the pci hostbridge resources like in x86.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Thierry Reding <thierry.reding@avionic-design.de>
Cc: linux-ia64@vger.kernel.org
---
arch/ia64/include/asm/pci.h | 18 ++++++-----
arch/ia64/pci/pci.c | 68 ++++++++++++++++++++--------------------
arch/ia64/sn/kernel/io_init.c | 67 ++++++++++++++++++++++++---------------
3 files changed, 85 insertions(+), 68 deletions(-)
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 5e04b59..82a236c 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -89,23 +89,25 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
#define pci_legacy_read platform_pci_legacy_read
#define pci_legacy_write platform_pci_legacy_write
-struct pci_window {
- struct resource resource;
- u64 offset;
-};
-
struct pci_controller {
void *acpi_handle;
void *iommu;
int segment;
int node; /* nearest node with memory or -1 for global allocation */
- unsigned int windows;
- struct pci_window *window;
-
void *platform_data;
};
+struct pci_root_info {
+ struct acpi_device *bridge;
+ struct pci_controller *controller;
+ struct list_head resources;
+ struct resource *res;
+ resource_size_t *res_offset;
+ unsigned int res_num;
+ char *name;
+};
+
#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment)
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index de1474f..d7681c6 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -130,12 +130,6 @@ static struct pci_controller *alloc_pci_controller(int seg)
return controller;
}
-struct pci_root_info {
- struct acpi_device *bridge;
- struct pci_controller *controller;
- struct list_head resources;
- char *name;
-};
static unsigned int
new_space (u64 phys_base, int sparse)
@@ -265,7 +259,7 @@ static acpi_status count_window(struct acpi_resource *resource, void *data)
static acpi_status add_window(struct acpi_resource *res, void *data)
{
struct pci_root_info *info = data;
- struct pci_window *window;
+ struct resource *resource;
struct acpi_resource_address64 addr;
acpi_status status;
unsigned long flags, offset = 0;
@@ -289,37 +283,36 @@ static acpi_status add_window(struct acpi_resource *res, void *data)
} else
return AE_OK;
- window = &info->controller->window[info->controller->windows++];
- window->resource.name = info->name;
- window->resource.flags = flags;
- window->resource.start = addr.minimum + offset;
- window->resource.end = window->resource.start + addr.address_length - 1;
- window->offset = offset;
+ resource = &info->res[info->res_num];
+ resource->name = info->name;
+ resource->flags = flags;
+ resource->start = addr.minimum + offset;
+ resource->end = resource->start + addr.address_length - 1;
+ info->res_offset[info->res_num] = offset;
- if (insert_resource(root, &window->resource)) {
+ if (insert_resource(root, resource)) {
dev_err(&info->bridge->dev,
"can't allocate host bridge window %pR\n",
- &window->resource);
+ resource);
} else {
if (offset)
dev_info(&info->bridge->dev, "host bridge window %pR "
"(PCI address [%#llx-%#llx])\n",
- &window->resource,
- window->resource.start - offset,
- window->resource.end - offset);
+ resource,
+ resource->start - offset,
+ resource->end - offset);
else
dev_info(&info->bridge->dev,
- "host bridge window %pR\n",
- &window->resource);
+ "host bridge window %pR\n", resource);
}
-
/* HP's firmware has a hack to work around a Windows bug.
* Ignore these tiny memory ranges */
- if (!((window->resource.flags & IORESOURCE_MEM) &&
- (window->resource.end - window->resource.start < 16)))
- pci_add_resource_offset(&info->resources, &window->resource,
- window->offset);
+ if (!((resource->flags & IORESOURCE_MEM) &&
+ (resource->end - resource->start < 16)))
+ pci_add_resource_offset(&info->resources, resource,
+ info->res_offset[info->res_num]);
+ info->res_num++;
return AE_OK;
}
@@ -329,7 +322,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
int domain = root->segment;
int bus = root->secondary.start;
struct pci_controller *controller;
- unsigned int windows = 0;
struct pci_root_info info;
struct pci_bus *pbus;
char *name;
@@ -351,22 +343,29 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
/* insert busn resource at first */
pci_add_resource(&info.resources, &root->secondary);
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
- &windows);
- if (windows) {
- controller->window =
- kzalloc_node(sizeof(*controller->window) * windows,
+ &info.res_num);
+ if (info.res_num) {
+ info.res =
+ kzalloc_node(sizeof(*info.res) * info.res_num,
GFP_KERNEL, controller->node);
- if (!controller->window)
+ if (!info.res)
goto out2;
+
+ info.res_offset =
+ kzalloc_node(sizeof(*info.res_offset) * info.res_num,
+ GFP_KERNEL, controller->node);
+ if (!info.res_offset)
+ goto out3;
name = kmalloc(16, GFP_KERNEL);
if (!name)
- goto out3;
+ goto out4;
sprintf(name, "PCI Bus %04x:%02x", domain, bus);
info.bridge = device;
info.controller = controller;
info.name = name;
+ info.res_num = 0;
acpi_walk_resources(device->handle, METHOD_NAME__CRS,
add_window, &info);
}
@@ -385,9 +384,10 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
pci_scan_child_bus(pbus);
return pbus;
-
+out4:
+ kfree(info.res_offset);
out3:
- kfree(controller->window);
+ kfree(info.res);
out2:
kfree(controller);
out1:
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index 99710f5..86c2335 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -125,27 +125,39 @@ static void __init sn_fixup_ionodes(void)
* and their resources (_CRS),
*/
static void
-sn_legacy_pci_window_fixup(struct pci_controller *controller,
+sn_legacy_pci_window_fixup(struct pci_root_info *info,
u64 legacy_io, u64 legacy_mem)
{
- controller->window = kcalloc(2, sizeof(struct pci_window),
- GFP_KERNEL);
- BUG_ON(controller->window == NULL);
- controller->window[0].offset = legacy_io;
- controller->window[0].resource.name = "legacy_io";
- controller->window[0].resource.flags = IORESOURCE_IO;
- controller->window[0].resource.start = legacy_io;
- controller->window[0].resource.end =
- controller->window[0].resource.start + 0xffff;
- controller->window[0].resource.parent = &ioport_resource;
- controller->window[1].offset = legacy_mem;
- controller->window[1].resource.name = "legacy_mem";
- controller->window[1].resource.flags = IORESOURCE_MEM;
- controller->window[1].resource.start = legacy_mem;
- controller->window[1].resource.end =
- controller->window[1].resource.start + (1024 * 1024) - 1;
- controller->window[1].resource.parent = &iomem_resource;
- controller->windows = 2;
+ info->res_num = 2;
+ info->res = kzalloc(sizeof(*info->res) * info->res_num, GFP_KERNEL);
+ if (!info->res) {
+ info->res_num = 0;
+ return;
+ }
+
+ info->res_offset = kzalloc(sizeof(*info->res_offset) * info->res_num,
+ GFP_KERNEL);
+ if (!info->res_offset) {
+ kfree(info->res);
+ info->res = NULL;
+ info->res_num = 0;
+ return;
+ }
+
+ info->res_offset[0] = legacy_io;
+ info->res[0].name = "legacy_io";
+ info->res[0].flags = IORESOURCE_IO;
+ info->res[0].start = legacy_io;
+ info->res[0].end =
+ info->res[0].start + 0xffff;
+ info->res[0].parent = &ioport_resource;
+ info->res_offset[1] = legacy_mem;
+ info->res[1].name = "legacy_mem";
+ info->res[1].flags = IORESOURCE_MEM;
+ info->res[1].start = legacy_mem;
+ info->res[1].end =
+ info->res[1].start + (1024 * 1024) - 1;
+ info->res[1].parent = &iomem_resource;
}
/*
@@ -248,6 +260,7 @@ static void __init
sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
{
s64 status = 0;
+ struct pci_root_info info;
struct pci_controller *controller;
struct pcibus_bussoft *prom_bussoft_ptr;
LIST_HEAD(resources);
@@ -262,20 +275,21 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
controller = kzalloc(sizeof(*controller), GFP_KERNEL);
BUG_ON(!controller);
controller->segment = segment;
-
- /*
+ /*
* Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup().
* (platform_data will be overwritten later in sn_common_bus_fixup())
*/
controller->platform_data = prom_bussoft_ptr;
+
+ info.controller = controller;
- sn_legacy_pci_window_fixup(controller,
+ sn_legacy_pci_window_fixup(&info,
prom_bussoft_ptr->bs_legacy_io,
prom_bussoft_ptr->bs_legacy_mem);
- for (i = 0; i < controller->windows; i++)
+ for (i = 0; i < info.res_num; i++)
pci_add_resource_offset(&resources,
- &controller->window[i].resource,
- controller->window[i].offset);
+ &info.res[i],
+ info.res_offset[i]);
bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
&resources);
if (bus == NULL)
@@ -286,8 +300,9 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
return;
error_return:
-
kfree(controller);
+ kfree(info.res);
+ kfree(info.res_offset);
return;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/7] PCI/IA64: Allocate pci_root_info instead of using stack
2013-04-27 9:12 [PATCH 0/7] Add hostbridge resource release to support root bus hotplug in IA64 Yijing Wang
` (2 preceding siblings ...)
2013-04-27 9:12 ` [PATCH 3/7] PCI/IA64: make pci_root_info holds pci hostbridge resources Yijing Wang
@ 2013-04-27 9:12 ` Yijing Wang
2013-04-27 9:12 ` [PATCH 5/7] PCI/IA64: fix memleak for create pci root bus fail Yijing Wang
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Yijing Wang @ 2013-04-27 9:12 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Hanjun Guo, jiang.liu, Yijing Wang, Tony Luck,
Fenghua Yu, Yinghai Lu, Greg Kroah-Hartman, linux-ia64
We need to pass around info for release function.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-ia64@vger.kernel.org
---
arch/ia64/pci/pci.c | 59 ++++++++++++++++++++++++++++++--------------------
1 files changed, 35 insertions(+), 24 deletions(-)
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index d7681c6..1f2779d 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -322,7 +322,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
int domain = root->segment;
int bus = root->secondary.start;
struct pci_controller *controller;
- struct pci_root_info info;
+ struct pci_root_info *info = NULL;
+ int busnum = root->secondary.start;
struct pci_bus *pbus;
char *name;
int pxm;
@@ -339,35 +340,42 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
controller->node = pxm_to_node(pxm);
#endif
- INIT_LIST_HEAD(&info.resources);
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ printk(KERN_WARNING "pci_bus %04x:%02x: "
+ "ignored (out of memory)\n", root->segment, busnum);
+ goto out2;
+ }
+
+ INIT_LIST_HEAD(&info->resources);
/* insert busn resource at first */
- pci_add_resource(&info.resources, &root->secondary);
+ pci_add_resource(&info->resources, &root->secondary);
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
- &info.res_num);
- if (info.res_num) {
- info.res =
- kzalloc_node(sizeof(*info.res) * info.res_num,
+ &info->res_num);
+ if (info->res_num) {
+ info->res =
+ kzalloc_node(sizeof(*info->res) * info->res_num,
GFP_KERNEL, controller->node);
- if (!info.res)
- goto out2;
-
- info.res_offset =
- kzalloc_node(sizeof(*info.res_offset) * info.res_num,
- GFP_KERNEL, controller->node);
- if (!info.res_offset)
+ if (!info->res)
goto out3;
+
+ info->res_offset =
+ kzalloc_node(sizeof(*info->res_offset) * info->res_num,
+ GFP_KERNEL, controller->node);
+ if (!info->res_offset)
+ goto out4;
name = kmalloc(16, GFP_KERNEL);
if (!name)
- goto out4;
+ goto out5;
sprintf(name, "PCI Bus %04x:%02x", domain, bus);
- info.bridge = device;
- info.controller = controller;
- info.name = name;
- info.res_num = 0;
+ info->bridge = device;
+ info->controller = controller;
+ info->name = name;
+ info->res_num = 0;
acpi_walk_resources(device->handle, METHOD_NAME__CRS,
- add_window, &info);
+ add_window, info);
}
/*
* See arch/x86/pci/acpi.c.
@@ -376,18 +384,21 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
* such quirk. So we just ignore the case now.
*/
pbus = pci_create_root_bus(NULL, bus, &pci_root_ops, controller,
- &info.resources);
+ &info->resources);
if (!pbus) {
- pci_free_resource_list(&info.resources);
+ pci_free_resource_list(&info->resources);
return NULL;
}
pci_scan_child_bus(pbus);
return pbus;
+
+out5:
+ kfree(info->res_offset);
out4:
- kfree(info.res_offset);
+ kfree(info->res);
out3:
- kfree(info.res);
+ kfree(info);
out2:
kfree(controller);
out1:
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/7] PCI/IA64: fix memleak for create pci root bus fail
2013-04-27 9:12 [PATCH 0/7] Add hostbridge resource release to support root bus hotplug in IA64 Yijing Wang
` (3 preceding siblings ...)
2013-04-27 9:12 ` [PATCH 4/7] PCI/IA64: Allocate pci_root_info instead of using stack Yijing Wang
@ 2013-04-27 9:12 ` Yijing Wang
2013-04-27 9:12 ` [PATCH 6/7] PCI/IA64: add host bridge resource release for _CRS path Yijing Wang
2013-04-27 9:12 ` [PATCH 7/7] PCI/IA64: introduce probe_pci_root_info() to manage _CRS resource Yijing Wang
6 siblings, 0 replies; 8+ messages in thread
From: Yijing Wang @ 2013-04-27 9:12 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Hanjun Guo, jiang.liu, Yijing Wang, Tony Luck,
Fenghua Yu, Yinghai Lu, Greg Kroah-Hartman, linux-ia64
From: Jiang Liu <jiang.liu@huawei.com>
If pci_create_root_bus() return fail, we should release
pci root info, pci controller etc.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-ia64@vger.kernel.org
---
arch/ia64/include/asm/pci.h | 6 +++
arch/ia64/pci/pci.c | 74 ++++++++++++++++++++++++++++++++++---------
2 files changed, 65 insertions(+), 15 deletions(-)
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 82a236c..fe813c2 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -89,6 +89,11 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
#define pci_legacy_read platform_pci_legacy_read
#define pci_legacy_write platform_pci_legacy_write
+struct iospace_resource {
+ struct list_head list;
+ struct resource res;
+};
+
struct pci_controller {
void *acpi_handle;
void *iommu;
@@ -105,6 +110,7 @@ struct pci_root_info {
struct resource *res;
resource_size_t *res_offset;
unsigned int res_num;
+ struct list_head io_resources;
char *name;
};
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 1f2779d..658030f 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -162,25 +162,21 @@ new_space (u64 phys_base, int sparse)
static u64 add_io_space(struct pci_root_info *info,
struct acpi_resource_address64 *addr)
{
+ struct iospace_resource *iospace;
struct resource *resource;
char *name;
unsigned long base, min, max, base_port;
unsigned int sparse = 0, space_nr, len;
- resource = kzalloc(sizeof(*resource), GFP_KERNEL);
- if (!resource) {
+ len = strlen(info->name) + 32;
+ iospace = kzalloc(sizeof(*iospace) + len, GFP_KERNEL);
+ if (!iospace) {
printk(KERN_ERR "PCI: No memory for %s I/O port space\n",
info->name);
goto out;
}
- len = strlen(info->name) + 32;
- name = kzalloc(len, GFP_KERNEL);
- if (!name) {
- printk(KERN_ERR "PCI: No memory for %s I/O port space name\n",
- info->name);
- goto free_resource;
- }
+ name = (char *)(iospace + 1);
min = addr->minimum;
max = min + addr->address_length - 1;
@@ -189,7 +185,7 @@ static u64 add_io_space(struct pci_root_info *info,
space_nr = new_space(addr->translation_offset, sparse);
if (space_nr == ~0)
- goto free_name;
+ goto free_resource;
base = __pa(io_space[space_nr].mmio_base);
base_port = IO_SPACE_BASE(space_nr);
@@ -204,18 +200,23 @@ static u64 add_io_space(struct pci_root_info *info,
if (space_nr == 0)
sparse = 1;
+ resource = &iospace->res;
resource->name = name;
resource->flags = IORESOURCE_MEM;
resource->start = base + (sparse ? IO_SPACE_SPARSE_ENCODING(min) : min);
resource->end = base + (sparse ? IO_SPACE_SPARSE_ENCODING(max) : max);
- insert_resource(&iomem_resource, resource);
+ if (insert_resource(&iomem_resource, resource)) {
+ dev_err(&info->bridge->dev,
+ "can't allocate host bridge io space resource %pR\n",
+ resource);
+ goto free_resource;
+ }
+ list_add_tail(&iospace->list, &info->io_resources);
return base_port;
-free_name:
- kfree(name);
free_resource:
- kfree(resource);
+ kfree(iospace);
out:
return ~0;
}
@@ -316,6 +317,47 @@ static acpi_status add_window(struct acpi_resource *res, void *data)
return AE_OK;
}
+static void free_pci_root_info_res(struct pci_root_info *info)
+{
+ struct iospace_resource *iospace, *tmp;
+
+ list_for_each_entry_safe(iospace, tmp, &info->io_resources, list)
+ kfree(iospace);
+
+ kfree(info->res);
+ info->res = NULL;
+ kfree(info->res_offset);
+ info->res_offset = NULL;
+ info->res_num = 0;
+ kfree(info->controller);
+ info->controller = NULL;
+}
+
+static void __release_pci_root_info(struct pci_root_info *info)
+{
+ int i;
+ struct resource *res;
+ struct iospace_resource *iospace;
+
+ list_for_each_entry(iospace, &info->io_resources, list)
+ release_resource(&iospace->res);
+
+ for (i = 0; i < info->res_num; i++) {
+ res = &info->res[i];
+
+ if (!res->parent)
+ continue;
+
+ if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
+ continue;
+
+ release_resource(res);
+ }
+
+ free_pci_root_info_res(info);
+ kfree(info);
+}
+
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
struct acpi_device *device = root->device;
@@ -346,7 +388,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
"ignored (out of memory)\n", root->segment, busnum);
goto out2;
}
-
+
+ INIT_LIST_HEAD(&info->io_resources);
INIT_LIST_HEAD(&info->resources);
/* insert busn resource at first */
pci_add_resource(&info->resources, &root->secondary);
@@ -387,6 +430,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
&info->resources);
if (!pbus) {
pci_free_resource_list(&info->resources);
+ __release_pci_root_info(info);
return NULL;
}
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/7] PCI/IA64: add host bridge resource release for _CRS path
2013-04-27 9:12 [PATCH 0/7] Add hostbridge resource release to support root bus hotplug in IA64 Yijing Wang
` (4 preceding siblings ...)
2013-04-27 9:12 ` [PATCH 5/7] PCI/IA64: fix memleak for create pci root bus fail Yijing Wang
@ 2013-04-27 9:12 ` Yijing Wang
2013-04-27 9:12 ` [PATCH 7/7] PCI/IA64: introduce probe_pci_root_info() to manage _CRS resource Yijing Wang
6 siblings, 0 replies; 8+ messages in thread
From: Yijing Wang @ 2013-04-27 9:12 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-pci, Hanjun Guo, jiang.liu, Yijing Wang, Tony Luck,
Fenghua Yu, Yinghai Lu, Greg Kroah-Hartman, linux-ia64
Set IA64 host bridge release function to make sure root bridge
related resources get freed during root bus removal.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-ia64@vger.kernel.org
---
arch/ia64/pci/pci.c | 11 ++++++++++-
1 files changed, 10 insertions(+), 1 deletions(-)
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 658030f..2857a83 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -358,6 +358,13 @@ static void __release_pci_root_info(struct pci_root_info *info)
kfree(info);
}
+static void release_pci_root_info(struct pci_host_bridge *bridge)
+{
+ struct pci_root_info *info = bridge->release_data;
+
+ __release_pci_root_info(info);
+}
+
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
struct acpi_device *device = root->device;
@@ -433,7 +440,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
__release_pci_root_info(info);
return NULL;
}
-
+
+ pci_set_host_bridge_release(to_pci_host_bridge(pbus->bridge),
+ release_pci_root_info, info);
pci_scan_child_bus(pbus);
return pbus;
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 7/7] PCI/IA64: introduce probe_pci_root_info() to manage _CRS resource
2013-04-27 9:12 [PATCH 0/7] Add hostbridge resource release to support root bus hotplug in IA64 Yijing Wang
` (5 preceding siblings ...)
2013-04-27 9:12 ` [PATCH 6/7] PCI/IA64: add host bridge resource release for _CRS path Yijing Wang
@ 2013-04-27 9:12 ` Yijing Wang
6 siblings, 0 replies; 8+ messages in thread
From: Yijing Wang @ 2013-04-27 9:12 UTC (permalink / raw)
To: Bjorn Helgaas; +Cc: linux-pci, Hanjun Guo, jiang.liu, Yijing Wang
Currently, initialize _CRS resource code in IA64 make pci_acpi_scan_root()
some lengthiness. Introduce probe_pci_root_info() to manage it like in X86,
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/ia64/pci/pci.c | 91 +++++++++++++++++++++++++++-----------------------
1 files changed, 49 insertions(+), 42 deletions(-)
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 2857a83..8076225 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -365,6 +365,48 @@ static void release_pci_root_info(struct pci_host_bridge *bridge)
__release_pci_root_info(info);
}
+static void
+probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
+ int busnum, int domain)
+{
+ char *name;
+
+ name = kmalloc(16, GFP_KERNEL);
+ if (!name)
+ return;
+
+ sprintf(name, "PCI Bus %04x:%02x", domain, busnum);
+ info->bridge = device;
+ info->name = name;
+
+ acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
+ &info->res_num);
+ if (info->res_num) {
+ info->res =
+ kzalloc_node(sizeof(*info->res) * info->res_num,
+ GFP_KERNEL, info->controller->node);
+ if (!info->res) {
+ kfree(name);
+ return;
+ }
+
+ info->res_offset =
+ kzalloc_node(sizeof(*info->res_offset) * info->res_num,
+ GFP_KERNEL, info->controller->node);
+ if (!info->res_offset) {
+ kfree(name);
+ kfree(info->res);
+ info->res = NULL;
+ return;
+ }
+
+ info->res_num = 0;
+ acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+ add_window, info);
+ } else
+ kfree(name);
+}
+
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
{
struct acpi_device *device = root->device;
@@ -374,12 +416,11 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
struct pci_root_info *info = NULL;
int busnum = root->secondary.start;
struct pci_bus *pbus;
- char *name;
int pxm;
controller = alloc_pci_controller(domain);
if (!controller)
- goto out1;
+ return NULL;
controller->acpi_handle = device->handle;
@@ -392,41 +433,18 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
printk(KERN_WARNING "pci_bus %04x:%02x: "
- "ignored (out of memory)\n", root->segment, busnum);
- goto out2;
+ "ignored (out of memory)\n", domain, busnum);
+ kfree(controller);
+ return NULL;
}
+ info->controller = controller;
INIT_LIST_HEAD(&info->io_resources);
INIT_LIST_HEAD(&info->resources);
+ probe_pci_root_info(info, device, busnum, domain);
+
/* insert busn resource at first */
pci_add_resource(&info->resources, &root->secondary);
- acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_window,
- &info->res_num);
- if (info->res_num) {
- info->res =
- kzalloc_node(sizeof(*info->res) * info->res_num,
- GFP_KERNEL, controller->node);
- if (!info->res)
- goto out3;
-
- info->res_offset =
- kzalloc_node(sizeof(*info->res_offset) * info->res_num,
- GFP_KERNEL, controller->node);
- if (!info->res_offset)
- goto out4;
-
- name = kmalloc(16, GFP_KERNEL);
- if (!name)
- goto out5;
-
- sprintf(name, "PCI Bus %04x:%02x", domain, bus);
- info->bridge = device;
- info->controller = controller;
- info->name = name;
- info->res_num = 0;
- acpi_walk_resources(device->handle, METHOD_NAME__CRS,
- add_window, info);
- }
/*
* See arch/x86/pci/acpi.c.
* The desired pci bus might already be scanned in a quirk. We
@@ -445,17 +463,6 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
release_pci_root_info, info);
pci_scan_child_bus(pbus);
return pbus;
-
-out5:
- kfree(info->res_offset);
-out4:
- kfree(info->res);
-out3:
- kfree(info);
-out2:
- kfree(controller);
-out1:
- return NULL;
}
int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge)
--
1.7.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2013-04-27 9:16 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-27 9:12 [PATCH 0/7] Add hostbridge resource release to support root bus hotplug in IA64 Yijing Wang
2013-04-27 9:12 ` [PATCH 1/7] PCI/X86: fix always use info->res[0] to store _CRS resource when pci=nocrs set Yijing Wang
2013-04-27 9:12 ` [PATCH 2/7] PCI/IA64: SN: remove sn_pci_window_fixup() Yijing Wang
2013-04-27 9:12 ` [PATCH 3/7] PCI/IA64: make pci_root_info holds pci hostbridge resources Yijing Wang
2013-04-27 9:12 ` [PATCH 4/7] PCI/IA64: Allocate pci_root_info instead of using stack Yijing Wang
2013-04-27 9:12 ` [PATCH 5/7] PCI/IA64: fix memleak for create pci root bus fail Yijing Wang
2013-04-27 9:12 ` [PATCH 6/7] PCI/IA64: add host bridge resource release for _CRS path Yijing Wang
2013-04-27 9:12 ` [PATCH 7/7] PCI/IA64: introduce probe_pci_root_info() to manage _CRS resource Yijing Wang
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).