LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/6] Introduce mechanism for registering active regions of memory
From: Mel Gorman @ 2006-08-21 13:45 UTC (permalink / raw)
  To: akpm
  Cc: tony.luck, linux-mm, Mel Gorman, linux-kernel, bob.picco, ak,
	linuxppc-dev
In-Reply-To: <20060821134518.22179.46355.sendpatchset@skynet.skynet.ie>


This patch defines the structure to represent an active range of page
frames within a node in an architecture independent manner. Architectures
are expected to register active ranges of PFNs using add_active_range(nid,
start_pfn, end_pfn) and call free_area_init_nodes() passing the PFNs of
the end of each zone.


 include/linux/mm.h     |   47 +++
 include/linux/mmzone.h |   10 
 mm/page_alloc.c        |  552 ++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 584 insertions(+), 25 deletions(-)

Signed-off-by: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: Bob Picco <bob.picco@hp.com>

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-clean/include/linux/mm.h linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/include/linux/mm.h
--- linux-2.6.18-rc4-mm2-clean/include/linux/mm.h	2006-08-21 09:23:52.000000000 +0100
+++ linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/include/linux/mm.h	2006-08-21 10:12:12.000000000 +0100
@@ -974,6 +974,53 @@ extern void free_area_init(unsigned long
 extern void free_area_init_node(int nid, pg_data_t *pgdat,
 	unsigned long * zones_size, unsigned long zone_start_pfn, 
 	unsigned long *zholes_size);
+#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
+/*
+ * With CONFIG_ARCH_POPULATES_NODE_MAP set, an architecture may initialise its
+ * zones, allocate the backing mem_map and account for memory holes in a more
+ * architecture independent manner. This is a substitute for creating the
+ * zone_sizes[] and zholes_size[] arrays and passing them to
+ * free_area_init_node()
+ *
+ * An architecture is expected to register range of page frames backed by
+ * physical memory with add_active_range() before calling
+ * free_area_init_nodes() passing in the PFN each zone ends at. At a basic
+ * usage, an architecture is expected to do something like
+ *
+ * unsigned long max_zone_pfns[MAX_NR_ZONES] = {max_dma, max_normal_pfn,
+ * 							 max_highmem_pfn};
+ * for_each_valid_physical_page_range()
+ * 	add_active_range(node_id, start_pfn, end_pfn)
+ * free_area_init_nodes(max_zone_pfns);
+ *
+ * If the architecture guarantees that there are no holes in the ranges
+ * registered with add_active_range(), free_bootmem_active_regions()
+ * will call free_bootmem_node() for each registered physical page range.
+ * Similarly sparse_memory_present_with_active_regions() calls
+ * memory_present() for each range when SPARSEMEM is enabled.
+ *
+ * See mm/page_alloc.c for more information on each function exposed by
+ * CONFIG_ARCH_POPULATES_NODE_MAP
+ */
+extern void free_area_init_nodes(unsigned long *max_zone_pfn);
+extern void add_active_range(unsigned int nid, unsigned long start_pfn,
+					unsigned long end_pfn);
+extern void shrink_active_range(unsigned int nid, unsigned long old_end_pfn,
+						unsigned long new_end_pfn);
+extern void remove_all_active_ranges(void);
+extern unsigned long absent_pages_in_range(unsigned long start_pfn,
+						unsigned long end_pfn);
+extern void get_pfn_range_for_nid(unsigned int nid,
+			unsigned long *start_pfn, unsigned long *end_pfn);
+extern unsigned long find_min_pfn_with_active_regions(void);
+extern unsigned long find_max_pfn_with_active_regions(void);
+extern void free_bootmem_with_active_regions(int nid,
+						unsigned long max_low_pfn);
+extern void sparse_memory_present_with_active_regions(int nid);
+#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
+extern int early_pfn_to_nid(unsigned long pfn);
+#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
+#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
 extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long);
 extern void setup_per_zone_pages_min(void);
 extern void mem_init(void);
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-clean/include/linux/mmzone.h linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/include/linux/mmzone.h
--- linux-2.6.18-rc4-mm2-clean/include/linux/mmzone.h	2006-08-21 09:23:52.000000000 +0100
+++ linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/include/linux/mmzone.h	2006-08-21 10:12:12.000000000 +0100
@@ -307,6 +307,13 @@ struct zonelist {
 	struct zone *zones[MAX_NUMNODES * MAX_NR_ZONES + 1]; // NULL delimited
 };
 
+#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
+struct node_active_region {
+	unsigned long start_pfn;
+	unsigned long end_pfn;
+	int nid;
+};
+#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
 
 /*
  * The pg_data_t structure is used in machines with CONFIG_DISCONTIGMEM
@@ -519,7 +526,8 @@ extern struct zone *next_zone(struct zon
 
 #endif
 
-#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
+#if !defined(CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID) && \
+	!defined(CONFIG_ARCH_POPULATES_NODE_MAP)
 #define early_pfn_to_nid(nid)  (0UL)
 #endif
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-clean/mm/page_alloc.c linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/mm/page_alloc.c
--- linux-2.6.18-rc4-mm2-clean/mm/page_alloc.c	2006-08-21 09:23:52.000000000 +0100
+++ linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/mm/page_alloc.c	2006-08-21 10:12:12.000000000 +0100
@@ -37,6 +37,8 @@
 #include <linux/vmalloc.h>
 #include <linux/mempolicy.h>
 #include <linux/stop_machine.h>
+#include <linux/sort.h>
+#include <linux/pfn.h>
 
 #include <asm/tlbflush.h>
 #include <asm/div64.h>
@@ -103,6 +105,33 @@ int min_free_kbytes = 1024;
 unsigned long __meminitdata nr_kernel_pages;
 unsigned long __meminitdata nr_all_pages;
 
+#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
+  /*
+   * MAX_ACTIVE_REGIONS determines the maxmimum number of distinct
+   * ranges of memory (RAM) that may be registered with add_active_range().
+   * Ranges passed to add_active_range() will be merged if possible
+   * so the number of times add_active_range() can be called is
+   * related to the number of nodes and the number of holes
+   */
+  #ifdef CONFIG_MAX_ACTIVE_REGIONS
+    /* Allow an architecture to set MAX_ACTIVE_REGIONS to save memory */
+    #define MAX_ACTIVE_REGIONS CONFIG_MAX_ACTIVE_REGIONS
+  #else
+    #if MAX_NUMNODES >= 32
+      /* If there can be many nodes, allow up to 50 holes per node */
+      #define MAX_ACTIVE_REGIONS (MAX_NUMNODES*50)
+    #else
+      /* By default, allow up to 256 distinct regions */
+      #define MAX_ACTIVE_REGIONS 256
+    #endif
+  #endif
+
+  struct node_active_region __initdata early_node_map[MAX_ACTIVE_REGIONS];
+  int __initdata nr_nodemap_entries;
+  unsigned long __initdata arch_zone_lowest_possible_pfn[MAX_NR_ZONES];
+  unsigned long __initdata arch_zone_highest_possible_pfn[MAX_NR_ZONES];
+#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
+
 #ifdef CONFIG_DEBUG_VM
 static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
 {
@@ -1731,25 +1760,6 @@ static inline unsigned long wait_table_b
 
 #define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
 
-static void __init calculate_zone_totalpages(struct pglist_data *pgdat,
-		unsigned long *zones_size, unsigned long *zholes_size)
-{
-	unsigned long realtotalpages, totalpages = 0;
-	enum zone_type i;
-
-	for (i = 0; i < MAX_NR_ZONES; i++)
-		totalpages += zones_size[i];
-	pgdat->node_spanned_pages = totalpages;
-
-	realtotalpages = totalpages;
-	if (zholes_size)
-		for (i = 0; i < MAX_NR_ZONES; i++)
-			realtotalpages -= zholes_size[i];
-	pgdat->node_present_pages = realtotalpages;
-	printk(KERN_DEBUG "On node %d totalpages: %lu\n", pgdat->node_id, realtotalpages);
-}
-
-
 /*
  * Initially all pages are reserved - free ones are freed
  * up by free_all_bootmem() once the early boot process is
@@ -2067,6 +2077,272 @@ __meminit int init_currently_empty_zone(
 	return 0;
 }
 
+#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
+/*
+ * Basic iterator support. Return the first range of PFNs for a node
+ * Note: nid == MAX_NUMNODES returns first region regardless of node
+ */
+static int __init first_active_region_index_in_nid(int nid)
+{
+	int i;
+
+	for (i = 0; i < nr_nodemap_entries; i++)
+		if (nid == MAX_NUMNODES || early_node_map[i].nid == nid)
+			return i;
+
+	return -1;
+}
+
+/*
+ * Basic iterator support. Return the next active range of PFNs for a node
+ * Note: nid == MAX_NUMNODES returns next region regardles of node
+ */
+static int __init next_active_region_index_in_nid(int index, int nid)
+{
+	for (index = index + 1; index < nr_nodemap_entries; index++)
+		if (nid == MAX_NUMNODES || early_node_map[index].nid == nid)
+			return index;
+
+	return -1;
+}
+
+#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
+/*
+ * Required by SPARSEMEM. Given a PFN, return what node the PFN is on.
+ * Architectures may implement their own version but if add_active_range()
+ * was used and there are no special requirements, this is a convenient
+ * alternative
+ */
+int __init early_pfn_to_nid(unsigned long pfn)
+{
+	int i;
+
+	for (i = 0; i < nr_nodemap_entries; i++) {
+		unsigned long start_pfn = early_node_map[i].start_pfn;
+		unsigned long end_pfn = early_node_map[i].end_pfn;
+
+		if (start_pfn <= pfn && pfn < end_pfn)
+			return early_node_map[i].nid;
+	}
+
+	return 0;
+}
+#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
+
+/* Basic iterator support to walk early_node_map[] */
+#define for_each_active_range_index_in_nid(i, nid) \
+	for (i = first_active_region_index_in_nid(nid); i != -1; \
+				i = next_active_region_index_in_nid(i, nid))
+
+/**
+ * free_bootmem_with_active_regions - Call free_bootmem_node for each active range
+ * @nid: The node to free memory on. If MAX_NUMNODES, all nodes are freed
+ * @max_low_pfn: The highest PFN that till be passed to free_bootmem_node
+ *
+ * If an architecture guarantees that all ranges registered with
+ * add_active_ranges() contain no holes and may be freed, this
+ * this function may be used instead of calling free_bootmem() manually.
+ */
+void __init free_bootmem_with_active_regions(int nid,
+						unsigned long max_low_pfn)
+{
+	int i;
+
+	for_each_active_range_index_in_nid(i, nid) {
+		unsigned long size_pages = 0;
+		unsigned long end_pfn = early_node_map[i].end_pfn;
+
+		if (early_node_map[i].start_pfn >= max_low_pfn)
+			continue;
+
+		if (end_pfn > max_low_pfn)
+			end_pfn = max_low_pfn;
+
+		size_pages = end_pfn - early_node_map[i].start_pfn;
+		free_bootmem_node(NODE_DATA(early_node_map[i].nid),
+				PFN_PHYS(early_node_map[i].start_pfn),
+				size_pages << PAGE_SHIFT);
+	}
+}
+
+/**
+ * sparse_memory_present_with_active_regions - Call memory_present for each active range
+ * @nid: The node to call memory_present for. If MAX_NUMNODES, all nodes will be used
+ *
+ * If an architecture guarantees that all ranges registered with
+ * add_active_ranges() contain no holes and may be freed, this
+ * this function may be used instead of calling memory_present() manually.
+ */
+void __init sparse_memory_present_with_active_regions(int nid)
+{
+	int i;
+
+	for_each_active_range_index_in_nid(i, nid)
+		memory_present(early_node_map[i].nid,
+				early_node_map[i].start_pfn,
+				early_node_map[i].end_pfn);
+}
+
+/**
+ * get_pfn_range_for_nid - Return the start and end page frames for a node
+ * @nid: The nid to return the range for. If MAX_NUMNODES, the min and max PFN are returned
+ * @start_pfn: Passed by reference. On return, it will have the node start_pfn
+ * @end_pfn: Passed by reference. On return, it will have the node end_pfn
+ *
+ * It returns the start and end page frame of a node based on information
+ * provided by an arch calling add_active_range(). If called for a node
+ * with no available memory, a warning is printed and the start and end
+ * PFNs will be 0
+ */
+void __init get_pfn_range_for_nid(unsigned int nid,
+			unsigned long *start_pfn, unsigned long *end_pfn)
+{
+	int i;
+	*start_pfn = -1UL;
+	*end_pfn = 0;
+
+	for_each_active_range_index_in_nid(i, nid) {
+		*start_pfn = min(*start_pfn, early_node_map[i].start_pfn);
+		*end_pfn = max(*end_pfn, early_node_map[i].end_pfn);
+	}
+
+	if (*start_pfn == -1UL) {
+		printk(KERN_WARNING "Node %u active with no memory\n", nid);
+		*start_pfn = 0;
+	}
+}
+
+/*
+ * Return the number of pages a zone spans in a node, including holes
+ * present_pages = zone_spanned_pages_in_node() - zone_absent_pages_in_node()
+ */
+unsigned long __init zone_spanned_pages_in_node(int nid,
+					unsigned long zone_type,
+					unsigned long *ignored)
+{
+	unsigned long node_start_pfn, node_end_pfn;
+	unsigned long zone_start_pfn, zone_end_pfn;
+
+	/* Get the start and end of the node and zone */
+	get_pfn_range_for_nid(nid, &node_start_pfn, &node_end_pfn);
+	zone_start_pfn = arch_zone_lowest_possible_pfn[zone_type];
+	zone_end_pfn = arch_zone_highest_possible_pfn[zone_type];
+
+	/* Check that this node has pages within the zone's required range */
+	if (zone_end_pfn < node_start_pfn || zone_start_pfn > node_end_pfn)
+		return 0;
+
+	/* Move the zone boundaries inside the node if necessary */
+	zone_end_pfn = min(zone_end_pfn, node_end_pfn);
+	zone_start_pfn = max(zone_start_pfn, node_start_pfn);
+
+	/* Return the spanned pages */
+	return zone_end_pfn - zone_start_pfn;
+}
+
+/*
+ * Return the number of holes in a range on a node. If nid is MAX_NUMNODES,
+ * then all holes in the requested range will be accounted for
+ */
+unsigned long __init __absent_pages_in_range(int nid,
+				unsigned long range_start_pfn,
+				unsigned long range_end_pfn)
+{
+	int i = 0;
+	unsigned long prev_end_pfn = 0, hole_pages = 0;
+	unsigned long start_pfn;
+
+	/* Find the end_pfn of the first active range of pfns in the node */
+	i = first_active_region_index_in_nid(nid);
+	if (i == -1)
+		return 0;
+
+	prev_end_pfn = early_node_map[i].start_pfn;
+
+	/* Find all holes for the zone within the node */
+	for (; i != -1; i = next_active_region_index_in_nid(i, nid)) {
+
+		/* No need to continue if prev_end_pfn is outside the zone */
+		if (prev_end_pfn >= range_end_pfn)
+			break;
+
+		/* Make sure the end of the zone is not within the hole */
+		start_pfn = min(early_node_map[i].start_pfn, range_end_pfn);
+		prev_end_pfn = max(prev_end_pfn, range_start_pfn);
+
+		/* Update the hole size cound and move on */
+		if (start_pfn > range_start_pfn) {
+			BUG_ON(prev_end_pfn > start_pfn);
+			hole_pages += start_pfn - prev_end_pfn;
+		}
+		prev_end_pfn = early_node_map[i].end_pfn;
+	}
+
+	return hole_pages;
+}
+
+/**
+ * absent_pages_in_range - Return number of page frames in holes within a range
+ * @start_pfn: The start PFN to start searching for holes
+ * @end_pfn: The end PFN to stop searching for holes
+ *
+ * It returns the number of pages frames in memory holes within a range
+ */
+unsigned long __init absent_pages_in_range(unsigned long start_pfn,
+							unsigned long end_pfn)
+{
+	return __absent_pages_in_range(MAX_NUMNODES, start_pfn, end_pfn);
+}
+
+/* Return the number of page frames in holes in a zone on a node */
+unsigned long __init zone_absent_pages_in_node(int nid,
+					unsigned long zone_type,
+					unsigned long *ignored)
+{
+	return __absent_pages_in_range(nid,
+				arch_zone_lowest_possible_pfn[zone_type],
+				arch_zone_highest_possible_pfn[zone_type]);
+}
+#else
+static inline unsigned long zone_spanned_pages_in_node(int nid,
+					unsigned long zone_type,
+					unsigned long *zones_size)
+{
+	return zones_size[zone_type];
+}
+
+static inline unsigned long zone_absent_pages_in_node(int nid,
+						unsigned long zone_type,
+						unsigned long *zholes_size)
+{
+	if (!zholes_size)
+		return 0;
+
+	return zholes_size[zone_type];
+}
+#endif
+
+static void __init calculate_node_totalpages(struct pglist_data *pgdat,
+		unsigned long *zones_size, unsigned long *zholes_size)
+{
+	unsigned long realtotalpages, totalpages = 0;
+	enum zone_type i;
+
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		totalpages += zone_spanned_pages_in_node(pgdat->node_id, i,
+								zones_size);
+	pgdat->node_spanned_pages = totalpages;
+
+	realtotalpages = totalpages;
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		realtotalpages -=
+			zone_absent_pages_in_node(pgdat->node_id, i,
+								zholes_size);
+	pgdat->node_present_pages = realtotalpages;
+	printk(KERN_DEBUG "On node %d totalpages: %lu\n", pgdat->node_id,
+							realtotalpages);
+}
+
 /*
  * Set up the zone data structures:
  *   - mark all pages reserved
@@ -2090,9 +2366,9 @@ static void __meminit free_area_init_cor
 		struct zone *zone = pgdat->node_zones + j;
 		unsigned long size, realsize;
 
-		realsize = size = zones_size[j];
-		if (zholes_size)
-			realsize -= zholes_size[j];
+		size = zone_spanned_pages_in_node(nid, j, zones_size);
+		realsize = size - zone_absent_pages_in_node(nid, j,
+								zholes_size);
 
 		if (!is_highmem_idx(j))
 			nr_kernel_pages += realsize;
@@ -2162,8 +2438,13 @@ static void __init alloc_node_mem_map(st
 	/*
 	 * With no DISCONTIG, the global mem_map is just set as node 0's
 	 */
-	if (pgdat == NODE_DATA(0))
+	if (pgdat == NODE_DATA(0)) {
 		mem_map = NODE_DATA(0)->node_mem_map;
+#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
+		if (page_to_pfn(mem_map) != pgdat->node_start_pfn)
+			mem_map -= pgdat->node_start_pfn;
+#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
+	}
 #endif
 #endif /* CONFIG_FLAT_NODE_MEM_MAP */
 }
