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  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 

Acked-by: KAMEZAWA Hiroyuki 
(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 
---
 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",
-