Re: [PATCH 5/9] v4 Allow memory_block to span multiple memory sections

2010-08-04 Thread KAMEZAWA Hiroyuki
On Tue, 03 Aug 2010 08:40:49 -0500
Nathan Fontenot nf...@austin.ibm.com wrote:

 Update the memory sysfs code that each sysfs memory directory is now
 considered a memory block that can contain multiple memory sections per
 memory block.  The default size of each memory block is SECTION_SIZE_BITS
 to maintain the current behavior of having a single memory section per
 memory block (i.e. one sysfs directory per memory section).
 
 For architectures that want to have memory blocks span multiple
 memory sections they need only define their own memory_block_size_bytes()
 routine.
 
 Signed-off-by: Nathan Fontenot nf...@austin.ibm.com

Acked-by: KAMEZAWA Hiroyuki kamezawa.hir...@jp.fujitsu.com
(But maybe it's better to get ppc guy's Ack.)


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH 5/9] v4 Allow memory_block to span multiple memory sections

2010-08-03 Thread Nathan Fontenot
Update the memory sysfs code that each sysfs memory directory is now
considered a memory block that can contain multiple memory sections per
memory block.  The default size of each memory block is SECTION_SIZE_BITS
to maintain the current behavior of having a single memory section per
memory block (i.e. one sysfs directory per memory section).

For architectures that want to have memory blocks span multiple
memory sections they need only define their own memory_block_size_bytes()
routine.

Signed-off-by: Nathan Fontenot nf...@austin.ibm.com
---
 drivers/base/memory.c |  148 ++
 1 file changed, 103 insertions(+), 45 deletions(-)

Index: linux-2.6/drivers/base/memory.c
===
--- linux-2.6.orig/drivers/base/memory.c2010-08-02 13:45:34.0 
-0500
+++ linux-2.6/drivers/base/memory.c 2010-08-02 14:01:04.0 -0500
@@ -30,6 +30,14 @@
 static struct mutex mem_sysfs_mutex;
 
 #define MEMORY_CLASS_NAME  memory
+#define MIN_MEMORY_BLOCK_SIZE  (1  SECTION_SIZE_BITS)
+
+static int sections_per_block;
+
+static inline int base_memory_block_id(int section_nr)
+{
+   return (section_nr / sections_per_block) * sections_per_block;
+}
 
 static struct sysdev_class memory_sysdev_class = {
.name = MEMORY_CLASS_NAME,
@@ -84,22 +92,21 @@ EXPORT_SYMBOL(unregister_memory_isolate_
  * register_memory - Setup a sysfs device for a memory block
  */
 static
-int register_memory(struct memory_block *memory, struct mem_section *section)
+int register_memory(struct memory_block *memory)
 {
int error;
 
memory-sysdev.cls = memory_sysdev_class;
-   memory-sysdev.id = __section_nr(section);
+   memory-sysdev.id = memory-start_phys_index;
 
error = sysdev_register(memory-sysdev);
return error;
 }
 
 static void
-unregister_memory(struct memory_block *memory, struct mem_section *section)
+unregister_memory(struct memory_block *memory)
 {
BUG_ON(memory-sysdev.cls != memory_sysdev_class);
-   BUG_ON(memory-sysdev.id != __section_nr(section));
 
/* drop the ref. we got in remove_memory_block() */
kobject_put(memory-sysdev.kobj);
@@ -133,13 +140,16 @@ static ssize_t show_mem_end_phys_index(s
 static ssize_t show_mem_removable(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
 {
-   unsigned long start_pfn;
-   int ret;
+   unsigned long i, pfn;
+   int ret = 1;
struct memory_block *mem =
container_of(dev, struct memory_block, sysdev);
 
-   start_pfn = section_nr_to_pfn(mem-start_phys_index);
-   ret = is_mem_section_removable(start_pfn, PAGES_PER_SECTION);
+   for (i = mem-start_phys_index; i = mem-end_phys_index; i++) {
+   pfn = section_nr_to_pfn(i);
+   ret = is_mem_section_removable(pfn, PAGES_PER_SECTION);
+   }
+
return sprintf(buf, %d\n, ret);
 }
 
@@ -192,17 +202,14 @@ int memory_isolate_notify(unsigned long
  * OK to have direct references to sparsemem variables in here.
  */
 static int
-memory_block_action(struct memory_block *mem, unsigned long action)
+memory_section_action(unsigned long phys_index, unsigned long action)
 {
int i;
-   unsigned long psection;
unsigned long start_pfn, start_paddr;
struct page *first_page;
int ret;
-   int old_state = mem-state;
 
-   psection = mem-start_phys_index;
-   first_page = pfn_to_page(psection  PFN_SECTION_SHIFT);
+   first_page = pfn_to_page(phys_index  PFN_SECTION_SHIFT);
 
/*
 * The probe routines leave the pages reserved, just
@@ -215,8 +222,8 @@ memory_block_action(struct memory_block
continue;
 
printk(KERN_WARNING section number %ld page number %d 
-   not reserved, was it already online? \n,
-   psection, i);
+   not reserved, was it already online?\n,
+   phys_index, i);
return -EBUSY;
}
}
@@ -227,18 +234,13 @@ memory_block_action(struct memory_block
ret = online_pages(start_pfn, PAGES_PER_SECTION);
break;
case MEM_OFFLINE:
-   mem-state = MEM_GOING_OFFLINE;
start_paddr = page_to_pfn(first_page)  PAGE_SHIFT;
ret = remove_memory(start_paddr,
PAGES_PER_SECTION  PAGE_SHIFT);
-   if (ret) {
-   mem-state = old_state;
-   break;
-   }
break;
default:
-   WARN(1, KERN_WARNING %s(%p, %ld) unknown action: 
%ld\n,
-