@@ -2174,13 +2455,236 @@ void __meminit free_area_init_node(int n
 {
 	pgdat->node_id = nid;
 	pgdat->node_start_pfn = node_start_pfn;
-	calculate_zone_totalpages(pgdat, zones_size, zholes_size);
+	calculate_node_totalpages(pgdat, zones_size, zholes_size);
 
 	alloc_node_mem_map(pgdat);
 
 	free_area_init_core(pgdat, zones_size, zholes_size);
 }
 
+#ifdef CONFIG_ARCH_POPULATES_NODE_MAP
+/**
+ * add_active_range - Register a range of PFNs backed by physical memory
+ * @nid: The node ID the range resides on
+ * @start_pfn: The start PFN of the available physical memory
+ * @end_pfn: The end PFN of the available physical memory
+ *
+ * These ranges are stored in an early_node_map[] and later used by
+ * free_area_init_nodes() to calculate zone sizes and holes. If the
+ * range spans a memory hole, it is up to the architecture to ensure
+ * the memory is not freed by the bootmem allocator. If possible
+ * the range being registered will be merged with existing ranges.
+ */
+void __init add_active_range(unsigned int nid, unsigned long start_pfn,
+						unsigned long end_pfn)
+{
+	int i;
+
+	printk(KERN_DEBUG "Entering add_active_range(%d, %lu, %lu) "
+			  "%d entries of %d used\n",
+			  nid, start_pfn, end_pfn,
+			  nr_nodemap_entries, MAX_ACTIVE_REGIONS);
+
+	/* Merge with existing active regions if possible */
+	for (i = 0; i < nr_nodemap_entries; i++) {
+		if (early_node_map[i].nid != nid)
+			continue;
+
+		/* Skip if an existing region covers this new one */
+		if (start_pfn >= early_node_map[i].start_pfn &&
+				end_pfn <= early_node_map[i].end_pfn)
+			return;
+
+		/* Merge forward if suitable */
+		if (start_pfn <= early_node_map[i].end_pfn &&
+				end_pfn > early_node_map[i].end_pfn) {
+			early_node_map[i].end_pfn = end_pfn;
+			return;
+		}
+
+		/* Merge backward if suitable */
+		if (start_pfn < early_node_map[i].end_pfn &&
+				end_pfn >= early_node_map[i].start_pfn) {
+			early_node_map[i].start_pfn = start_pfn;
+			return;
+		}
+	}
+
+	/* Check that early_node_map is large enough */
+	if (i >= MAX_ACTIVE_REGIONS) {
+		printk(KERN_CRIT "More than %d memory regions, truncating\n",
+							MAX_ACTIVE_REGIONS);
+		return;
+	}
+
+	early_node_map[i].nid = nid;
+	early_node_map[i].start_pfn = start_pfn;
+	early_node_map[i].end_pfn = end_pfn;
+	nr_nodemap_entries = i + 1;
+}
+
+/**
+ * shrink_active_range - Shrink an existing registered range of PFNs
+ * @nid: The node id the range is on that should be shrunk
+ * @old_end_pfn: The old end PFN of the range
+ * @new_end_pfn: The new PFN of the range
+ *
+ * i386 with NUMA use alloc_remap() to store a node_mem_map on a local node.
+ * The map is kept at the end physical page range that has already been
+ * registered with add_active_range(). This function allows an arch to shrink
+ * an existing registered range.
+ */
+void __init shrink_active_range(unsigned int nid, unsigned long old_end_pfn,
+						unsigned long new_end_pfn)
+{
+	int i;
+
+	/* Find the old active region end and shrink */
+	for_each_active_range_index_in_nid(i, nid)
+		if (early_node_map[i].end_pfn == old_end_pfn) {
+			early_node_map[i].end_pfn = new_end_pfn;
+			break;
+		}
+}
+
+/**
+ * remove_all_active_ranges - Remove all currently registered regions
+ * During discovery, it may be found that a table like SRAT is invalid
+ * and an alternative discovery method must be used. This function removes
+ * all currently registered regions.
+ */
+void __init remove_all_active_ranges()
+{
+	memset(early_node_map, 0, sizeof(early_node_map));
+	nr_nodemap_entries = 0;
+}
+
+/* Compare two active node_active_regions */
+static int __init cmp_node_active_region(const void *a, const void *b)
+{
+	struct node_active_region *arange = (struct node_active_region *)a;
+	struct node_active_region *brange = (struct node_active_region *)b;
+
+	/* Done this way to avoid overflows */
+	if (arange->start_pfn > brange->start_pfn)
+		return 1;
+	if (arange->start_pfn < brange->start_pfn)
+		return -1;
+
+	return 0;
+}
+
+/* sort the node_map by start_pfn */
+static void __init sort_node_map(void)
+{
+	sort(early_node_map, (size_t)nr_nodemap_entries,
+			sizeof(struct node_active_region),
+			cmp_node_active_region, NULL);
+}
+
+/* Find the lowest pfn for a node. This depends on a sorted early_node_map */
+unsigned long __init find_min_pfn_for_node(unsigned long nid)
+{
+	int i;
+
+	/* Assuming a sorted map, the first range found has the starting pfn */
+	for_each_active_range_index_in_nid(i, nid)
+		return early_node_map[i].start_pfn;
+
+	printk(KERN_WARNING "Could not find start_pfn for node %lu\n", nid);
+	return 0;
+}
+
+/**
+ * find_min_pfn_with_active_regions - Find the minimum PFN registered
+ *
+ * It returns the minimum PFN based on information provided via
+ * add_active_range()
+ */
+unsigned long __init find_min_pfn_with_active_regions(void)
+{
+	return find_min_pfn_for_node(MAX_NUMNODES);
+}
+
+/**
+ * find_max_pfn_with_active_regions - Find the maximum PFN registered
+ *
+ * It returns the maximum PFN based on information provided via
+ * add_active_range()
+ */
+unsigned long __init find_max_pfn_with_active_regions(void)
+{
+	int i;
+	unsigned long max_pfn = 0;
+
+	for (i = 0; i < nr_nodemap_entries; i++)
+		max_pfn = max(max_pfn, early_node_map[i].end_pfn);
+
+	return max_pfn;
+}
+
+/**
+ * free_area_init_nodes - Initialise all pg_data_t and zone data
+ * @arch_max_dma_pfn: The maximum PFN usable for ZONE_DMA
+ * @arch_max_dma32_pfn: The maximum PFN usable for ZONE_DMA32
+ * @arch_max_low_pfn: The maximum PFN usable for ZONE_NORMAL
+ * @arch_max_high_pfn: The maximum PFN usable for ZONE_HIGHMEM
+ *
+ * This will call free_area_init_node() for each active node in the system.
+ * Using the page ranges provided by add_active_range(), the size of each
+ * zone in each node and their holes is calculated. If the maximum PFN
+ * between two adjacent zones match, it is assumed that the zone is empty.
+ * For example, if arch_max_dma_pfn == arch_max_dma32_pfn, it is assumed
+ * that arch_max_dma32_pfn has no pages. It is also assumed that a zone
+ * starts where the previous one ended. For example, ZONE_DMA32 starts
+ * at arch_max_dma_pfn.
+ */
+void __init free_area_init_nodes(unsigned long *max_zone_pfn)
+{
+	unsigned long nid;
+	enum zone_type i;
+
+	/* Record where the zone boundaries are */
+	memset(arch_zone_lowest_possible_pfn, 0,
+				sizeof(arch_zone_lowest_possible_pfn));
+	memset(arch_zone_highest_possible_pfn, 0,
+				sizeof(arch_zone_highest_possible_pfn));
+	arch_zone_lowest_possible_pfn[0] = find_min_pfn_with_active_regions();
+	arch_zone_highest_possible_pfn[0] = max_zone_pfn[0];
+	for (i = 1; i < MAX_NR_ZONES; i++) {
+		arch_zone_lowest_possible_pfn[i] =
+			arch_zone_highest_possible_pfn[i-1];
+		arch_zone_highest_possible_pfn[i] =
+			max(max_zone_pfn[i], arch_zone_lowest_possible_pfn[i]);
+	}
+
+	/* Regions in the early_node_map can be in any order */
+	sort_node_map();
+
+	/* Print out the zone ranges */
+	printk("Zone PFN ranges:\n");
+	for (i = 0; i < MAX_NR_ZONES; i++)
+		printk("  %-8s %8lu -> %8lu\n",
+				zone_names[i],
+				arch_zone_lowest_possible_pfn[i],
+				arch_zone_highest_possible_pfn[i]);
+
+	/* Print out the early_node_map[] */
+	printk("early_node_map[%d] active PFN ranges\n", nr_nodemap_entries);
+	for (i = 0; i < nr_nodemap_entries; i++)
+		printk("  %3d: %8lu -> %8lu\n", early_node_map[i].nid,
+						early_node_map[i].start_pfn,
+						early_node_map[i].end_pfn);
+
+	/* Initialise every node */
+	for_each_online_node(nid) {
+		pg_data_t *pgdat = NODE_DATA(nid);
+		free_area_init_node(nid, pgdat, NULL,
+				find_min_pfn_for_node(nid), NULL);
+	}
+}
+#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
+
 #ifndef CONFIG_NEED_MULTIPLE_NODES
 static bootmem_data_t contig_bootmem_data;
 struct pglist_data contig_page_data = { .bdata = &contig_bootmem_data };

^ permalink raw reply

* [PATCH 2/6] Have Power use add_active_range() and free_area_init_nodes()
From: Mel Gorman @ 2006-08-21 13:45 UTC (permalink / raw)
  To: akpm
  Cc: tony.luck, linuxppc-dev, Mel Gorman, ak, bob.picco, linux-kernel,
	linux-mm
In-Reply-To: <20060821134518.22179.46355.sendpatchset@skynet.skynet.ie>


Size zones and holes in an architecture independent manner for Power.


 powerpc/Kconfig   |    7 --
 powerpc/mm/mem.c  |   51 +++++----------
 powerpc/mm/numa.c |  159 ++++---------------------------------------------
 ppc/Kconfig       |    3 
 ppc/mm/init.c     |   23 +++----
 5 files changed, 52 insertions(+), 191 deletions(-)

Signed-off-by: Mel Gorman <mel@csn.ul.ie>

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/powerpc/Kconfig linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/powerpc/Kconfig
--- linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/powerpc/Kconfig	2006-08-06 19:20:11.000000000 +0100
+++ linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/powerpc/Kconfig	2006-08-21 10:13:25.000000000 +0100
@@ -715,11 +715,10 @@ config ARCH_SPARSEMEM_DEFAULT
 	def_bool y
 	depends on SMP && PPC_PSERIES
 
-source "mm/Kconfig"
-
-config HAVE_ARCH_EARLY_PFN_TO_NID
+config ARCH_POPULATES_NODE_MAP
 	def_bool y
-	depends on NEED_MULTIPLE_NODES
+
+source "mm/Kconfig"
 
 config ARCH_MEMORY_PROBE
 	def_bool y
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/powerpc/mm/mem.c linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/powerpc/mm/mem.c
--- linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/powerpc/mm/mem.c	2006-08-06 19:20:11.000000000 +0100
+++ linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/powerpc/mm/mem.c	2006-08-21 10:13:25.000000000 +0100
@@ -256,20 +256,22 @@ void __init do_init_bootmem(void)
 
 	boot_mapsize = init_bootmem(start >> PAGE_SHIFT, total_pages);
 
+	/* Add active regions with valid PFNs */
+	for (i = 0; i < lmb.memory.cnt; i++) {
+		unsigned long start_pfn, end_pfn;
+		start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
+		end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
+		add_active_range(0, start_pfn, end_pfn);
+	}
+
 	/* Add all physical memory to the bootmem map, mark each area
 	 * present.
 	 */
-	for (i = 0; i < lmb.memory.cnt; i++) {
-		unsigned long base = lmb.memory.region[i].base;
-		unsigned long size = lmb_size_bytes(&lmb.memory, i);
 #ifdef CONFIG_HIGHMEM
-		if (base >= total_lowmem)
-			continue;
-		if (base + size > total_lowmem)
-			size = total_lowmem - base;
+	free_bootmem_with_active_regions(0, total_lowmem >> PAGE_SHIFT);
+#else
+	free_bootmem_with_active_regions(0, max_pfn);
 #endif
-		free_bootmem(base, size);
-	}
 
 	/* reserve the sections we're already using */
 	for (i = 0; i < lmb.reserved.cnt; i++)
@@ -277,9 +279,8 @@ void __init do_init_bootmem(void)
 				lmb_size_bytes(&lmb.reserved, i));
 
 	/* XXX need to clip this if using highmem? */
-	for (i = 0; i < lmb.memory.cnt; i++)
-		memory_present(0, lmb_start_pfn(&lmb.memory, i),
-			       lmb_end_pfn(&lmb.memory, i));
+	sparse_memory_present_with_active_regions(0);
+
 	init_bootmem_done = 1;
 }
 
@@ -288,10 +289,9 @@ void __init do_init_bootmem(void)
  */
 void __init paging_init(void)
 {
-	unsigned long zones_size[MAX_NR_ZONES];
-	unsigned long zholes_size[MAX_NR_ZONES];
 	unsigned long total_ram = lmb_phys_mem_size();
 	unsigned long top_of_ram = lmb_end_of_DRAM();
+	unsigned long max_zone_pfns[MAX_NR_ZONES];
 
 #ifdef CONFIG_HIGHMEM
 	map_page(PKMAP_BASE, 0, 0);	/* XXX gross */
@@ -307,26 +307,13 @@ void __init paging_init(void)
 	       top_of_ram, total_ram);
 	printk(KERN_DEBUG "Memory hole size: %ldMB\n",
 	       (top_of_ram - total_ram) >> 20);
-	/*
-	 * All pages are DMA-able so we put them all in the DMA zone.
-	 */
-	memset(zones_size, 0, sizeof(zones_size));
-	memset(zholes_size, 0, sizeof(zholes_size));
-
-	zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
-	zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
-
 #ifdef CONFIG_HIGHMEM
-	zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
-	zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT;
-	zholes_size[ZONE_HIGHMEM] = (top_of_ram - total_ram) >> PAGE_SHIFT;
+	max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT;
+	max_zone_pfns[1] = top_of_ram >> PAGE_SHIFT;
 #else
