All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yinghai Lu <yinghai@kernel.org>
To: Jesse Barnes <jbarnes@virtuousgeek.org>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Tony Luck <tony.luck@intel.com>,
	David Miller <davem@davemloft.net>, x86 <x86@kernel.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>,
	Dominik Brodowski <linux@dominikbrodowski.net>,
	linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arch@vger.kernel.org, Yinghai Lu <yinghai@kernel.org>
Subject: [PATCH 10/36] x86, PCI: Allocating pci_root_info for not using _CRS path
Date: Wed, 29 Feb 2012 19:00:11 -0800	[thread overview]
Message-ID: <1330570837-26638-11-git-send-email-yinghai@kernel.org> (raw)
In-Reply-To: <1330570837-26638-1-git-send-email-yinghai@kernel.org>

so we could get ride of static allocation and hard limits.

We could save some bytes, and can handle system with more than 4
peer root buses.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/pci/amd_bus.c      |   76 +++++++++++++++---------------------------
 arch/x86/pci/broadcom_bus.c |   12 ++----
 arch/x86/pci/bus_numa.c     |   69 ++++++++++++++++++++++++++------------
 arch/x86/pci/bus_numa.h     |   18 ++++++----
 4 files changed, 88 insertions(+), 87 deletions(-)

diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 0567df3..459a731 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -32,6 +32,18 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
 
 #define RANGE_NUM 16
 
+static struct pci_root_info __init *find_pci_root_info(int node, int link)
+{
+	struct pci_root_info *info;
+
+	/* find the position */
+	list_for_each_entry(info, &pci_root_infos, list)
+		if (info->node == node && info->link == link)
+			return info;
+
+	return NULL;
+}
+
 /**
  * early_fill_mp_bus_to_node()
  * called before pcibios_scan_root and pci_scan_bus
@@ -50,7 +62,6 @@ static int __init early_fill_mp_bus_info(void)
 	int def_link;
 	struct pci_root_info *info;
 	u32 reg;
-	struct resource *res;
 	u64 start;
 	u64 end;
 	struct range range[RANGE_NUM];
@@ -86,7 +97,6 @@ static int __init early_fill_mp_bus_info(void)
 	if (!found)
 		return 0;
 
-	pci_root_num = 0;
 	for (i = 0; i < 4; i++) {
 		int min_bus;
 		int max_bus;
@@ -105,13 +115,8 @@ static int __init early_fill_mp_bus_info(void)
 #endif
 		link = (reg >> 8) & 0x03;
 
-		info = &pci_root_info[pci_root_num];
-		info->bus_min = min_bus;
-		info->bus_max = max_bus;
-		info->node = node;
-		info->link = link;
+		info = alloc_pci_root_info(min_bus, max_bus, node, link);
 		sprintf(info->name, "PCI Bus #%02x", min_bus);
-		pci_root_num++;
 	}
 
 	/* get the default node and link for left over res */
@@ -134,16 +139,10 @@ static int __init early_fill_mp_bus_info(void)
 		link = (reg >> 4) & 0x03;
 		end = (reg & 0xfff000) | 0xfff;
 
-		/* find the position */
-		for (j = 0; j < pci_root_num; j++) {
-			info = &pci_root_info[j];
-			if (info->node == node && info->link == link)
-				break;
-		}
-		if (j == pci_root_num)
+		info = find_pci_root_info(node, link);
+		if (!info)
 			continue; /* not found */
 
-		info = &pci_root_info[j];
 		printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
 		       node, link, start, end);
 
@@ -155,13 +154,8 @@ static int __init early_fill_mp_bus_info(void)
 	}
 	/* add left over io port range to def node/link, [0, 0xffff] */
 	/* find the position */