-	zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT;
-	zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT;
-#endif /* CONFIG_HIGHMEM */
-
-	free_area_init_node(0, NODE_DATA(0), zones_size,
-			    __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size);
+	max_zone_pfns[0] = top_of_ram >> PAGE_SHIFT;
+#endif
+	free_area_init_nodes(max_zone_pfns);
 }
 #endif /* ! CONFIG_NEED_MULTIPLE_NODES */
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/powerpc/mm/numa.c linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/powerpc/mm/numa.c
--- linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/powerpc/mm/numa.c	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/powerpc/mm/numa.c	2006-08-21 10:13:25.000000000 +0100
@@ -39,96 +39,6 @@ static bootmem_data_t __initdata plat_no
 static int min_common_depth;
 static int n_mem_addr_cells, n_mem_size_cells;
 
-/*
- * We need somewhere to store start/end/node for each region until we have
- * allocated the real node_data structures.
- */
-#define MAX_REGIONS	(MAX_LMB_REGIONS*2)
-static struct {
-	unsigned long start_pfn;
-	unsigned long end_pfn;
-	int nid;
-} init_node_data[MAX_REGIONS] __initdata;
-
-int __init early_pfn_to_nid(unsigned long pfn)
-{
-	unsigned int i;
-
-	for (i = 0; init_node_data[i].end_pfn; i++) {
-		unsigned long start_pfn = init_node_data[i].start_pfn;
-		unsigned long end_pfn = init_node_data[i].end_pfn;
-
-		if ((start_pfn <= pfn) && (pfn < end_pfn))
-			return init_node_data[i].nid;
-	}
-
-	return -1;
-}
-
-void __init add_region(unsigned int nid, unsigned long start_pfn,
-		       unsigned long pages)
-{
-	unsigned int i;
-
-	dbg("add_region nid %d start_pfn 0x%lx pages 0x%lx\n",
-		nid, start_pfn, pages);
-
-	for (i = 0; init_node_data[i].end_pfn; i++) {
-		if (init_node_data[i].nid != nid)
-			continue;
-		if (init_node_data[i].end_pfn == start_pfn) {
-			init_node_data[i].end_pfn += pages;
-			return;
-		}
-		if (init_node_data[i].start_pfn == (start_pfn + pages)) {
-			init_node_data[i].start_pfn -= pages;
-			return;
-		}
-	}
-
-	/*
-	 * Leave last entry NULL so we dont iterate off the end (we use
-	 * entry.end_pfn to terminate the walk).
-	 */
-	if (i >= (MAX_REGIONS - 1)) {
-		printk(KERN_ERR "WARNING: too many memory regions in "
-				"numa code, truncating\n");
-		return;
-	}
-
-	init_node_data[i].start_pfn = start_pfn;
-	init_node_data[i].end_pfn = start_pfn + pages;
-	init_node_data[i].nid = nid;
-}
-
-/* We assume init_node_data has no overlapping regions */
-void __init get_region(unsigned int nid, unsigned long *start_pfn,
-		       unsigned long *end_pfn, unsigned long *pages_present)
-{
-	unsigned int i;
-
-	*start_pfn = -1UL;
-	*end_pfn = *pages_present = 0;
-
-	for (i = 0; init_node_data[i].end_pfn; i++) {
-		if (init_node_data[i].nid != nid)
-			continue;
-
-		*pages_present += init_node_data[i].end_pfn -
-			init_node_data[i].start_pfn;
-
-		if (init_node_data[i].start_pfn < *start_pfn)
-			*start_pfn = init_node_data[i].start_pfn;
-
-		if (init_node_data[i].end_pfn > *end_pfn)
-			*end_pfn = init_node_data[i].end_pfn;
-	}
-
-	/* We didnt find a matching region, return start/end as 0 */
-	if (*start_pfn == -1UL)
-		*start_pfn = 0;
-}
-
 static void __cpuinit map_cpu_to_node(int cpu, int node)
 {
 	numa_cpu_lookup_table[cpu] = node;
@@ -468,8 +378,8 @@ new_range:
 				continue;
 		}
 
-		add_region(nid, start >> PAGE_SHIFT,
-			   size >> PAGE_SHIFT);
+		add_active_range(nid, start >> PAGE_SHIFT,
+				(start >> PAGE_SHIFT) + (size >> PAGE_SHIFT));
 
 		if (--ranges)
 			goto new_range;
@@ -482,6 +392,7 @@ static void __init setup_nonnuma(void)
 {
 	unsigned long top_of_ram = lmb_end_of_DRAM();
 	unsigned long total_ram = lmb_phys_mem_size();
+	unsigned long start_pfn, end_pfn;
 	unsigned int i;
 
 	printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
@@ -489,9 +400,11 @@ static void __init setup_nonnuma(void)
 	printk(KERN_DEBUG "Memory hole size: %ldMB\n",
 	       (top_of_ram - total_ram) >> 20);
 
-	for (i = 0; i < lmb.memory.cnt; ++i)
-		add_region(0, lmb.memory.region[i].base >> PAGE_SHIFT,
-			   lmb_size_pages(&lmb.memory, i));
+	for (i = 0; i < lmb.memory.cnt; ++i) {
+		start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
+		end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
+		add_active_range(0, start_pfn, end_pfn);
+	}
 	node_set_online(0);
 }
 
@@ -630,11 +543,11 @@ void __init do_init_bootmem(void)
 			  (void *)(unsigned long)boot_cpuid);
 
 	for_each_online_node(nid) {
-		unsigned long start_pfn, end_pfn, pages_present;
+		unsigned long start_pfn, end_pfn;
 		unsigned long bootmem_paddr;
 		unsigned long bootmap_pages;
 
-		get_region(nid, &start_pfn, &end_pfn, &pages_present);
+		get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
 
 		/* Allocate the node structure node local if possible */
 		NODE_DATA(nid) = careful_allocation(nid,
@@ -667,19 +580,7 @@ void __init do_init_bootmem(void)
 		init_bootmem_node(NODE_DATA(nid), bootmem_paddr >> PAGE_SHIFT,
 				  start_pfn, end_pfn);
 
-		/* Add free regions on this node */
-		for (i = 0; init_node_data[i].end_pfn; i++) {
-			unsigned long start, end;
-
-			if (init_node_data[i].nid != nid)
-				continue;
-
-			start = init_node_data[i].start_pfn << PAGE_SHIFT;
-			end = init_node_data[i].end_pfn << PAGE_SHIFT;
-
-			dbg("free_bootmem %lx %lx\n", start, end - start);
-  			free_bootmem_node(NODE_DATA(nid), start, end - start);
-		}
+		free_bootmem_with_active_regions(nid, end_pfn);
 
 		/* Mark reserved regions on this node */
 		for (i = 0; i < lmb.reserved.cnt; i++) {
@@ -710,44 +611,16 @@ void __init do_init_bootmem(void)
 			}
 		}
 
-		/* Add regions into sparsemem */
-		for (i = 0; init_node_data[i].end_pfn; i++) {
-			unsigned long start, end;
-
-			if (init_node_data[i].nid != nid)
-				continue;
-
-			start = init_node_data[i].start_pfn;
-			end = init_node_data[i].end_pfn;
-
-			memory_present(nid, start, end);
-		}
+		sparse_memory_present_with_active_regions(nid);
 	}
 }
 
 void __init paging_init(void)
 {
-	unsigned long zones_size[MAX_NR_ZONES];
-	unsigned long zholes_size[MAX_NR_ZONES];
-	int nid;
-
-	memset(zones_size, 0, sizeof(zones_size));
-	memset(zholes_size, 0, sizeof(zholes_size));
-
-	for_each_online_node(nid) {
-		unsigned long start_pfn, end_pfn, pages_present;
-
-		get_region(nid, &start_pfn, &end_pfn, &pages_present);
-
-		zones_size[ZONE_DMA] = end_pfn - start_pfn;
-		zholes_size[ZONE_DMA] = zones_size[ZONE_DMA] - pages_present;
-
-		dbg("free_area_init node %d %lx %lx (hole: %lx)\n", nid,
-		    zones_size[ZONE_DMA], start_pfn, zholes_size[ZONE_DMA]);
-
-		free_area_init_node(nid, NODE_DATA(nid), zones_size, start_pfn,
-				    zholes_size);
-	}
+	unsigned long max_zone_pfns[MAX_NR_ZONES] = {
+				lmb_end_of_DRAM() >> PAGE_SHIFT
+	};
+	free_area_init_nodes(max_zone_pfns);
 }
 
 static int __init early_numa(char *p)
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/ppc/Kconfig linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/ppc/Kconfig
--- linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/ppc/Kconfig	2006-08-06 19:20:11.000000000 +0100
+++ linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/ppc/Kconfig	2006-08-21 10:13:25.000000000 +0100
@@ -953,6 +953,9 @@ config NR_CPUS
 config HIGHMEM
 	bool "High memory support"
 
+config ARCH_POPULATES_NODE_MAP
+	def_bool y
+
 source kernel/Kconfig.hz
 source kernel/Kconfig.preempt
 source "mm/Kconfig"
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/ppc/mm/init.c linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/ppc/mm/init.c
--- linux-2.6.18-rc4-mm2-101-add_free_area_init_nodes/arch/ppc/mm/init.c	2006-08-06 19:20:11.000000000 +0100
+++ linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/ppc/mm/init.c	2006-08-21 10:13:25.000000000 +0100
@@ -358,8 +358,8 @@ void __init do_init_bootmem(void)
  */
 void __init paging_init(void)
 {
-	unsigned long zones_size[MAX_NR_ZONES], i;
-
+	unsigned long start_pfn, end_pfn;
+	unsigned long max_zone_pfns;
 #ifdef CONFIG_HIGHMEM
 	map_page(PKMAP_BASE, 0, 0);	/* XXX gross */
 	pkmap_page_table = pte_offset_kernel(pmd_offset(pgd_offset_k
@@ -369,19 +369,18 @@ void __init paging_init(void)
 			(KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN);
 	kmap_prot = PAGE_KERNEL;
 #endif /* CONFIG_HIGHMEM */
-
-	/*
-	 * All pages are DMA-able so we put them all in the DMA zone.
-	 */
-	zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
-	for (i = 1; i < MAX_NR_ZONES; i++)
-		zones_size[i] = 0;
+	/* All pages are DMA-able so we put them all in the DMA zone. */
+	start_pfn = __pa(PAGE_OFFSET) >> PAGE_SHIFT;
+	end_pfn = start_pfn + (total_memory >> PAGE_SHIFT);
+	add_active_range(0, start_pfn, end_pfn);
 
 #ifdef CONFIG_HIGHMEM
-	zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT;
+	max_zone_pfns[0] = total_lowmem >> PAGE_SHIFT;
+	max_zone_pfns[1] = total_memory >> PAGE_SHIFT;
+#else
+	max_zone_pfns[0] = total_memory >> PAGE_SHIFT;
 #endif /* CONFIG_HIGHMEM */
-
-	free_area_init(zones_size);
+	free_area_init_nodes(max_zone_pfns);
 }
 
 void __init mem_init(void)

^ permalink raw reply

* [PATCH 3/6] Have x86 use add_active_range() and free_area_init_nodes
From: Mel Gorman @ 2006-08-21 13:46 UTC (permalink / raw)
  To: akpm
  Cc: tony.luck, linux-mm, Mel Gorman, linux-kernel, bob.picco, ak,
	linuxppc-dev
In-Reply-To: <20060821134518.22179.46355.sendpatchset@skynet.skynet.ie>


Size zones and holes in an architecture independent manner for x86.


 Kconfig        |    8 +---
 kernel/setup.c |   24 ++++--------
 kernel/srat.c  |   97 +---------------------------------------------------
 mm/discontig.c |   69 +++++++++---------------------------
 4 files changed, 31 insertions(+), 167 deletions(-)

Signed-off-by: Mel Gorman <mel@csn.ul.ie>

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/i386/Kconfig linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/i386/Kconfig
--- linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/i386/Kconfig	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/i386/Kconfig	2006-08-21 10:14:43.000000000 +0100
@@ -602,12 +602,10 @@ config ARCH_SELECT_MEMORY_MODEL
 	def_bool y
 	depends on ARCH_SPARSEMEM_ENABLE
 
-source "mm/Kconfig"
+config ARCH_POPULATES_NODE_MAP
+	def_bool y
 
-config HAVE_ARCH_EARLY_PFN_TO_NID
-	bool
-	default y
-	depends on NUMA
+source "mm/Kconfig"
 
 config HIGHPTE
 	bool "Allocate 3rd-level pagetables from highmem"
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/i386/kernel/setup.c linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/i386/kernel/setup.c
--- linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/i386/kernel/setup.c	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/i386/kernel/setup.c	2006-08-21 10:14:43.000000000 +0100
@@ -1107,22 +1107,16 @@ static unsigned long __init setup_memory
 
 void __init zone_sizes_init(void)
 {
-	unsigned long zones_size[MAX_NR_ZONES] = { 0, };
-	unsigned int max_dma, low;
-
-	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-	low = max_low_pfn;
-
-	if (low < max_dma)
-		zones_size[ZONE_DMA] = low;
-	else {
-		zones_size[ZONE_DMA] = max_dma;
-		zones_size[ZONE_NORMAL] = low - max_dma;
-#ifdef CONFIG_HIGHMEM
-		zones_size[ZONE_HIGHMEM] = highend_pfn - low;
+	unsigned long max_zone_pfns[MAX_NR_ZONES] = {
+			virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
+			max_low_pfn,
+			highend_pfn};
+#ifndef CONFIG_HIGHMEM
+	unsigned long highend_pfn = max_low_pfn;
 #endif
-	}
-	free_area_init(zones_size);
+
+	add_active_range(0, 0, highend_pfn);
+	free_area_init_nodes(max_zone_pfns);
 }
 #else
 extern unsigned long __init setup_memory(void);
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/i386/kernel/srat.c linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/i386/kernel/srat.c
--- linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/i386/kernel/srat.c	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/i386/kernel/srat.c	2006-08-21 10:14:43.000000000 +0100
@@ -55,8 +55,6 @@ struct node_memory_chunk_s {
 static struct node_memory_chunk_s node_memory_chunk[MAXCHUNKS];
 
 static int num_memory_chunks;		/* total number of memory chunks */
-static int zholes_size_init;
-static unsigned long zholes_size[MAX_NUMNODES * MAX_NR_ZONES];
 static u8 __initdata apicid_to_pxm[MAX_APICID];
 
 extern void * boot_ioremap(unsigned long, unsigned long);
@@ -139,47 +137,6 @@ static void __init parse_memory_affinity
 		 "enabled and removable" : "enabled" ) );
 }
 
-/* Take a chunk of pages from page frame cstart to cend and count the number
- * of pages in each zone, returned via zones[].
- */
-static __init void chunk_to_zones(unsigned long cstart, unsigned long cend, 
-		unsigned long *zones)
-{
-	unsigned long max_dma;
-	extern unsigned long max_low_pfn;
-
-	int z;
-	unsigned long rend;
-
-	/* FIXME: MAX_DMA_ADDRESS and max_low_pfn are trying to provide
-	 * similarly scoped information and should be handled in a consistant
-	 * manner.
-	 */
-	max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-
-	/* Split the hole into the zones in which it falls.  Repeatedly
-	 * take the segment in which the remaining hole starts, round it
-	 * to the end of that zone.
-	 */
-	memset(zones, 0, MAX_NR_ZONES * sizeof(long));
-	while (cstart < cend) {
-		if (cstart < max_dma) {
-			z = ZONE_DMA;
-			rend = (cend < max_dma)? cend : max_dma;
-
-		} else if (cstart < max_low_pfn) {
-			z = ZONE_NORMAL;
-			rend = (cend < max_low_pfn)? cend : max_low_pfn;
-
-		} else {
-			z = ZONE_HIGHMEM;
-			rend = cend;
-		}
-		zones[z] += rend - cstart;
-		cstart = rend;
-	}
-}
-
 /*
  * The SRAT table always lists ascending addresses, so can always
  * assume that the first "start" address that you see is the real
@@ -224,7 +181,6 @@ static int __init acpi20_parse_srat(stru
 
 	memset(pxm_bitmap, 0, sizeof(pxm_bitmap));	/* init proximity domain bitmap */
 	memset(node_memory_chunk, 0, sizeof(node_memory_chunk));
-	memset(zholes_size, 0, sizeof(zholes_size));
 
 	num_memory_chunks = 0;
 	while (p < end) {
@@ -291,6 +247,7 @@ static int __init acpi20_parse_srat(stru
 		printk("chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
 		       j, chunk->nid, chunk->start_pfn, chunk->end_pfn);
 		node_read_chunk(chunk->nid, chunk);
+		add_active_range(chunk->nid, chunk->start_pfn, chunk->end_pfn);
 	}
  
 	for_each_online_node(nid) {
@@ -399,57 +356,7 @@ int __init get_memcfg_from_srat(void)
 		return acpi20_parse_srat((struct acpi_table_srat *)header);
 	}
 out_err:
+	remove_all_active_ranges();
 	printk("failed to get NUMA memory information from SRAT table\n");
 	return 0;
 }
-
-/* For each node run the memory list to determine whether there are
- * any memory holes.  For each hole determine which ZONE they fall
- * into.
- *
- * NOTE#1: this requires knowledge of the zone boundries and so
- * _cannot_ be performed before those are calculated in setup_memory.
- * 
- * NOTE#2: we rely on the fact that the memory chunks are ordered by
- * start pfn number during setup.
- */
-static void __init get_zholes_init(void)
-{
-	int nid;
-	int c;
-	int first;
-	unsigned long end = 0;
-
-	for_each_online_node(nid) {
-		first = 1;
-		for (c = 0; c < num_memory_chunks; c++){
-			if (node_memory_chunk[c].nid == nid) {
-				if (first) {
-					end = node_memory_chunk[c].end_pfn;
-					first = 0;
-
-				} else {
-					/* Record any gap between this chunk
-					 * and the previous chunk on this node
-					 * against the zones it spans.
-					 */
-					chunk_to_zones(end,
-						node_memory_chunk[c].start_pfn,
-						&zholes_size[nid * MAX_NR_ZONES]);
-				}
-			}
-		}
-	}
-}
-
-unsigned long * __init get_zholes_size(int nid)
-{
-	if (!zholes_size_init) {
-		zholes_size_init++;
-		get_zholes_init();
-	}
-	if (nid >= MAX_NUMNODES || !node_online(nid))
-		printk("%s: nid = %d is invalid/offline. num_online_nodes = %d",
-		       __FUNCTION__, nid, num_online_nodes());
-	return &zholes_size[nid * MAX_NR_ZONES];
-}
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/i386/mm/discontig.c linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/i386/mm/discontig.c
--- linux-2.6.18-rc4-mm2-102-powerpc_use_init_nodes/arch/i386/mm/discontig.c	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/i386/mm/discontig.c	2006-08-21 10:14:43.000000000 +0100
@@ -157,21 +157,6 @@ static void __init find_max_pfn_node(int
 		BUG();
 }
 
-/* Find the owning node for a pfn. */
-int early_pfn_to_nid(unsigned long pfn)
-{
-	int nid;
-
-	for_each_node(nid) {
-		if (node_end_pfn[nid] == 0)
-			break;
-		if (node_start_pfn[nid] <= pfn && node_end_pfn[nid] >= pfn)
-			return nid;
-	}
-
-	return 0;
-}
-
 /* 
  * Allocate memory for the pg_data_t for this node via a crude pre-bootmem
  * method.  For node zero take this from the bottom of memory, for
@@ -227,6 +212,8 @@ static unsigned long calculate_numa_rema
 	unsigned long pfn;
 
 	for_each_online_node(nid) {
+		unsigned old_end_pfn = node_end_pfn[nid];
+
 		/*
 		 * The acpi/srat node info can show hot-add memroy zones
 		 * where memory could be added but not currently present.
@@ -276,6 +263,7 @@ static unsigned long calculate_numa_rema
 
 		node_end_pfn[nid] -= size;
 		node_remap_start_pfn[nid] = node_end_pfn[nid];
+		shrink_active_range(nid, old_end_pfn, node_end_pfn[nid]);
 	}
 	printk("Reserving total of %ld pages for numa KVA remap\n",
 			reserve_pages);
@@ -369,45 +357,22 @@ void __init numa_kva_reserve(void)
 void __init zone_sizes_init(void)
 {
 	int nid;
-
-
-	for_each_online_node(nid) {
-		unsigned long zones_size[MAX_NR_ZONES] = {0, };
-		unsigned long *zholes_size;
-		unsigned int max_dma;
-
-		unsigned long low = max_low_pfn;
-		unsigned long start = node_start_pfn[nid];
-		unsigned long high = node_end_pfn[nid];
-
-		max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
-
-		if (node_has_online_mem(nid)){
-			if (start > low) {
-#ifdef CONFIG_HIGHMEM
-				BUG_ON(start > high);
-				zones_size[ZONE_HIGHMEM] = high - start;
-#endif
-			} else {
-				if (low < max_dma)
-					zones_size[ZONE_DMA] = low;
-				else {
-					BUG_ON(max_dma > low);
-					BUG_ON(low > high);
-					zones_size[ZONE_DMA] = max_dma;
-					zones_size[ZONE_NORMAL] = low - max_dma;
-#ifdef CONFIG_HIGHMEM
-					zones_size[ZONE_HIGHMEM] = high - low;
-#endif
-				}
-			}
+	unsigned long max_zone_pfns[MAX_NR_ZONES] = {
+		virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT,
+		max_low_pfn,
+		highend_pfn
+	};
+
+	/* If SRAT has not registered memory, register it now */
+	if (find_max_pfn_with_active_regions() == 0) {
+		for_each_online_node(nid) {
+			if (node_has_online_mem(nid))
+				add_active_range(nid, node_start_pfn[nid],
+							node_end_pfn[nid]);
 		}
-
-		zholes_size = get_zholes_size(nid);
-
-		free_area_init_node(nid, NODE_DATA(nid), zones_size, start,
-				zholes_size);
 	}
+
+	free_area_init_nodes(max_zone_pfns);
 	return;
 }
 

^ permalink raw reply

* [PATCH 4/6] Have x86_64 use add_active_range() and free_area_init_nodes
From: Mel Gorman @ 2006-08-21 13:46 UTC (permalink / raw)
  To: akpm
  Cc: tony.luck, linuxppc-dev, Mel Gorman, ak, bob.picco, linux-kernel,
	linux-mm
In-Reply-To: <20060821134518.22179.46355.sendpatchset@skynet.skynet.ie>


Size zones and holes in an architecture independent manner for x86_64.


 arch/x86_64/Kconfig         |    3 
 arch/x86_64/kernel/e820.c   |  125 ++++++++++++++-------------------------
 arch/x86_64/kernel/setup.c  |    7 +-
 arch/x86_64/mm/init.c       |   65 +-------------------
 arch/x86_64/mm/k8topology.c |    3 
 arch/x86_64/mm/numa.c       |   21 +++---
 arch/x86_64/mm/srat.c       |   11 ++-
 include/asm-x86_64/e820.h   |    5 -
 include/asm-x86_64/proto.h  |    2 
 9 files changed, 84 insertions(+), 158 deletions(-)

Signed-off-by: Mel Gorman <mel@csn.ul.ie>

diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/Kconfig linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/Kconfig
--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/Kconfig	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/Kconfig	2006-08-21 10:15:58.000000000 +0100
@@ -85,6 +85,9 @@ config ARCH_MAY_HAVE_PC_FDC
 	bool
 	default y
 
+config ARCH_POPULATES_NODE_MAP
+	def_bool y
+
 config DMI
 	bool
 	default y
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/kernel/e820.c linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/kernel/e820.c
--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/kernel/e820.c	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/kernel/e820.c	2006-08-21 10:15:58.000000000 +0100
@@ -162,59 +162,14 @@ unsigned long __init find_e820_area(unsi
 	return -1UL;		
 } 
 
-/* 
- * Free bootmem based on the e820 table for a node.
- */
-void __init e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end)
-{
-	int i;
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i]; 
-		unsigned long last, addr;
-
-		if (ei->type != E820_RAM || 
-		    ei->addr+ei->size <= start || 
-		    ei->addr >= end)
-			continue;
-
-		addr = round_up(ei->addr, PAGE_SIZE);
-		if (addr < start) 
-			addr = start;
-
-		last = round_down(ei->addr + ei->size, PAGE_SIZE); 
-		if (last >= end)
-			last = end; 
-
-		if (last > addr && last-addr >= PAGE_SIZE)
-			free_bootmem_node(pgdat, addr, last-addr);
-	}
-}
-
 /*
  * Find the highest page frame number we have available
  */
 unsigned long __init e820_end_of_ram(void)
 {
-	int i;
 	unsigned long end_pfn = 0;
+	end_pfn = find_max_pfn_with_active_regions();
 	
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i]; 
-		unsigned long start, end;
-
-		start = round_up(ei->addr, PAGE_SIZE); 
-		end = round_down(ei->addr + ei->size, PAGE_SIZE); 
-		if (start >= end)
-			continue;
-		if (ei->type == E820_RAM) { 
-		if (end > end_pfn<<PAGE_SHIFT)
-			end_pfn = end>>PAGE_SHIFT;
-		} else { 
-			if (end > end_pfn_map<<PAGE_SHIFT) 
-				end_pfn_map = end>>PAGE_SHIFT;
-		} 
-	}
-
 	if (end_pfn > end_pfn_map) 
 		end_pfn_map = end_pfn;
 	if (end_pfn_map > MAXMEM>>PAGE_SHIFT)
@@ -224,43 +179,10 @@ unsigned long __init e820_end_of_ram(voi
 	if (end_pfn > end_pfn_map) 
 		end_pfn = end_pfn_map; 
 
+	printk("end_pfn_map = %lu\n", end_pfn_map);
 	return end_pfn;	
 }
 
-/* 
- * Compute how much memory is missing in a range.
- * Unlike the other functions in this file the arguments are in page numbers.
- */
-unsigned long __init
-e820_hole_size(unsigned long start_pfn, unsigned long end_pfn)
-{
-	unsigned long ram = 0;
-	unsigned long start = start_pfn << PAGE_SHIFT;
-	unsigned long end = end_pfn << PAGE_SHIFT;
-	int i;
-	for (i = 0; i < e820.nr_map; i++) {
-		struct e820entry *ei = &e820.map[i];
-		unsigned long last, addr;
-
-		if (ei->type != E820_RAM ||
-		    ei->addr+ei->size <= start ||
-		    ei->addr >= end)
-			continue;
-
-		addr = round_up(ei->addr, PAGE_SIZE);
-		if (addr < start)
-			addr = start;
-
-		last = round_down(ei->addr + ei->size, PAGE_SIZE);
-		if (last >= end)
-			last = end;
-
-		if (last > addr)
-			ram += last - addr;
-	}
-	return ((end - start) - ram) >> PAGE_SHIFT;
-}
-
 /*
  * Mark e820 reserved areas as busy for the resource manager.
  */
@@ -342,6 +264,49 @@ void __init e820_mark_nosave_regions(voi
 	}
 }
 
+/* Walk the e820 map and register active regions within a node */
+void __init
+e820_register_active_regions(int nid, unsigned long start_pfn,
+							unsigned long end_pfn)
+{
+	int i;
+	unsigned long ei_startpfn, ei_endpfn;
+	for (i = 0; i < e820.nr_map; i++) {
+		struct e820entry *ei = &e820.map[i];
+		ei_startpfn = round_up(ei->addr, PAGE_SIZE) >> PAGE_SHIFT;
+		ei_endpfn = round_down(ei->addr + ei->size, PAGE_SIZE)
+								>> PAGE_SHIFT;
+
+		/* Skip map entries smaller than a page */
+		if (ei_startpfn > ei_endpfn)
+			continue;
+
+		/* Check if end_pfn_map should be updated */
+		if (ei->type != E820_RAM && ei_endpfn > end_pfn_map)
+			end_pfn_map = ei_endpfn;
+
+		/* Skip if map is outside the node */
+		if (ei->type != E820_RAM ||
+				ei_endpfn <= start_pfn ||
+				ei_startpfn >= end_pfn)
+			continue;
+
+		/* Check for overlaps */
+		if (ei_startpfn < start_pfn)
+			ei_startpfn = start_pfn;
+		if (ei_endpfn > end_pfn)
+			ei_endpfn = end_pfn;
+
+		/* Obey end_user_pfn to save on memmap */
+		if (ei_startpfn >= end_user_pfn)
+			continue;
+		if (ei_endpfn > end_user_pfn)
+			ei_endpfn = end_user_pfn;
+
+		add_active_range(nid, ei_startpfn, ei_endpfn);
+	}
+}
+
 /* 
  * Add a memory region to the kernel e820 map.
  */ 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/kernel/setup.c linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/kernel/setup.c
--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/kernel/setup.c	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/kernel/setup.c	2006-08-21 10:15:58.000000000 +0100
@@ -292,7 +292,8 @@ contig_initmem_init(unsigned long start_
 	if (bootmap == -1L)
 		panic("Cannot find bootmem map of size %ld\n",bootmap_size);
 	bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn);
-	e820_bootmem_free(NODE_DATA(0), 0, end_pfn << PAGE_SHIFT);
+	e820_register_active_regions(0, start_pfn, end_pfn);
+	free_bootmem_with_active_regions(0, end_pfn);
 	reserve_bootmem(bootmap, bootmap_size);
 } 
 #endif
@@ -386,6 +387,7 @@ void __init setup_arch(char **cmdline_p)
 
 	finish_e820_parsing();
 
+	e820_register_active_regions(0, 0, -1UL);
 	/*
 	 * partially used pages are not usable - thus
 	 * we are rounding upwards:
@@ -416,6 +418,9 @@ void __init setup_arch(char **cmdline_p)
 	max_pfn = end_pfn;
 	high_memory = (void *)__va(end_pfn * PAGE_SIZE - 1) + 1;
 
+	/* Remove active ranges so rediscovery with NUMA-awareness happens */
+	remove_all_active_ranges();
+
 #ifdef CONFIG_ACPI_NUMA
 	/*
 	 * Parse SRAT to discover nodes.
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/init.c linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/init.c
--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/init.c	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/init.c	2006-08-21 10:15:58.000000000 +0100
@@ -404,69 +404,15 @@ void __cpuinit zap_low_mappings(int cpu)
 	__flush_tlb_all();
 }
 
-/* Compute zone sizes for the DMA and DMA32 zones in a node. */
-__init void
-size_zones(unsigned long *z, unsigned long *h,
-	   unsigned long start_pfn, unsigned long end_pfn)
-{
- 	int i;
- 	unsigned long w;
-
- 	for (i = 0; i < MAX_NR_ZONES; i++)
- 		z[i] = 0;
-
- 	if (start_pfn < MAX_DMA_PFN)
- 		z[ZONE_DMA] = MAX_DMA_PFN - start_pfn;
- 	if (start_pfn < MAX_DMA32_PFN) {
- 		unsigned long dma32_pfn = MAX_DMA32_PFN;
- 		if (dma32_pfn > end_pfn)
- 			dma32_pfn = end_pfn;
- 		z[ZONE_DMA32] = dma32_pfn - start_pfn;
- 	}
- 	z[ZONE_NORMAL] = end_pfn - start_pfn;
-
- 	/* Remove lower zones from higher ones. */
- 	w = 0;
- 	for (i = 0; i < MAX_NR_ZONES; i++) {
- 		if (z[i])
- 			z[i] -= w;
- 	        w += z[i];
-	}
-
-	/* Compute holes */
-	w = start_pfn;
-	for (i = 0; i < MAX_NR_ZONES; i++) {
-		unsigned long s = w;
-		w += z[i];
-		h[i] = e820_hole_size(s, w);
-	}
-
-	/* Add the space pace needed for mem_map to the holes too. */
-	for (i = 0; i < MAX_NR_ZONES; i++)
-		h[i] += (z[i] * sizeof(struct page)) / PAGE_SIZE;
-
-	/* The 16MB DMA zone has the kernel and other misc mappings.
- 	   Account them too */
-	if (h[ZONE_DMA]) {
-		h[ZONE_DMA] += dma_reserve;
-		if (h[ZONE_DMA] >= z[ZONE_DMA]) {
-			printk(KERN_WARNING
-				"Kernel too large and filling up ZONE_DMA?\n");
-			h[ZONE_DMA] = z[ZONE_DMA];
-		}
-	}
-}
-
 #ifndef CONFIG_NUMA
 void __init paging_init(void)
 {
-	unsigned long zones[MAX_NR_ZONES], holes[MAX_NR_ZONES];
-
+	unsigned long max_zone_pfns[MAX_NR_ZONES] = {MAX_DMA_PFN,
+							MAX_DMA32_PFN,
+							end_pfn};
 	memory_present(0, 0, end_pfn);
 	sparse_init();
-	size_zones(zones, holes, 0, end_pfn);
-	free_area_init_node(0, NODE_DATA(0), zones,
-			    __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes);
+	free_area_init_nodes(max_zone_pfns);
 }
 #endif
 
@@ -613,7 +559,8 @@ void __init mem_init(void)
 #else
 	totalram_pages = free_all_bootmem();
 #endif