-	for (j = 0; j < pci_root_num; j++) {
-		info = &pci_root_info[j];
-		if (info->node == def_node && info->link == def_link)
-			break;
-	}
-	if (j < pci_root_num) {
-		info = &pci_root_info[j];
+	info = find_pci_root_info(def_node, def_link);
+	if (info) {
 		for (i = 0; i < RANGE_NUM; i++) {
 			if (!range[i].end)
 				continue;
@@ -214,16 +208,10 @@ static int __init early_fill_mp_bus_info(void)
 		end <<= 8;
 		end |= 0xffff;
 
-		/* find the position */
-		for (j = 0; j < pci_root_num; j++) {
-			info = &pci_root_info[j];
-			if (info->node == node && info->link == link)
-				break;
-		}
-		if (j == pci_root_num)
-			continue; /* not found */
+		info = find_pci_root_info(node, link);
 
-		info = &pci_root_info[j];
+		if (!info)
+			continue;
 
 		printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
 		       node, link, start, end);
@@ -291,14 +279,8 @@ static int __init early_fill_mp_bus_info(void)
 	 * add left over mmio range to def node/link ?
 	 * that is tricky, just record range in from start_min to 4G
 	 */
-	for (j = 0; j < pci_root_num; j++) {
-		info = &pci_root_info[j];
-		if (info->node == def_node && info->link == def_link)
-			break;
-	}
-	if (j < pci_root_num) {
-		info = &pci_root_info[j];
-
+	info = find_pci_root_info(def_node, def_link);
+	if (info) {
 		for (i = 0; i < RANGE_NUM; i++) {
 			if (!range[i].end)
 				continue;
@@ -309,20 +291,16 @@ static int __init early_fill_mp_bus_info(void)
 		}
 	}
 
-	for (i = 0; i < pci_root_num; i++) {
-		int res_num;
+	list_for_each_entry(info, &pci_root_infos, list) {
 		int busnum;
+		struct pci_root_res *root_res;
 
-		info = &pci_root_info[i];
-		res_num = info->res_num;
 		busnum = info->bus_min;
 		printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n",
 		       info->bus_min, info->bus_max, info->node, info->link);
-		for (j = 0; j < res_num; j++) {
-			res = &info->res[j];
-			printk(KERN_DEBUG "bus: %02x index %x %pR\n",
-				       busnum, j, res);
-		}
+		list_for_each_entry(root_res, &info->resources, list)
+			printk(KERN_DEBUG "bus: %02x %pR\n",
+				       busnum, &root_res->res);
 	}
 
 	return 0;
diff --git a/arch/x86/pci/broadcom_bus.c b/arch/x86/pci/broadcom_bus.c
index f3a7c56..614392c 100644
--- a/arch/x86/pci/broadcom_bus.c
+++ b/arch/x86/pci/broadcom_bus.c
@@ -22,19 +22,15 @@
 static void __init cnb20le_res(u8 bus, u8 slot, u8 func)
 {
 	struct pci_root_info *info;
+	struct pci_root_res *root_res;
 	struct resource res;
 	u16 word1, word2;
 	u8 fbus, lbus;
-	int i;
-
-	info = &pci_root_info[pci_root_num];
-	pci_root_num++;
 
 	/* read the PCI bus numbers */
 	fbus = read_pci_config_byte(bus, slot, func, 0x44);
 	lbus = read_pci_config_byte(bus, slot, func, 0x45);
-	info->bus_min = fbus;
-	info->bus_max = lbus;
+	info = alloc_pci_root_info(fbus, lbus, 0, 0);
 
 	/*
 	 * Add the legacy IDE ports on bus 0
@@ -86,8 +82,8 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func)
 	res.flags = IORESOURCE_BUS;
 	printk(KERN_INFO "CNB20LE PCI Host Bridge (domain 0000 %pR)\n", &res);
 
-	for (i = 0; i < info->res_num; i++)
-		printk(KERN_INFO "host bridge window %pR\n", &info->res[i]);
+	list_for_each_entry(root_res, &info->resources, list)
+		printk(KERN_INFO "host bridge window %pR\n", &root_res->res);
 }
 
 static int __init broadcom_postcore_init(void)
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c
index fd3f655..306579f 100644
--- a/arch/x86/pci/bus_numa.c
+++ b/arch/x86/pci/bus_numa.c
@@ -4,35 +4,38 @@
 
 #include "bus_numa.h"
 
-int pci_root_num;
-struct pci_root_info pci_root_info[PCI_ROOT_NR];
+LIST_HEAD(pci_root_infos);
 
-void x86_pci_root_bus_resources(int bus, struct list_head *resources)
+static struct pci_root_info *x86_find_pci_root_info(int bus)
 {
-	int i;
-	int j;
 	struct pci_root_info *info;
 
-	if (!pci_root_num)
-		goto default_resources;
+	if (list_empty(&pci_root_infos))
+		return NULL;
 
-	for (i = 0; i < pci_root_num; i++) {
-		if (pci_root_info[i].bus_min == bus)
-			break;
-	}
+	list_for_each_entry(info, &pci_root_infos, list)
+		if (info->bus_min == bus)
+			return info;
+
+	return NULL;
+}
 
-	if (i == pci_root_num)
+void x86_pci_root_bus_resources(int bus, struct list_head *resources)
+{
+	struct pci_root_info *info = x86_find_pci_root_info(bus);
+	struct pci_root_res *root_res;
+
+	if (!info)
 		goto default_resources;
 
 	printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n",
 	       bus);
 
-	info = &pci_root_info[i];
-	for (j = 0; j < info->res_num; j++) {
+	list_for_each_entry(root_res, &info->resources, list) {
 		struct resource *res;
 		struct resource *root;
 
-		res = &info->res[j];
+		res = &root_res->res;
 		pci_add_resource(resources, res);
 		if (res->flags & IORESOURCE_IO)
 			root = &ioport_resource;
@@ -53,11 +56,32 @@ default_resources:
 	pci_add_resource(resources, &iomem_resource);
 }
 
+struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max,
+						 int node, int link)
+{
+	struct pci_root_info *info;
+
+	info = kzalloc(sizeof(*info), GFP_KERNEL);
+
+	if (!info)
+		return info;
+
+	INIT_LIST_HEAD(&info->resources);
+	info->bus_min = bus_min;
+	info->bus_max = bus_max;
+	info->node = node;
+	info->link = link;
+
+	list_add_tail(&info->list, &pci_root_infos);
+
+	return info;
+}
+
 void __devinit update_res(struct pci_root_info *info, resource_size_t start,
 			  resource_size_t end, unsigned long flags, int merge)
 {
-	int i;
 	struct resource *res;
+	struct pci_root_res *root_res;
 
 	if (start > end)
 		return;
@@ -69,11 +93,11 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
 		goto addit;
 
 	/* try to merge it with old one */
-	for (i = 0; i < info->res_num; i++) {
+	list_for_each_entry(root_res, &info->resources, list) {
 		resource_size_t final_start, final_end;
 		resource_size_t common_start, common_end;
 
-		res = &info->res[i];
+		res = &root_res->res;
 		if (res->flags != flags)
 			continue;
 
@@ -93,14 +117,15 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
 addit:
 
 	/* need to add that */
-	if (info->res_num >= RES_NUM)
+	root_res = kzalloc(sizeof(*root_res), GFP_KERNEL);
+	if (!root_res)
 		return;
 
-	res = &info->res[info->res_num];
+	res = &root_res->res;
 	res->name = info->name;
 	res->flags = flags;
 	res->start = start;
 	res->end = end;
-	res->child = NULL;
-	info->res_num++;
+
+	list_add_tail(&root_res->list, &info->resources);
 }
diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h
index 804a4b4..226a466 100644
--- a/arch/x86/pci/bus_numa.h
+++ b/arch/x86/pci/bus_numa.h
@@ -4,22 +4,24 @@
  * sub bus (transparent) will use entres from 3 to store extra from
  * root, so need to make sure we have enough slot there.
  */
-#define RES_NUM 16
+struct pci_root_res {
+	struct list_head list;
+	struct resource res;
+};
+
 struct pci_root_info {
+	struct list_head list;
 	char name[12];
-	unsigned int res_num;
-	struct resource res[RES_NUM];
+	struct list_head resources;
 	int bus_min;
 	int bus_max;
 	int node;
 	int link;
 };
 
-/* 4 at this time, it may become to 32 */
-#define PCI_ROOT_NR 4
-extern int pci_root_num;
-extern struct pci_root_info pci_root_info[PCI_ROOT_NR];
-
+extern struct list_head pci_root_infos;
+struct pci_root_info *alloc_pci_root_info(int bus_min, int bus_max,
+						int node, int link);
 extern void update_res(struct pci_root_info *info, resource_size_t start,
 		      resource_size_t end, unsigned long flags, int merge);
 #endif
-- 
1.7.7

  parent reply	other threads:[~2012-03-01  3:00 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-01  3:00 [PATCH -v2 00/36] PCI: pci_host_bridge related cleanup and busn_alloc Yinghai Lu
2012-03-01  3:00 ` [PATCH 01/36] PCI: Separate host_bridge code out from probe.c Yinghai Lu
2012-03-01  3:00 ` [PATCH 02/36] x86, PCI: Fix memleak with get_current_resources Yinghai Lu
2012-03-15  8:39   ` Taku Izumi
2012-03-15 17:44     ` Yinghai Lu
2012-03-01  3:00 ` [PATCH 03/36] PCI: rename pci_host_bridge() to find_pci_root_bridge() Yinghai Lu
2012-03-01  3:00 ` [PATCH 04/36] PCI: add generic device into pci_host_bridge struct Yinghai Lu
2012-03-01  3:00 ` [PATCH 05/36] PCI: add host bridge release support Yinghai Lu
2012-03-01  3:00 ` [PATCH 06/36] x86, PCI: break down get_current_resource() Yinghai Lu
2012-03-01  3:00 ` [PATCH 07/36] x86, PCI: add host bridge resource release for using _CRS Yinghai Lu
2012-03-01  3:00 ` [PATCH 08/36] x86, PCI: embed name acpi version pci_root_info struct Yinghai Lu
2012-03-01  3:00 ` [PATCH 09/36] x86, PCI: embed pci_sysdata into pci_root_info on acpi path Yinghai Lu
2012-03-01  3:00 ` Yinghai Lu [this message]
2012-03-01  3:00 ` [PATCH 11/36] x86, PCI: Merge root info printing for nocrs path Yinghai Lu
2012-03-01  3:00 ` [PATCH 12/36] x86, PCI: add print all root info " Yinghai Lu
2012-03-01  3:00 ` [PATCH 13/36] x86, PCI: allocate temp range array in amd_bus pci_root_info probing Yinghai Lu
2012-03-01  3:00 ` [PATCH 14/36] x86, PCI: Merge pcibios_scan_root and pci_scan_bus_on_node Yinghai Lu
2012-03-01  3:00 ` [PATCH 15/36] PCI: Add busn_res into struct pci_bus Yinghai Lu
2012-03-01  3:00 ` [PATCH 16/36] PCI: Add busn_res operation functions Yinghai Lu
2012-03-01  3:00 ` [PATCH 17/36] PCI: release busn when removing bus Yinghai Lu
2012-03-01  3:00 ` [PATCH 18/36] PCI: insert busn_res in pci_create_root_bus Yinghai Lu
2012-03-01  3:00 ` [PATCH 19/36] PCI: checking busn_res in pci_scan_root_bus Yinghai Lu
2012-03-01  3:00 ` [PATCH 20/36] PCI: default busn_resource Yinghai Lu
2012-03-01  3:00 ` [PATCH 21/36] PCI: add default res for pci_scan_bus Yinghai Lu
2012-03-01  3:00 ` [PATCH 22/36] x86, PCI: add busn into resources list for acpi path Yinghai Lu
2012-03-01  3:00 ` [PATCH 23/36] x86, PCI: put busn resource in pci_root_info for no_crs path Yinghai Lu
2012-03-01  3:00 ` [PATCH 24/36] PCI, ia64: Register busn_res for root buses Yinghai Lu
2012-03-01  3:00   ` Yinghai Lu
2012-03-01  3:00 ` [PATCH 25/36] PCI, sparc: " Yinghai Lu
2012-03-01  3:00   ` Yinghai Lu
2012-03-01  3:00 ` [PATCH 26/36] PCI, powerpc: " Yinghai Lu
2012-03-01  3:00   ` Yinghai Lu
2012-03-01  3:00 ` [PATCH 27/36] PCI, parisc: " Yinghai Lu
2012-03-01  3:00 ` [PATCH 28/36] PCI: Add pci_bus_extend/shrink_top() Yinghai Lu
2012-03-16 19:36   ` Bjorn Helgaas
2012-03-16 20:42     ` Yinghai Lu
2012-03-16 21:04       ` Bjorn Helgaas
2012-03-01  3:00 ` [PATCH 29/36] PCI: Probe safe range that we can use for unassigned bridge Yinghai Lu
2012-03-01  3:00 ` [PATCH 30/36] PCI: Strict checking of valid range for bridge Yinghai Lu
2012-03-01  3:00 ` [PATCH 31/36] PCI: Allocate bus range instead of use max blindly Yinghai Lu
2012-03-01  3:00 ` [PATCH 32/36] PCI: kill pci_fixup_parent_subordinate_busnr() Yinghai Lu
2012-03-01  3:00 ` [PATCH 33/36] PCI: Seperate child bus scanning to two passes overall Yinghai Lu
2012-03-01  3:00 ` [PATCH 34/36] pcmcia: remove workaround for fixing pci parent bus subordinate Yinghai Lu
2012-03-01  3:00   ` Yinghai Lu
2012-03-01  3:00 ` [PATCH 35/36] PCI: Double checking setting for bus register and bus struct Yinghai Lu
2012-03-01  3:00 ` [PATCH 36/36] PCI, pciehp: Remove not needed bus number range checking Yinghai Lu
2012-03-15  6:40 ` [PATCH -v2 00/36] PCI: pci_host_bridge related cleanup and busn_alloc Taku Izumi
2012-03-15 17:40   ` 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=1330570837-26638-11-git-send-email-yinghai@kernel.org \
    --to=yinghai@kernel.org \
    --cc=benh@kernel.crashing.org \
    --cc=bhelgaas@google.com \
    --cc=davem@davemloft.net \
    --cc=jbarnes@virtuousgeek.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux@dominikbrodowski.net \
    --cc=tony.luck@intel.com \
    --cc=x86@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.