-	reservedpages = end_pfn - totalram_pages - e820_hole_size(0, end_pfn);
+	reservedpages = end_pfn - totalram_pages -
+					absent_pages_in_range(0, end_pfn);
 
 	after_bootmem = 1;
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/k8topology.c linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/k8topology.c
--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/k8topology.c	2006-08-06 19:20:11.000000000 +0100
+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/k8topology.c	2006-08-21 10:15:58.000000000 +0100
@@ -146,6 +146,9 @@ int __init k8_scan_nodes(unsigned long s
 		
 		nodes[nodeid].start = base; 
 		nodes[nodeid].end = limit;
+		e820_register_active_regions(nodeid,
+				nodes[nodeid].start >> PAGE_SHIFT,
+				nodes[nodeid].end >> PAGE_SHIFT);
 
 		prevbase = base;
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/numa.c linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/numa.c
--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/numa.c	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/numa.c	2006-08-21 10:15:58.000000000 +0100
@@ -161,7 +161,7 @@ void __init setup_node_bootmem(int nodei
 					 bootmap_start >> PAGE_SHIFT, 
 					 start_pfn, end_pfn); 
 
-	e820_bootmem_free(NODE_DATA(nodeid), start, end);
+	free_bootmem_with_active_regions(nodeid, end);
 
 	reserve_bootmem_node(NODE_DATA(nodeid), nodedata_phys, pgdat_size); 
 	reserve_bootmem_node(NODE_DATA(nodeid), bootmap_start, bootmap_pages<<PAGE_SHIFT);
@@ -175,13 +175,11 @@ void __init setup_node_bootmem(int nodei
 void __init setup_node_zones(int nodeid)
 { 
 	unsigned long start_pfn, end_pfn, memmapsize, limit;
-	unsigned long zones[MAX_NR_ZONES];
-	unsigned long holes[MAX_NR_ZONES];
 
  	start_pfn = node_start_pfn(nodeid);
  	end_pfn = node_end_pfn(nodeid);
 
-	Dprintk(KERN_INFO "Setting up node %d %lx-%lx\n",
+	Dprintk(KERN_INFO "Setting up memmap for node %d %lx-%lx\n",
 		nodeid, start_pfn, end_pfn);
 
 	/* Try to allocate mem_map at end to not fill up precious <4GB
@@ -195,10 +193,6 @@ void __init setup_node_zones(int nodeid)
 				round_down(limit - memmapsize, PAGE_SIZE), 
 				limit);
 #endif
-
-	size_zones(zones, holes, start_pfn, end_pfn);
-	free_area_init_node(nodeid, NODE_DATA(nodeid), zones,
-			    start_pfn, holes);
 } 
 
 void __init numa_init_array(void)
@@ -259,8 +253,11 @@ static int __init numa_emulation(unsigne
  		printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n");
  		return -1;
  	}
- 	for_each_online_node(i)
+ 	for_each_online_node(i) {
+		e820_register_active_regions(i, nodes[i].start >> PAGE_SHIFT,
+						nodes[i].end >> PAGE_SHIFT);
  		setup_node_bootmem(i, nodes[i].start, nodes[i].end);
+	}
  	numa_init_array();
  	return 0;
 }
@@ -299,6 +296,7 @@ void __init numa_initmem_init(unsigned l
 	for (i = 0; i < NR_CPUS; i++)
 		numa_set_node(i, 0);
 	node_to_cpumask[0] = cpumask_of_cpu(0);
+	e820_register_active_regions(0, start_pfn, end_pfn);
 	setup_node_bootmem(0, start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
 }
 
@@ -340,12 +338,17 @@ static void __init arch_sparse_init(void
 void __init paging_init(void)
 { 
 	int i;
+	unsigned long max_zone_pfns[MAX_NR_ZONES] = { MAX_DMA_PFN,
+		MAX_DMA32_PFN,
+		end_pfn};
 
 	arch_sparse_init();
 
 	for_each_online_node(i) {
 		setup_node_zones(i); 
 	}
+
+	free_area_init_nodes(max_zone_pfns);
 } 
 
 static __init int numa_setup(char *opt)
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/srat.c linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/srat.c
--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/arch/x86_64/mm/srat.c	2006-08-21 09:23:50.000000000 +0100
+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/arch/x86_64/mm/srat.c	2006-08-21 10:15:58.000000000 +0100
@@ -84,6 +84,7 @@ static __init void bad_srat(void)
 		apicid_to_node[i] = NUMA_NO_NODE;
 	for (i = 0; i < MAX_NUMNODES; i++)
 		nodes_add[i].start = nodes[i].end = 0;
+	remove_all_active_ranges();
 }
 
 static __init inline int srat_disabled(void)
@@ -166,7 +167,7 @@ static int hotadd_enough_memory(struct b
 
 	if (mem < 0)
 		return 0;
-	allowed = (end_pfn - e820_hole_size(0, end_pfn)) * PAGE_SIZE;
+	allowed = (end_pfn - absent_pages_in_range(0, end_pfn)) * PAGE_SIZE;
 	allowed = (allowed / 100) * hotadd_percent;
 	if (allocated + mem > allowed) {
 		unsigned long range;
@@ -238,7 +239,7 @@ static int reserve_hotadd(int node, unsi
 	}
 
 	/* This check might be a bit too strict, but I'm keeping it for now. */
-	if (e820_hole_size(s_pfn, e_pfn) != e_pfn - s_pfn) {
+	if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) {
 		printk(KERN_ERR "SRAT: Hotplug area has existing memory\n");
 		return -1;
 	}
@@ -329,6 +330,8 @@ acpi_numa_memory_affinity_init(struct ac
 
 	printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
 	       nd->start, nd->end);
+	e820_register_active_regions(node, nd->start >> PAGE_SHIFT,
+						nd->end >> PAGE_SHIFT);
 
  	if (ma->flags.hot_pluggable && !reserve_hotadd(node, start, end) < 0) {
 		/* Ignore hotadd region. Undo damage */
@@ -351,12 +354,12 @@ static int nodes_cover_memory(void)
 		unsigned long s = nodes[i].start >> PAGE_SHIFT;
 		unsigned long e = nodes[i].end >> PAGE_SHIFT;
 		pxmram += e - s;
-		pxmram -= e820_hole_size(s, e);
+		pxmram -= absent_pages_in_range(s, e);
 		if ((long)pxmram < 0)
 			pxmram = 0;
 	}
 
-	e820ram = end_pfn - e820_hole_size(0, end_pfn);
+	e820ram = end_pfn - absent_pages_in_range(0, end_pfn);
 	/* We seem to lose 3 pages somewhere. Allow a bit of slack. */
 	if ((long)(e820ram - pxmram) >= 1*1024*1024) {
 		printk(KERN_ERR
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/include/asm-x86_64/e820.h linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/include/asm-x86_64/e820.h
--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/include/asm-x86_64/e820.h	2006-08-21 09:23:52.000000000 +0100
+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/include/asm-x86_64/e820.h	2006-08-21 10:15:58.000000000 +0100
@@ -51,10 +51,9 @@ extern void e820_print_map(char *who);
 extern int e820_any_mapped(unsigned long start, unsigned long end, unsigned type);
 extern int e820_all_mapped(unsigned long start, unsigned long end, unsigned type);
 
-extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end);
 extern void e820_setup_gap(void);
-extern unsigned long e820_hole_size(unsigned long start_pfn,
-				    unsigned long end_pfn);
+extern void e820_register_active_regions(int nid,
+				unsigned long start_pfn, unsigned long end_pfn);
 
 extern void finish_e820_parsing(void);
 
diff -rup -X /usr/src/patchset-0.6/bin//dontdiff linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/include/asm-x86_64/proto.h linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/include/asm-x86_64/proto.h
--- linux-2.6.18-rc4-mm2-103-x86_use_init_nodes/include/asm-x86_64/proto.h	2006-08-21 09:23:52.000000000 +0100
+++ linux-2.6.18-rc4-mm2-104-x86_64_use_init_nodes/include/asm-x86_64/proto.h	2006-08-21 10:15:58.000000000 +0100
@@ -24,8 +24,6 @@ extern void mtrr_bp_init(void);
 #define mtrr_bp_init() do {} while (0)
 #endif
 extern void init_memory_mapping(unsigned long start, unsigned long end);
-extern void size_zones(unsigned long *z, unsigned long *h,
-			unsigned long start_pfn, unsigned long end_pfn);
 
 extern void system_call(void); 
 extern int kernel_syscall(void);

^ permalink raw reply

* [PATCH 0/6] Sizing zones and holes in an architecture independent manner V9
From: Mel Gorman @ 2006-08-21 13:45 UTC (permalink / raw)
  To: akpm
  Cc: tony.luck, linuxppc-dev, Mel Gorman, ak, bob.picco, linux-kernel,
	linux-mm

This is V9 of the patchset to size zones and memory holes in an
architecture-independent manner. It booted successfully on 5 different
machines (arches were x86, x86_64, ppc64 and ia64) in a number of different
configurations and successfully built a kernel. If it fails on any machine,
booting with loglevel=8 and the console log should tell me what went wrong.

Changelog since V8
o Rebase to 2.6.17-rc4-mm1
o Make dma_reserve static
o Use enumerated zone numbers

Changelog since V7
o Rebase to 2.6.17-mm6
o Account for mem_map as a memory hole
o Adjust mem_map when arch independent zone-sizing is used and PFN 0 is in
  a memory hole not accounted for by ARCH_PFN_OFFSET

Changelog since V6
o MAX_ACTIVE_REGIONS is really maximum active regions, not MAX_ACTIVE_REGIONS-1
o MAX_ACTIVE_REGIONS is 256 unless the architecture specifically asks for
  a different number or MAX_NUMNODES is >= 32
o nr_nodemap_entries tracks the number of entries rather than terminating with
  end_pfn == 0
o Add number of documentation-related comments. Functions exposed by headers
  may potentially be picked up by kerneldoc
o Changed misleading zone_present_pages_in_node() name to
  zone_spanned_pages_in_node()
o Be a bit more verbose to help debugging when things go wrong.
o On x86_64, end_pfn_map now gets updated properly or ACPI tables get "lost"
o Signoffs added to patches 1 and 5 by Bob Picco related to contributions,
  fixes and reviews

Changelog since V5
o Add a missing #include to mm/mem_init.c
o Drop the verbose debugging part of the set
o Report active range registration when loglevel is set for KERN_DEBUG

Changelog since V4
o Rebase to 2.6.17-rc3-mm1
o Calculate holes on x86 with SRAT correctly

Changelog since V3
o Rebase to 2.6.17-rc2
o Allow the active regions to be cleared. Needed by x86_64 when it decides
  the SRAT table is bad half way through the registering of active regions
o Fix for flatmem x86_64 machines booting

Changelog since V2
o Fix a bug where holes in lower zones get double counted
o Catch the case where a new range is registered that is within an range
o Catch the case where a zone boundary is within a hole
o Use the EFI map for registering ranges on x86_64+numa
o On IA64+NUMA, add the active ranges before rounding for granules
o On x86_64, remove e820_hole_size and e820_bootmem_free and use
  arch-independent equivalents
o On x86_64, remove the map walk in e820_end_of_ram()
o Rename memory_present_with_active_regions, name ambiguous
o Add absent_pages_in_range() for arches to call

Changelog since V1
o Correctly convert virtual and physical addresses to PFNs on ia64
o Correctly convert physical addresses to PFN on older ppc 
o When add_active_range() is called with overlapping pfn ranges, merge them
o When a zone boundary occurs within a memory hole, account correctly
o Minor whitespace damage cleanup
o Debugging patch temporarily included

At a basic level, architectures define structures to record where active
ranges of page frames are located. Once located, the code to calculate
zone sizes and holes in each architecture is very similar.  Some of this
zone and hole sizing code is difficult to read for no good reason. This
set of patches eliminates the similar-looking architecture-specific code.

The patches introduce a mechanism where architectures register where the
active ranges of page frames are with add_active_range(). When all areas
have been discovered, free_area_init_nodes() is called to initialise
the pgdat and zones. The zone sizes and holes are then calculated in an
architecture independent manner.

Patch 1 introduces the mechanism for registering and initialising PFN ranges
Patch 2 changes ppc to use the mechanism - 139 arch-specific LOC removed
Patch 3 changes x86 to use the mechanism - 136 arch-specific LOC removed
Patch 4 changes x86_64 to use the mechanism - 74 arch-specific LOC removed
Patch 5 changes ia64 to use the mechanism - 52 arch-specific LOC removed
Patch 6 accounts for mem_map as a memory hole as the pages are not reclaimable.
	It adjusts the watermarks slightly

Tony Luck has successfully tested for ia64 on Itanium with tiger_defconfig,
gensparse_defconfig and defconfig. Bob Picco has also tested and debugged
on IA64. Jack Steiner successfully boot tested on a mammoth SGI IA64-based
machine. These were on patches against 2.6.17-rc1 and release 3 of these
patches but there have been no ia64-changes since release 3.

There are differences in the zone sizes for x86_64 as the arch-specific code
for x86_64 accounts the kernel image and the starting mem_maps as memory
holes but the architecture-independent code accounts the memory as present.

The big benefit of this set of patches is a sizable reduction of
architecture-specific code, some of which is very hairy. There should be a
greater reduction when other architectures use the same mechanisms for
zone and hole sizing but I lack the hardware to test on.

Additional credit;
	Dave Hansen for the initial suggestion and comments on early patches
	Andy Whitcroft for reviewing early versions and catching numerous
		errors
	Tony Luck for testing and debugging on IA64
	Bob Picco for fixing bugs related to pfn registration, reviewing a
		number of patch revisions, providing a number of suggestions
		on future direction and testing heavily
	Jack Steiner and Robin Holt for testing on IA64 and clarifying
		issues related to memory holes
	Yasunori for testing on IA64
	Andi Kleen for reviewing and feeding back about x86_64
	Christian Kujau for providing valuable information related to ACPI
		problems on x86_64 and testing potential fixes
-- 
-- 
Mel Gorman
Part-time Phd Student                          Linux Technology Center
University of Limerick                         IBM Dublin Software Lab

^ permalink raw reply

* PPC beginner questions
From: Wade Maxfield @ 2006-08-21 13:51 UTC (permalink / raw)
  To: ppc

[-- Attachment #1: Type: text/plain, Size: 778 bytes --]

  I'm new to the PPC and I have a few questions.  I have written a  driver
in the past for the X86 family, using i/o ports, but it was kernel 2.0 and
i/o ports are not mmu handled.
  I've been looking through the archive and I am slowly growing more
confused.

  We are using Xilinx with PPC built in.

   The PPC has a memory management unit.  All of the IP we've added is
mapped to physical addresses.

   1. Can I access the memory the peripherasl are mapped to directly within
the driver without going through functions?
       if NOT, then Do I use
          1. ioremap(),
          2. request_mem_region(),
          3. request_region()
          4. something else?

   2.  Are there any gotcha's with the ppc 405 that Xilinx uses that I
should know about?


thanks,
wade

[-- Attachment #2: Type: text/html, Size: 1101 bytes --]

^ permalink raw reply

* Using a file as blockdevice for vscsi host
From: Ingvar Hagelund @ 2006-08-21 13:30 UTC (permalink / raw)
  To: linuxppc-dev

I think someone, sometime told me something about using a file as vscsi
device in a (Linux) vio server. Is this possible?

I tried this, but it doesn't seem to work:

vios# dd if=/dev/zero of=/path/to/sysvol bs=1M count=9000
viod# cd sys/bus/vio/devices/30000020/bus0
vios# echo 2 > num_targets
vios# cd target1
vios# echo /path/to/sysvol > device
vios# echo b > type
vios# echo 1 > active
vios# echo $?
1
vios# cat active
0

Ingvar


-- 
Blogs are the new usenet
(Mike of UserFriendly.org)

^ permalink raw reply

* Re: [2.6.19 PATCH 1/7] ehea: interface to network stack
From: Jörn Engel @ 2006-08-21 13:18 UTC (permalink / raw)
  To: Jan-Bernd Themann
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
	Thomas Klein, linux-ppc, Christoph Raisch, Marcus Eder,
	Alexey Dobriyan
In-Reply-To: <200608211423.54250.ossthema@de.ibm.com>

On Mon, 21 August 2006 14:23:53 +0200, Jan-Bernd Themann wrote:
> 
> Is it valid (common in the kernel environment) to treat NULL as 0 after a memset
> and thus to forget about initialization?

Yes.  According to C99, "An implementation might conveivably have
codes for floating zero and/or null pointer other than all bits zero."
But as long as you don't use floating point (you shouldn't) and don't
redefine NULL to something other than (void*)0, this is rather
"inconceivable" for the kernel.

Jörn

-- 
Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it.
-- Brian W. Kernighan

^ permalink raw reply

* Re: [openib-general] [PATCH 08/13] IB/ehca: qp
From: Hal Rosenstock @ 2006-08-21 12:44 UTC (permalink / raw)
  To: Roland Dreier
  Cc: linux-kernel, openib-general, linuxppc-dev, Christoph Raisch,
	HNGUYEN, MEDER
In-Reply-To: <20068171311.7Z4EtLP0ZYtya78R@cisco.com>

On Thu, 2006-08-17 at 16:11, Roland Dreier wrote:

[snip...]

> diff --git a/drivers/infiniband/hw/ehca/ehca_sqp.c b/drivers/infiniband/hw/ehca/ehca_sqp.c
> new file mode 100644
> index 0000000..d2c5552
> --- /dev/null
> +++ b/drivers/infiniband/hw/ehca/ehca_sqp.c
> @@ -0,0 +1,123 @@
> +/*
> + *  IBM eServer eHCA Infiniband device driver for Linux on POWER
> + *
> + *  SQP functions
> + *
> + *  Authors: Khadija Souissi <souissi@de.ibm.com>
> + *           Heiko J Schick <schickhj@de.ibm.com>

[snip...]

> +
> +extern int ehca_create_aqp1(struct ehca_shca *shca, struct ehca_sport *sport);
> +extern int ehca_destroy_aqp1(struct ehca_sport *sport);
> +
> +extern int ehca_port_act_time;
> +
> +/**
> + * ehca_define_sqp - Defines special queue pair 1 (GSI QP). When special queue
> + * pair is created successfully, the corresponding port gets active.
> + *
> + * Define Special Queue pair 0 (SMI QP) is still not supported.
> + *
> + * @qp_init_attr: Queue pair init attributes with port and queue pair type
> + */
> +
> +u64 ehca_define_sqp(struct ehca_shca *shca,
> +		    struct ehca_qp *ehca_qp,
> +		    struct ib_qp_init_attr *qp_init_attr)
> +{
> +
> +	u32 pma_qp_nr = 0;
> +	u32 bma_qp_nr = 0;
> +	u64 ret = H_SUCCESS;
> +	u8 port = qp_init_attr->port_num;
> +	int counter = 0;
> +
> +	EDEB_EN(7, "port=%x qp_type=%x",
> +		port, qp_init_attr->qp_type);
> +
> +	shca->sport[port - 1].port_state = IB_PORT_DOWN;
> +
> +	switch (qp_init_attr->qp_type) {
> +	case IB_QPT_SMI:
> +		/* function not supported yet */
> +		break;
> +	case IB_QPT_GSI:
> +		ret = hipz_h_define_aqp1(shca->ipz_hca_handle,
> +					 ehca_qp->ipz_qp_handle,
> +					 ehca_qp->galpas.kernel,
> +					 (u32) qp_init_attr->port_num,
> +					 &pma_qp_nr, &bma_qp_nr);
> +
> +		if (ret != H_SUCCESS) {
> +			EDEB_ERR(4, "Can't define AQP1 for port %x. rc=%lx",
> +				    port, ret);
> +			goto ehca_define_aqp1;
> +		}
> +		break;
> +	default:
> +		ret = H_PARAMETER;
> +		goto ehca_define_aqp1;
> +	}
> +
> +	while ((shca->sport[port - 1].port_state != IB_PORT_ACTIVE) &&
> +	       (counter < ehca_port_act_time)) {
> +		EDEB(6, "... wait until port %x is active",
> +			port);
> +		msleep_interruptible(1000);
> +		counter++;
> +	}
> +
> +	if (counter == ehca_port_act_time) {
> +		EDEB_ERR(4, "Port %x is not active.", port);
> +		ret = H_HARDWARE;
> +	}
> +
> +ehca_define_aqp1:
> +	EDEB_EX(7, "ret=%lx", ret);
> +
> +	return ret;
> +}

I, for one, was hoping that the timer based transition to active for QP1
would have been resolved before being submitted. Any idea on the plan to
resolve this ?

-- Hal

^ permalink raw reply

* Re: [2.6.19 PATCH 1/7] ehea: interface to network stack
From: Jan-Bernd Themann @ 2006-08-21 12:23 UTC (permalink / raw)
  To: Alexey Dobriyan
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
	Thomas Klein, linux-ppc, Christoph Raisch, Marcus Eder
In-Reply-To: <20060818144429.GF5201@martell.zuzino.mipt.ru>

Hi

On Friday 18 August 2006 16:44, Alexey Dobriyan wrote:
> > +static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
> > +			      struct port_res_cfg *pr_cfg, int queue_token)
> > +{
> > +	int ret = -EINVAL;
> > +	int max_rq_entries = 0;
> > +	enum ehea_eq_type eq_type = EHEA_EQ;
> > +	struct ehea_qp_init_attr *init_attr = NULL;
> > +	struct ehea_adapter *adapter = port->adapter;
> > +
> > +	memset(pr, 0, sizeof(struct ehea_port_res));
> > +
> > +	pr->skb_arr_rq3 = NULL;
> > +	pr->skb_arr_rq2 = NULL;
> > +	pr->skb_arr_rq1 = NULL;
> > +	pr->skb_arr_sq = NULL;
> > +	pr->qp = NULL;
> > +	pr->send_cq = NULL;
> > +	pr->recv_cq = NULL;
> > +	pr->send_eq = NULL;
> > +	pr->recv_eq = NULL;
> 
> After memset unneeded. ;-)
> 

Is it valid (common in the kernel environment) to treat NULL as 0 after a memset
and thus to forget about initialization?

Thanks,
Jan-Bernd

^ permalink raw reply

* Re: [openib-general] [PATCH 08/13] IB/ehca: qp
From: Christoph Raisch @ 2006-08-21 12:59 UTC (permalink / raw)
  To: Hal Rosenstock
  Cc: linux-kernel, openib-general, linuxppc-dev, Hoang-Nam Nguyen,
	Marcus Eder
In-Reply-To: <1156164265.9855.196633.camel@hal.voltaire.com>


>
> I, for one, was hoping that the timer based transition to active for QP1
> would have been resolved before being submitted. Any idea on the plan to
> resolve this ?
>
> -- Hal
>
>
>
We're testing it. As I mentioned before, this requires a change in the
system firmware. I personally don't think this will show up in firmware in
time for 2.6.19 merge window.
So unfortunately we still need that loop.

Regards . . . Christoph R

^ permalink raw reply

* Re: [PATCH 2/6] ehea: pHYP interface
From: Jan-Bernd Themann @ 2006-08-21 12:04 UTC (permalink / raw)
  To: Nathan Lynch
  Cc: Thomas Klein, netdev, linux-kernel, linux-ppc, Christoph Raisch,
	Marcus Eder
In-Reply-To: <20060811211915.GL3233@localdomain>

Hi Nathan,

sorry for the delayed answer.

On Friday 11 August 2006 23:19, Nathan Lynch wrote:
> > +static inline long ehea_hcall_9arg_9ret(unsigned long opcode,
> > +					unsigned long arg1,
> > +					unsigned long arg2,
> > +					unsigned long arg3,
> > +					unsigned long arg4,
> > +					unsigned long arg5,
> > +					unsigned long arg6,
> > +					unsigned long arg7,
> > +					unsigned long arg8,
> > +					unsigned long arg9,
> > +					unsigned long *out1,
> > +					unsigned long *out2,
> > +					unsigned long *out3,
> > +					unsigned long *out4,
> > +					unsigned long *out5,
> > +					unsigned long *out6,
> > +					unsigned long *out7,
> > +					unsigned long *out8,
> > +					unsigned long *out9)
> > +{
> > +	long hret = H_SUCCESS;
> > +	int i, sleep_msecs;
> > +
> > +	EDEB_EN(7, "opcode=%lx arg1=%lx arg2=%lx arg3=%lx arg4=%lx "
> > +		"arg5=%lx arg6=%lx arg7=%lx arg8=%lx arg9=%lx",
> > +		opcode, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
> > +		arg8, arg9);
> > +
> > +
> > +	for (i = 0; i < 5; i++) {
> > +		hret = plpar_hcall_9arg_9ret(opcode,
> > +					    arg1, arg2, arg3, arg4,
> > +					    arg5, arg6, arg7, arg8,
> > +					    arg9,
> > +					    out1, out2, out3, out4,
> > +					    out5, out6, out7, out8,
> > +					    out9);
> > +
> > +		if (H_IS_LONG_BUSY(hret)) {
> > +			sleep_msecs = get_longbusy_msecs(hret);
> > +			msleep_interruptible(sleep_msecs);
> > +			continue;
> > +		}
> 
> Looping five times before giving up seems arbitrary and failure-prone
> on busy systems.

This is the number we came up with after having talked to the H_CALL
developers

> 
> Is msleep_interruptible (as opposed to msleep) really appropriate?
> 
> Hope all the callers of this function are in non-atomic context (but I
> wasn't able to find any callers?).
That's our intention.
We did not find a place where it is used in an atomic context. 

> 
> And this function is too big to be inline.
> 
> 

Ok, function is no longer inline

^ permalink raw reply

* [PATCH] update pmac32_defconfig
From: Olaf Hering @ 2006-08-21 12:43 UTC (permalink / raw)
  To: linuxppc-dev, Paul Mackeras


disable unused winbond IDE driver
disable usbmon, seccomp and rmmod -f
enable windfarm, pppoe, pegasus, Euro nls and magic sysrq.
optimize for size

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 arch/powerpc/configs/pmac32_defconfig |   51 ++++++++++++++++------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

Index: linux-2.6.18-rc4/arch/powerpc/configs/pmac32_defconfig
===================================================================
--- linux-2.6.18-rc4.orig/arch/powerpc/configs/pmac32_defconfig
+++ linux-2.6.18-rc4/arch/powerpc/configs/pmac32_defconfig
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.17
-# Mon Jul  3 14:20:49 2006
+# Linux kernel version: 2.6.18-rc4-git1
+# Mon Aug 21 13:46:05 2006
 #
 # CONFIG_PPC64 is not set
 CONFIG_PPC32=y
@@ -60,13 +60,14 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_ALL is not set
@@ -91,7 +92,7 @@ CONFIG_BASE_SMALL=0
 #
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
@@ -182,7 +183,7 @@ CONFIG_PM=y
 CONFIG_PM_DEBUG=y
 CONFIG_SOFTWARE_SUSPEND=y
 CONFIG_PM_STD_PARTITION=""
-CONFIG_SECCOMP=y
+# CONFIG_SECCOMP is not set
 CONFIG_ISA_DMA_API=y
 
 #
@@ -515,7 +516,7 @@ CONFIG_WIRELESS_EXT=y
 #
 # Generic Driver Options
 #
-# CONFIG_STANDALONE is not set
+CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
 # CONFIG_DEBUG_DRIVER is not set
@@ -559,6 +560,7 @@ CONFIG_BLK_DEV_UB=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
@@ -591,7 +593,7 @@ CONFIG_IDEPCI_SHARE_IRQ=y
 # CONFIG_BLK_DEV_OFFBOARD is not set
 CONFIG_BLK_DEV_GENERIC=y
 # CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_SL82C105=y
+# CONFIG_BLK_DEV_SL82C105 is not set
 CONFIG_BLK_DEV_IDEDMA_PCI=y
 # CONFIG_BLK_DEV_IDEDMA_FORCED is not set
 CONFIG_IDEDMA_PCI_AUTO=y
@@ -793,7 +795,7 @@ CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
 CONFIG_THERM_WINDTUNNEL=m
 CONFIG_THERM_ADT746X=m
-# CONFIG_WINDFARM is not set
+CONFIG_WINDFARM=m
 # CONFIG_ANSLCD is not set
 
 #
@@ -952,7 +954,7 @@ CONFIG_PPP_SYNC_TTY=m
 CONFIG_PPP_DEFLATE=y
 CONFIG_PPP_BSDCOMP=m
 # CONFIG_PPP_MPPE is not set
-# CONFIG_PPPOE is not set
+CONFIG_PPPOE=m
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
 # CONFIG_SHAPER is not set
@@ -979,7 +981,7 @@ CONFIG_INPUT=y
 # Userland interfaces
 #
 CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
 CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 # CONFIG_INPUT_JOYDEV is not set
@@ -1007,11 +1009,7 @@ CONFIG_INPUT_MOUSE=y
 #
 # Hardware I/O ports
 #
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO is not set
 # CONFIG_GAMEPORT is not set
 
 #
@@ -1479,7 +1477,7 @@ CONFIG_USB_APPLETOUCH=y
 #
 # CONFIG_USB_CATC is not set
 # CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
+CONFIG_USB_PEGASUS=m
 # CONFIG_USB_RTL8150 is not set
 CONFIG_USB_USBNET=m
 CONFIG_USB_NET_AX8817X=m
@@ -1490,7 +1488,7 @@ CONFIG_USB_NET_NET1080=m
 # CONFIG_USB_NET_RNDIS_HOST is not set
 # CONFIG_USB_NET_CDC_SUBSET is not set
 CONFIG_USB_NET_ZAURUS=m
-CONFIG_USB_MON=y
+# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -1502,7 +1500,6 @@ CONFIG_USB_MON=y
 CONFIG_USB_SERIAL=m
 # CONFIG_USB_SERIAL_GENERIC is not set
 # CONFIG_USB_SERIAL_AIRPRIME is not set
-# CONFIG_USB_SERIAL_ANYDATA is not set
 # CONFIG_USB_SERIAL_ARK3116 is not set
 # CONFIG_USB_SERIAL_BELKIN is not set
 # CONFIG_USB_SERIAL_WHITEHEAT is not set
@@ -1540,6 +1537,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 # CONFIG_USB_SERIAL_PL2303 is not set
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
+# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
 # CONFIG_USB_SERIAL_TI is not set
 # CONFIG_USB_SERIAL_CYBERJACK is not set
 # CONFIG_USB_SERIAL_XIRCOM is not set
@@ -1557,7 +1555,7 @@ CONFIG_USB_EZUSB=y
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
 # CONFIG_USB_LED is not set
-# CONFIG_USB_CY7C63 is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
 # CONFIG_USB_CYTHERM is not set
 # CONFIG_USB_PHIDGETKIT is not set
 # CONFIG_USB_PHIDGETSERVO is not set
@@ -1728,7 +1726,6 @@ CONFIG_RPCSEC_GSS_KRB5=y
 CONFIG_SMB_FS=m
 # CONFIG_SMB_NLS_DEFAULT is not set
 # CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
 # CONFIG_AFS_FS is not set
@@ -1763,8 +1760,8 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
 # CONFIG_NLS_CODEPAGE_855 is not set
 # CONFIG_NLS_CODEPAGE_857 is not set
 # CONFIG_NLS_CODEPAGE_860 is not set
@@ -1781,7 +1778,7 @@ CONFIG_NLS_CODEPAGE_437=m
 # CONFIG_NLS_CODEPAGE_949 is not set
 # CONFIG_NLS_CODEPAGE_874 is not set
 # CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
+CONFIG_NLS_CODEPAGE_1250=m
 # CONFIG_NLS_CODEPAGE_1251 is not set
 # CONFIG_NLS_ASCII is not set
 CONFIG_NLS_ISO8859_1=m
@@ -1794,7 +1791,7 @@ CONFIG_NLS_ISO8859_1=m
 # CONFIG_NLS_ISO8859_9 is not set
 # CONFIG_NLS_ISO8859_13 is not set
 # CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
+CONFIG_NLS_ISO8859_15=m
 # CONFIG_NLS_KOI8_R is not set
 # CONFIG_NLS_KOI8_U is not set
 CONFIG_NLS_UTF8=m
@@ -1824,18 +1821,20 @@ CONFIG_OPROFILE=y
 # Kernel hacking
 #
 # CONFIG_PRINTK_TIME is not set
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_KERNEL=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_MUTEXES is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_RWSEMS is not set
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
 # CONFIG_DEBUG_KOBJECT is not set
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_FS is not set

^ permalink raw reply

* Re: booting with BootX corrupts memory
From: Olaf Hering @ 2006-08-21 12:17 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Niels Kristian Bech Jensen
In-Reply-To: <20060818070113.GA28088@aepfle.de>

On Fri, Aug 18, 2006 at 09:01:13AM +0200, Olaf Hering wrote:

> On Fri, Aug 18, 2006 at 02:02:12PM +1000, Benjamin Herrenschmidt wrote:
> > On Wed, 2006-08-09 at 06:00 +0200, Niels Kristian Bech Jensen wrote:
> > >  On Tue, Aug  1, Olaf Hering wrote:
> > > 
> > > > Booting an old Mac with BootX corrupts memory, the kernel seldom gets
> > > > into init. Even the built-in initramfs archive gets corrupted. So far I
> > > > havent figured out where the corruption starts. The only data point so
> > > > far is that a passed initrd gets overwritten with stuff that looks like
> > > > part of the device-tree after the call to free_area_init_node() from
> > > > paging_init(). Perhaps the virtual/real address mapping isnt handled
> > > > correctly.
> > > 
> > > > This is broken since at least 2.6.15, 2.6.14 dies very early, 2.6.13 was
> > > > still ok.
> > > 
> > > > Symptoms differ, depending on used .config and wether an initrd is passed.
> > > 
> > > I think I've been hit by this bug on my beige G3 running Ubuntu Edgy.
> > > 
> > > When booting with initrd the boot process stops before any kernel output (CONFIG_BOOTX_TEXT is not enabled).
> > > Booting without initrd works fine - at least until it cannot find the root filesystem driver. ;-)
> > 
> > Does this patch helps ?
> 
> No, now I dont even get console= output on serial console.

It doesnt work on a 7200, butit works on a beige G3.
But later it locks up in 'PM: Adding info for No Bus:target0:0',
after mesh init. This one is likely unrelated.

^ permalink raw reply

* Re: [2.6.19 PATCH 7/7] ehea: Makefile & Kconfig
From: Thomas Klein @ 2006-08-21 12:16 UTC (permalink / raw)
  To: Alexey Dobriyan
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
	Christoph Raisch, linux-ppc, Marcus Eder
In-Reply-To: <20060818141847.GE5201@martell.zuzino.mipt.ru>

Alexey Dobriyan wrote:
 > On Fri, Aug 18, 2006 at 01:37:44PM +0200, Jan-Bernd Themann wrote:
 >> --- linux-2.6.18-rc4/drivers/net/Kconfig
 >> +++ patched_kernel/drivers/net/Kconfig
 >> @@ -2277,6 +2277,12 @@ config CHELSIO_T1
 >>            To compile this driver as a module, choose M here: the module
 >>            will be called cxgb.
 >>
 >> +config EHEA
 >> +        tristate "eHEA Ethernet support"
 >> +        depends on IBMEBUS
 >> +        ---help---
 >> +          This driver supports the IBM pSeries ethernet adapter
 >                                                                 .
 >
 > People usually add the following boilerplate:
 >
 >       To compile this driver as a module, choose M here: the module
 >       will be called $FOO.

Agreed.

^ permalink raw reply

* Re: [2.6.19 PATCH 5/7] ehea: main header files
From: Thomas Klein @ 2006-08-21 12:03 UTC (permalink / raw)
  To: Michael Neuling
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
	Christoph Raisch, linux-ppc, Marcus Eder
In-Reply-To: <20060818180345.9660E67B64@ozlabs.org>

Michael Neuling wrote:
 >> +static inline void ehea_update_sqa(struct ehea_qp *qp, u16 nr_wqes)
 >> +{
 >> +    struct h_epa epa = qp->epas.kernel;
 >> +    epa_store_acc(epa, QPTEMM_OFFSET(qpx_sqa),
 >> +                  EHEA_BMASK_SET(QPX_SQA_VALUE, nr_wqes));
 >> +}
 >> +
 >> +static inline void ehea_update_rq3a(struct ehea_qp *qp, u16 nr_wqes)
 >> +{
 >> +    struct h_epa epa = qp->epas.kernel;
 >> +    epa_store_acc(epa, QPTEMM_OFFSET(qpx_rq3a),
 >> +                  EHEA_BMASK_SET(QPX_RQ1A_VALUE, nr_wqes));
 >> +}
 >> +
 >> +static inline void ehea_update_rq2a(struct ehea_qp *qp, u16 nr_wqes)
 >> +{
 >> +    struct h_epa epa = qp->epas.kernel;
 >> +    epa_store_acc(epa, QPTEMM_OFFSET(qpx_rq2a),
 >> +                  EHEA_BMASK_SET(QPX_RQ1A_VALUE, nr_wqes));
 >> +}
 >> +
 >> +static inline void ehea_update_rq1a(struct ehea_qp *qp, u16 nr_wqes)
 >> +{
 >> +    struct h_epa epa = qp->epas.kernel;
 >> +    epa_store_acc(epa, QPTEMM_OFFSET(qpx_rq1a),
 >> +                  EHEA_BMASK_SET(QPX_RQ1A_VALUE, nr_wqes));
 >> +}
 >> +
 >> +static inline void ehea_update_feca(struct ehea_cq *cq, u32 nr_cqes)
 >> +{
 >> +    struct h_epa epa = cq->epas.kernel;
 >> +    epa_store_acc(epa, CQTEMM_OFFSET(cqx_feca),
 >> +                  EHEA_BMASK_SET(CQX_FECADDER, nr_cqes));
 >> +}
 >> +
 >> +static inline void ehea_reset_cq_n1(struct ehea_cq *cq)
 >> +{
 >> +    struct h_epa epa = cq->epas.kernel;
 >> +    epa_store_cq(epa, cqx_n1,
 >> +                 EHEA_BMASK_SET(CQX_N1_GENERATE_COMP_EVENT, 1));
 >> +}
 >> +
 >> +static inline void ehea_reset_cq_ep(struct ehea_cq *my_cq)
 >> +{
 >> +    struct h_epa epa = my_cq->epas.kernel;
 >> +    epa_store_acc(epa, CQTEMM_OFFSET(cqx_ep),
 >> +                  EHEA_BMASK_SET(CQX_EP_EVENT_PENDING, 0));
 >> +}
 >
 > These are almost identical... I'm sure most (if not all) could be merged
 > into a single function or #define.
 >
 > Mikey

Hi Mikey,

I gave it a try: ehea_reset_cq_n1() drops out because it calls epa_store_cq(),
not epa_store_acc(). ehea_update_feca() and ehea_reset_cq_ep() require a
different input parm as the others and replacing two inline functions by
one inline function and two macros doesn't help neither the code nor does
it improve readability.
Finally we have ehea_update_sqa() and the 3 ehea_update_rqXa() functions which
I replaced by an inline function and four macros. See the result below. It
think understanding what this does is way more difficult than looking at the
four inline functions we had before. Therefore I'd prefer leaving those inline
functions as is.

Regards
Thomas


#define ehea_update_sqa(qp, nr_wqes) \
         ehea_update_qa(qp, nr_wqes, \
                        QPTEMM_OFFSET(qpx_sqa), \
                        EHEA_BMASK_SET(QPX_SQA_VALUE, nr_wqes));

#define ehea_update_rq1a(qp, nr_wqes) \
         ehea_update_qa(qp, nr_wqes, \
                        QPTEMM_OFFSET(qpx_rq1a), \
                        EHEA_BMASK_SET(QPX_RQ1A_VALUE, nr_wqes));

#define ehea_update_rq2a(qp, nr_wqes) \
         ehea_update_qa(qp, nr_wqes, \
                        QPTEMM_OFFSET(qpx_rq2a), \
                        EHEA_BMASK_SET(QPX_RQ2A_VALUE, nr_wqes));

#define ehea_update_rq3a(qp, nr_wqes) \
         ehea_update_qa(qp, nr_wqes, \
                        QPTEMM_OFFSET(qpx_rq3a), \
                        EHEA_BMASK_SET(QPX_RQ3A_VALUE, nr_wqes));

static inline void ehea_update_qa(struct ehea_qp *qp, u16 nr_wqes,
                                   u32 offset, u64 value)
{
         struct h_epa epa = qp->epas.kernel;
         epa_store_acc(epa, offset, value);
}

^ permalink raw reply

* Re: [2.6.19 PATCH 4/7] ehea: ethtool interface
From: Thomas Klein @ 2006-08-21 10:53 UTC (permalink / raw)
  To: Alexey Dobriyan
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
	Christoph Raisch, linux-ppc, Marcus Eder
In-Reply-To: <20060818140506.GC5201@martell.zuzino.mipt.ru>


Alexey Dobriyan wrote:
 > On Fri, Aug 18, 2006 at 01:33:22PM +0200, Jan-Bernd Themann wrote:
 >> --- linux-2.6.18-rc4-orig/drivers/net/ehea/ehea_ethtool.c
 >> +++ kernel/drivers/net/ehea/ehea_ethtool.c
 >> +{
 >> +    strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
 >> +    strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
 >
 > Use strlcpy() to not forget -1 accidently.

Done.

 >
 >> +static u32 netdev_get_msglevel(struct net_device *dev)
 >                        ^^^^^^^^
 >> +{
 >> +    struct ehea_port *port = netdev_priv(dev);
 >> +    return port->msg_enable;
 >                        ^^^^^^
 >
 > Something is mis-named here.

The kernel requires a structure member of that name.

 >> +struct ethtool_ops ehea_ethtool_ops = {
 >> +    .get_settings = netdev_get_settings,
 >> +    .get_drvinfo = netdev_get_drvinfo,
 >> +    .get_msglevel = netdev_get_msglevel,
 >> +    .set_msglevel = netdev_set_msglevel,
 >> +        .get_link = ethtool_op_get_link,
 >> +        .get_tx_csum = ethtool_op_get_tx_csum,
 >
 > Whitespace breakage.

Fixed.

 >> +    .set_settings = NULL,
 >> +    .nway_reset = NULL,
 >> +    .get_pauseparam = NULL,
 >> +    .set_pauseparam = NULL,
 >> +    .get_rx_csum = NULL,
 >> +    .set_rx_csum = NULL,
 >> +    .phys_id = NULL,
 >> +    .self_test = NULL,
 >> +    .self_test_count = NULL
 >
 > If you don't use them, don't mention them at all. Compiler will DTRT.

Agreed. Assignments removed.

Thanks again :-)
Thomas

^ permalink raw reply

* Re: [2.6.19 PATCH 2/7] ehea: pHYP interface
From: Thomas Klein @ 2006-08-21 10:21 UTC (permalink / raw)
  To: Alexey Dobriyan
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
	Christoph Raisch, linux-ppc, Marcus Eder
In-Reply-To: <20060818150600.GG5201@martell.zuzino.mipt.ru>

Alexey Dobriyan wrote:
> On Fri, Aug 18, 2006 at 01:30:21PM +0200, Jan-Bernd Themann wrote:
>> --- linux-2.6.18-rc4-orig/drivers/net/ehea/ehea_phyp.c
>> +++ kernel/drivers/net/ehea/ehea_phyp.c
> 
>> +	hret = ehea_h_register_rpage(hcp_adapter_handle, pagesize, queue_type,
>> +				     eq_handle, log_pageaddr, count);
>> +	return hret;
> 
> Just
> 	return ehea_h_register_rpage(...);
> 
>> +	hret = ehea_h_register_rpage(hcp_adapter_handle, pagesize, queue_type,
>> +				     cq_handle, log_pageaddr, count);
>> +	return hret;
> 
> Ditto.
> 
>> +	hret = ehea_h_register_rpage(hcp_adapter_handle, pagesize, queue_type,
>> +				     qp_handle, log_pageaddr, count);
>> +	return hret;
>> +}
> 
> Ditto.

Returncode handling was reworked throughout the whole driver. Those assignments
were modified according to your suggestion.

>> +static inline int hcp_epas_ctor(struct h_epas *epas, u64 paddr_kernel,
>> +				u64 paddr_user)
>> +{
>> +	epas->kernel.fw_handle = (u64) ioremap(paddr_kernel, PAGE_SIZE);
>> +	epas->user.fw_handle = paddr_user;
>> +	return 0;
>> +}
>> +
>> +static inline int hcp_epas_dtor(struct h_epas *epas)
>> +{
>> +
>> +	if (epas->kernel.fw_handle)
>> +		iounmap((void *)epas->kernel.fw_handle);
>> +	epas->user.fw_handle = epas->kernel.fw_handle = 0;
>> +	return 0;
>> +}
> 
> Always returns 0;

Correct. They're returning void now.

Thanks
Thomas

^ permalink raw reply

* Re: [RFC PATCH 1/4] powerpc 2.6.16-rt17: to build on powerpc w/ RT
From: Tsutomu OWA @ 2006-08-21 10:01 UTC (permalink / raw)
  To: john stultz; +Cc: linux-kernel, linuxppc-dev, Paul Mackerras, mingo, tglx
In-Reply-To: <1155318983.5337.2.camel@localhost.localdomain>


Sorry about the late response.

> On Fri, 11 Aug 2006 10:56:23 -0700, john stultz <johnstul@us.ibm.com> wrote:

> You might take a peek at the patch set here:
> http://sr71.net/~jstultz/tod/ for a somewhat rough powerpc conversion to
> CONFIG_GENERIC_TIME.

  Thank a lot for the info.  I'll look into it (I need to read
timekeeping.txt first...)

  BTW, do you have any plan to make it vsdo safe?
# I'm completely unfamiliar with vsdo :-X.

thanks
-- owa
Software Engineering Center, TOSHIBA.

^ permalink raw reply

* Re: [2.6.19 PATCH 4/7] ehea: ethtool interface
From: Thomas Klein @ 2006-08-21  9:53 UTC (permalink / raw)
  To: Stephen Hemminger
  Cc: Thomas Klein, Jan-Bernd Themann, netdev, linux-kernel,
	Christoph Raisch, linux-ppc, Marcus Eder, Alexey Dobriyan
In-Reply-To: <20060818104547.5ad1352f@localhost.localdomain>

Stephen Hemminger wrote:
> On Fri, 18 Aug 2006 17:41:26 +0200
> Thomas Klein <osstklei@de.ibm.com> wrote:
> 
>> Hi Alexey,
>>
>> first of all thanks a lot for the extensive review.
>>
>>
>> Alexey Dobriyan wrote:
>>>> +	u64 hret = H_HARDWARE;
>>> Useless assignment here and everywhere.
>>>
>> Initializing returncodes to errorstate is a cheap way to prevent
>> accidentally returning (uninitalized) success returncodes which
>> can lead to catastrophic misbehaviour.
> 
> That is old thinking. Current compilers do live/dead analysis
> and tell you about this at compile time which is better than relying
> on default behavior at runtime.

Understood. I reworked the returncode handling and removed the
unnecessary initializations.

Thanks for pointing this out.

Thomas

^ permalink raw reply

* [RFC PATCH 3/4] powerpc 2.6.16-rt17: to support CONFIG_MCOUNT
From: Tsutomu OWA @ 2006-08-21  9:44 UTC (permalink / raw)
  To: Daniel Walker; +Cc: mingo, tglx, linux-kernel, linuxppc-dev
In-Reply-To: <1155305556.16579.49.camel@c-67-188-28-158.hsd1.ca.comcast.net>


Sorry about the late response and thanks a lot for your comments.

> On Fri, 11 Aug 2006 07:12:35 -0700, Daniel Walker <dwalker@mvista.com> said:

>> On Fri, 2006-08-11 at 11:02 +0900, Tsutomu OWA wrote:

>> +
>> +#if defined(CONFIG_PREEMPT_TRACE) || defined(CONFIG_LATENCY_TRACE)
>> +        print_traces(current);
>> +#endif /* CONFIG_PREEMPT_TRACE || CONFIG_LATENCY_TRACE */

> You shouldn't need the ifdef's here.

  Right.  I'll remove them.

>> +#ifdef CONFIG_DEBUG_MUTEXES
>> +	show_held_locks(current);
>> +#endif /* CONFIG_DEBUG_MUTEXES */
>> +
>> }
>> EXPORT_SYMBOL(dump_stack);
>> 
>> diff -rup -x CVS 2.6.16-rt17/arch/powerpc/kernel/prom.c rt-powerpc/arch/powerpc/kernel/prom.c

> Your on an ancient version of the -rt patch. I see that your using CVS
> which explains that. If you want to keep better pace you should consider
> not using CVS. 

  Hmm... I'll think about that.

>> diff -rup -x CVS 2.6.16-rt17/lib/string.c rt-powerpc/lib/string.c
>> --- 2.6.16-rt17/lib/string.c	2006-03-20 14:53:29.000000000 +0900
>> +++ rt-powerpc/lib/string.c	2006-06-16 13:08:07.000000000 +0900
>> @@ -67,7 +67,7 @@ EXPORT_SYMBOL(strnicmp);
>> * @src: Where to copy the string from
>> */
>> #undef strcpy
>> -char *strcpy(char *dest, const char *src)
>> +char * notrace strcpy(char *dest, const char *src)
>> {
>> char *tmp = dest;

> Why are these notrace ?

  Because these are called from prom_init before the relocation.
I was a bit reluctant to calcurate the address of mcount_enabled,
every time _mcount is called and was not sure if it's ok to call
__trace() at this early stage.

thanks.
-- owa
Software Engineering Center, TOSHIBA.

^ permalink raw reply

* Re: Broken Firewire 400/SCSI on ppc Powerbook5,8
From: Stefan Richter @ 2006-08-21  7:56 UTC (permalink / raw)
  To: Wolfgang Pfeiffer; +Cc: linuxppc-dev, linux1394-devel
In-Reply-To: <20060820013121.GA2732@localhost>

Wolfgang Pfeiffer wrote:
[...]
> So at least it looks now as if the Firewire 400 Hardware on the
> alubook is not broken. Correct? Would be a great relief as I hate it
> to have it away at the repair service.
> 
> I could mount the 2 tibook partitions easily on the alubook.

Yes, the port is certainly working correctly.

> OTOH: Connecting the alubook and tibook with Linux up and running on
> both machines did not create a working (FW) connection between them ..

Of course they won't export SBP-2 targets then. But they should be
visible in Linux' sysfs or gscanbus or OS X' system profiler as external
nodes. It is also possible to establish an IPv4 connection over FireWire
between them, using eth1394 on Linux and OS X' network preferences panel.

[...]
> BTW: Do you know how to switch off verbose logging for the 1394
> drivers once they're compiled into the kernel, via some
> echo  "<some-value>" to /sys/*/* ?
> I didn't find any entry there until now for that purpose ...

It can only be configured at compile time.
-- 
Stefan Richter
-=====-=-==- =--- =-=-=
http://arcgraph.de/sr/

^ permalink raw reply

* Re: Broken Firewire 400/SCSI on ppc Powerbook5,8
From: Wolfgang Pfeiffer @ 2006-08-21  0:40 UTC (permalink / raw)
  To: Stefan Richter; +Cc: linuxppc-dev, linux1394-devel
In-Reply-To: <20060821002921.GA2736@localhost>

On Mon, Aug 21, 2006 at 02:29:21AM +0200, Wolfgang Pfeiffer wrote:

> Note: About 2 days ago I had, IIRC, ext2fsx

wrong: I had ext2fsx_dev installed, IIRC.

> (http://sourceforge.net/project/showfiles.php?group_id=64713) shortly
> installed on OSX - I quickly uninstalled it afterwards, [ ... ]


Sorry
Wolfgang

-- 
Wolfgang Pfeiffer: /ICQ: 286585973/ + + +  /AIM: crashinglinux/
http://profiles.yahoo.com/wolfgangpfeiffer

Key ID: E3037113
http://keyserver.mine.nu/pks/lookup?search=0xE3037113&fingerprint=on

^ permalink raw reply

* Re: Broken Firewire 400/SCSI on ppc Powerbook5,8
From: Wolfgang Pfeiffer @ 2006-08-21  0:29 UTC (permalink / raw)
  To: Stefan Richter; +Cc: linuxppc-dev, linux1394-devel
In-Reply-To: <44E6D634.3000207@s5r6.in-berlin.de>

On Sat, Aug 19, 2006 at 11:13:24AM +0200, Stefan Richter wrote:

> If you have got the TiBook around, you could connect it with the AlBook 
> and look what gscanbus or OS X's system profiler have to say about it. 
> If possible, also try the TiBook in target disk mode and see if it 
> appears as a disk for Linux' sbp2 or under OS X.

I sent the test results of the target disk mode last night.

Now this evening I tried to connect the alubook to the titanium via the FW
400 ports with both machines fully booted. 

First the alubook with OSX connected to the titanium with Linux on it,
and then both computers connected to each other with Linux running on
both of them.

The alubook is a dual-boot machine (OSX/Linux), while the titanium
only has Linux on it.


_____________________________________________________________________________
PART I

Connecting the alubook (with OSX running) to the tibook (with Linux running)
---------------------------------------------------------------------------

Status on the titanium, with a kernel 2.6.14-1, IEEE1394_VERBOSEDEBUG
is enabled there.

After modprobing raw1394 the connected AluBook (OSX running) is seen
via gscanbus, but /dev/sda is not created. sbp2 was not started at
that time.  modprobing sbp2 does not help to change this.

gscanbus tho:

clicking
S400 Linux - ohci 1394:

------------------------
SelfID Info
-----------
Physical ID: 1
Link active: Yes
Gap Count: 63
PHY Speed: S400
PHY Delay: <=144ns
IRM Capable: Yes
Power Class: None
Port 0: Connected to child node
Init. reset: Yes

CSR ROM Info
------------
GUID: 0x000393FFFECDE4C4
Node Capabilities: 0x000083C0
Vendor ID: 0x00000393
Unit Spec ID: 0x0000005E
Unit SW Version: 0x00000001
Model ID: 0x00000000
Nr. Textual Leafes: 1

Vendor:  Apple Computer, Inc.
Textual Leafes: 
Linux - ohci1394

AV/C Subunits
-------------
N/A

---------------------


clicking
"Unknown
Apple Computer, Inc." results in:

---------------------
SelfID Info
-----------
Physical ID: 0
Link active: Yes
Gap Count: 63
PHY Speed: Unknown
PHY Delay: <=144ns
IRM Capable: Yes
Power Class: -1W
Port 0: Not connected
Port 1: Connected to parent node
Port 2: Not connected
Init. reset: No

CSR ROM Info
------------
GUID: 0x001451FFFE3148BE
Node Capabilities: 0x000083C0
Vendor ID: 0x00000A27
Unit Spec ID: 0x0000005E
Unit SW Version: 0x00000002
Model ID: 0x00000000
Nr. Textual Leafes: 2

Vendor:  Apple Computer, Inc.
Textual Leafes: 
Apple Computer, Inc.
Macintosh

AV/C Subunits
-------------
N/A

--------------------

Im getting in /var/log/kern.log messages like this:

---------------------------------
Aug 20 23:48:27 debby kernel: [ 2389.161336] raw1394:read_request called
Aug 20 23:48:27 debby kernel: [ 2389.161357] ieee1394: send packet local: ffc1a540 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.161369] ieee1394: received packet: ffc1a540 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.161386] ieee1394: send packet local: ffc1a560 ffc10000 00000000 7a2367e9
Aug 20 23:48:27 debby kernel: [ 2389.161400] ieee1394: received packet: ffc1a560 ffc10000 00000000 7a2367e9
Aug 20 23:48:27 debby kernel: [ 2389.261335] raw1394:read_request called
Aug 20 23:48:27 debby kernel: [ 2389.261356] ieee1394: send packet local: ffc1a940 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.261369] ieee1394: received packet: ffc1a940 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.261386] ieee1394: send packet local: ffc1a960 ffc10000 00000000 7a5567ff
Aug 20 23:48:27 debby kernel: [ 2389.261400] ieee1394: received packet: ffc1a960 ffc10000 00000000 7a5567ff
Aug 20 23:48:27 debby kernel: [ 2389.361334] raw1394:read_request called
Aug 20 23:48:27 debby kernel: [ 2389.361356] ieee1394: send packet local: ffc1ad40 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.361369] ieee1394: received packet: ffc1ad40 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.361386] ieee1394: send packet local: ffc1ad60 ffc10000 00000000 7a876814
Aug 20 23:48:27 debby kernel: [ 2389.361401] ieee1394: received packet: ffc1ad60 ffc10000 00000000 7a876814
Aug 20 23:48:27 debby kernel: [ 2389.461326] raw1394:read_request called
Aug 20 23:48:27 debby kernel: [ 2389.461348] ieee1394: send packet local: ffc1b140 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.461361] ieee1394: received packet: ffc1b140 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.461378] ieee1394: send packet local: ffc1b160 ffc10000 00000000 7ab96750
Aug 20 23:48:27 debby kernel: [ 2389.461392] ieee1394: received packet: ffc1b160 ffc10000 00000000 7ab96750
Aug 20 23:48:27 debby kernel: [ 2389.561323] raw1394:read_request called
Aug 20 23:48:27 debby kernel: [ 2389.561346] ieee1394: send packet local: ffc1b540 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.561359] ieee1394: received packet: ffc1b540 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.561377] ieee1394: send packet local: ffc1b560 ffc10000 00000000 7aeb675c
Aug 20 23:48:27 debby kernel: [ 2389.561392] ieee1394: received packet: ffc1b560 ffc10000 00000000 7aeb675c
Aug 20 23:48:27 debby kernel: [ 2389.661317] raw1394:read_request called
Aug 20 23:48:27 debby kernel: [ 2389.661338] ieee1394: send packet local: ffc1b940 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.661351] ieee1394: received packet: ffc1b940 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.661367] ieee1394: send packet local: ffc1b960 ffc10000 00000000 7b1d668a
Aug 20 23:48:27 debby kernel: [ 2389.661382] ieee1394: received packet: ffc1b960 ffc10000 00000000 7b1d668a
Aug 20 23:48:27 debby kernel: [ 2389.761314] raw1394:read_request called
Aug 20 23:48:27 debby kernel: [ 2389.761335] ieee1394: send packet local: ffc1bd40 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.761348] ieee1394: received packet: ffc1bd40 ffc1ffff f0000200
Aug 20 23:48:27 debby kernel: [ 2389.761366] ieee1394: send packet local: ffc1bd60 ffc10000 00000000 7b4f6677
Aug 20 23:48:27 debby kernel: [ 2389.761381] ieee1394: received packet: ffc1bd60 ffc10000 00000000 7b4f6677
Aug 20 23:48:28 debby kernel: [ 2389.862296] raw1394:read_request called
Aug 20 23:48:28 debby kernel: [ 2389.862316] ieee1394: send packet local: ffc1c140 ffc1ffff f0000200
Aug 20 23:48:28 debby kernel: [ 2389.862329] ieee1394: received packet: ffc1c140 ffc1ffff f0000200
Aug 20 23:48:28 debby kernel: [ 2389.862347] ieee1394: send packet local: ffc1c160 ffc10000 00000000 7b81e4b4
Aug 20 23:48:28 debby kernel: [ 2389.862362] ieee1394: received packet: ffc1c160 ffc10000 00000000 7b81e4b4
---------------------------


This is what OSX (on the alubook) says:
---------------------


.. about the titanium with Linux running: No pasting possible of the
values I saw: I wrote it down what I saw on the OSX screen:


Network status in OS X System Preferences reports something like this:

"Built in Firewire"

"Cable for built-in Firewire is connected, but your computer does not
have an IP address and cannot connect to the Internet"

I didn't even try (never will) to reconfigure this - I don't trust OSX
enough to let it come closer than 500 meters to my Linux partitions.

The Apple System Profiler, as it seems about the Titanium:

---------------------
Firewire Bus:
Unknown device

Manufacturer: Linux - ohci1394
Model: unknown device
GUID: 0x393FFFECDE4C4
Maximum Speed: Up to 400 Mb/Sec
Connection Speed: Up to 400 Mb/Sec

Unknown Unit:
Unit Software version: 0x1
Unit Spec ID: 0x5E
-----------------------------


-----------------------------------------------------------------------------------
PART II

Connecting the alubook to the titanium, with both machines running Linux on them:
---------------------------------------------------------------------------------

Status on the titanium:

----------------------------------------------
$ /sbin/lsmod | grep -i sbp
sbp2                   24932  0 
scsi_mod              160836  2 sbp2,sg
ieee1394              425552  4 sbp2,raw1394,eth1394,ohci1394
[shorty@ 00:58:55]$ /sbin/lsmod | grep 1394  
raw1394                35064  2 
eth1394                20552  0 
ohci1394               44980  0 
ieee1394              425552  4 sbp2,raw1394,eth1394,ohci1394
--------------------------------------------------------

No /dev/sda on the titanium.

gscanbus:

2 icons on the gscanbus window:

#1:
" <some Penguin picture>
 S400
 Linux - ohci1394"

Clicking it:

------------------------------
SelfID Info
-----------
Physical ID: 1
Link active: Yes
Gap Count: 63
PHY Speed: S400
PHY Delay: <=144ns
IRM Capable: Yes
Power Class: None
Port 0: Connected to child node
Init. reset: Yes

CSR ROM Info
------------
GUID: 0x000393FFFECDE4C4
Node Capabilities: 0x000083C0
Vendor ID: 0x00000393
Unit Spec ID: 0x0000005E
Unit SW Version: 0x00000001
Model ID: 0x00000000
Nr. Textual Leafes: 1

Vendor:  Apple Computer, Inc.
Textual Leafes: 
Linux - ohci1394

AV/C Subunits
-------------
N/A

------------------------------


#2:

"<Question mark>
 Unknown
 Linux - ohci1394"


Clicking it:

----------------------------
SelfID Info
-----------
Physical ID: 0
Link active: Yes
Gap Count: 63
PHY Speed: Unknown
PHY Delay: <=144ns
IRM Capable: Yes
Power Class: -1W
Port 0: Not connected
Port 1: Connected to parent node
Port 2: Not connected
Init. reset: No

CSR ROM Info
------------
GUID: 0x001451FFFE3148BE
Node Capabilities: 0x000083C0
Vendor ID: 0x00001451
Unit Spec ID: 0x0000005E
Unit SW Version: 0x00000001
Model ID: 0x00000000
Nr. Textual Leafes: 1

Vendor: Unknown
Textual Leafes: 
Linux - ohci1394

AV/C Subunits
-------------
N/A

-----------------------------


---------------------------
Status on the alubook:
---------------------------

$ /sbin/lsmod | grep -i sbp
sbp2                   23528  0 
scsi_mod              154128  2 sr_mod,sbp2
ieee1394              417744  4 raw1394,sbp2,eth1394,ohci1394
[shorty@ 01:46:06]$ /sbin/lsmod | grep 1394
raw1394                28128  2 
eth1394                18628  0 
ohci1394               37392  0 
ieee1394              417744  4 raw1394,sbp2,eth1394,ohci1394

kernel is 2.6.18-rc4

$ zgrep IEEE1394_VERBOSEDEBUG /proc/config.gz
# CONFIG_IEEE1394_VERBOSEDEBUG is not set


gscanbus says this, after a "Force bus reset":

2 icons:

#1

"<Monitor with an Apple logo picture>
S400 
Linux - ohci1394"

clicking it:

-------------------------
SelfID Info
-----------
Physical ID: 1
Link active: Yes
Gap Count: 63
PHY Speed: S400
PHY Delay: <=144ns
IRM Capable: Yes
Power Class: None
Port 0: Connected to child node
Init. reset: No

CSR ROM Info
------------
GUID: 0x000393FFFECDE4C4
Node Capabilities: 0x000083C0
Vendor ID: 0x00000393
Unit Spec ID: 0x0000005E
Unit SW Version: 0x00000001
Model ID: 0x00000000
Nr. Textual Leafes: 1

Vendor:  Apple Computer, Inc.
Textual Leafes: 
Linux - ohci1394

AV/C Subunits
-------------
N/A

---------------------------
 

#2:

"<Monitor with a penguin picture>
Unknown
Linux - ohci1394"

clicking the picture:

-------------------------
SelfID Info
-----------
Physical ID: 0
Link active: Yes
Gap Count: 63
PHY Speed: Unknown
PHY Delay: <=144ns
IRM Capable: Yes
Power Class: -1W
Port 0: Not connected
Port 1: Connected to parent node
Port 2: Not connected
Init. reset: Yes

CSR ROM Info
------------
GUID: 0x001451FFFE3148BE
Node Capabilities: 0x000083C0
Vendor ID: 0x00001451
Unit Spec ID: 0x0000005E
Unit SW Version: 0x00000001
Model ID: 0x00000000
Nr. Textual Leafes: 1

Vendor: Unknown
Textual Leafes: 
Linux - ohci1394

AV/C Subunits
-------------
N/A

----------------------------

No kern.log messages that I saw after the bus reset via gscanbus.
No /dev/sda on the alubook.


> 
> The fact that Linux on the AlBook gets at least as far as "ieee1394: 
> Error parsing configrom for node 0-00:1023" indicates that not all hope 
> is lost. If you have got the time, compile the 1394 drivers for verbose 
> logging and send the log. Don't crosspost the log if it gets too big.

As I already wrote: Tuesday or Wednesday I'll have the git kernel
compiled, if all goes well. With CONFIG_IEEE1394_VERBOSEDEBUG enabled.


Note: About 2 days ago I had, IIRC, ext2fsx
(http://sourceforge.net/project/showfiles.php?group_id=64713) shortly
installed on OSX - I quickly uninstalled it afterwards, and at the time
of the tests today on OSX nothing *should* have been installed of that
software anymore .. let's hope :) 

I do not know too much on OS X, that's why I keep my hands off Linux
via OSX.


Until then

Best Regards
Wolfgang


-- 
Wolfgang Pfeiffer: /ICQ: 286585973/ + + +  /AIM: crashinglinux/
http://profiles.yahoo.com/wolfgangpfeiffer

Key ID: E3037113
http://keyserver.mine.nu/pks/lookup?search=0xE3037113&fingerprint=on

^ permalink raw reply

* mpic_alloc() parameter change in 2.6.18-rc4 - must update users
From: Guennadi Liakhovetski @ 2006-08-20 22:16 UTC (permalink / raw)
  To: linuxppc-dev

Hi all,

have all platforms been updated for the mpic_alloc() change in -rc4 since 
then? AFAICS, at least 85xx/mpc85xx_cds.c, 86xx/mpc86xx_hpcn.c, 
embedded6xx/mpc7448_hpc2.c in -rc4 are new and are calling it with the old 
parameters. Or has it already been fixed in some tree?

Thanks
Guennadi
---
Guennadi Liakhovetski

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox