v4 De-couple sysfs memory directories from memory sections
Subsystems (6)
cover v4 De-couple sysfs memory directories from memory sections
This set of patches de-couples the idea that there is a single directory in sysfs for each memory section. The intent of the patches is to reduce the number of sysfs directories created to resolve a boot-time performance issue. On very large systems boot time are getting very long (as seen on powerpc hardware) due to the enormous number of sysfs directories being created. On a system with 1 TB of memory we create ~63,000 directories. For even larger systems boot times are being measured in hours.
This set of patches allows for each directory created in sysfs to cover more than one memory section. The default behavior for sysfs directory creation is the same, in that each directory represents a single memory section. A new file 'end_phys_index' in each directory contains the physical_id of the last memory section covered by the directory so that users can easily determine the memory section range of a directory.
Updates for version 4 of the patchset includes an additional patch [4/9] that introduces a new mutex to be taken for any add or remove (not hotplug) of memory. The following updates are also included.
Patch 2/9 Add new phys_index properties
- The start_phys_index property was reverted to the original phys_index name.
Patch 3/9 Add section count to memory_block
- Use atomic_dec_and_test()
Patch 7/9 Update the node sysfs code
- Update the inline definition of unregister_mem_sects_under_nodes for !CONFIG_NUMA builds.
Patch 8/9 Define memory_block_size_bytes() for ppc/pseries
- Use an unsigned long for getting property value.
Patch 9/9 Update memory-hotplug documentation
- Minor updates for reversion of phys_index property name.
Thanks,
Nathan Fontenot
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/9 v4 Move the find_memory_block() routine up
Move the find_memory_block() routine up to avoid needing a forward declaration in subsequent patches.
--- drivers/base/memory.c | 62 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 31 deletions(-)
drivers/base/memory.c +31 -31
@@ -435,6 +435,37 @@ int __weak arch_get_memory_phys_device(ureturn 0 ; } +/* +* For now, we have a linear search to go find the appropriate +* memory_block corresponding to a particular phys_index. If +* this gets to be a real problem, we can always use a radix +* tree or something here. +* +* This could be made generic for all sysdev classes. +*/ +struct memory_block *find_memory_block (struct mem_section *section) +{ +struct kobject *kobj; +struct sys_device *sysdev; +struct memory_block *mem; +char name[sizeof (MEMORY_CLASS_NAME ) +9 +1 ]; + +/* +* This only works because we know that section == sysdev->id +* slightly redundant with sysdev_register() +*/ +sprintf (&name[0 ],"%s%d" ,MEMORY_CLASS_NAME ,__section_nr (section)); + + kobj =kset_find_obj (&memory_sysdev_class.kset, name); +if (!kobj) +return NULL ; + + sysdev = container_of(kobj, struct sys_device, kobj); + mem = container_of(sysdev, struct memory_block, sysdev); + +return mem; +} +static int add_memory_block (int nid,struct mem_section *section,unsigned long state,enum mem_add_context context) {
@@ -468,37 +499,6 @@ static int add_memory_block(int nid, strreturn ret; } -/* -* For now, we have a linear search to go find the appropriate -* memory_block corresponding to a particular phys_index. If -* this gets to be a real problem, we can always use a radix -* tree or something here. -* -* This could be made generic for all sysdev classes. -*/ -struct memory_block *find_memory_block (struct mem_section *section) -{ -struct kobject *kobj; -struct sys_device *sysdev; -struct memory_block *mem; -char name[sizeof (MEMORY_CLASS_NAME ) +9 +1 ]; - -/* -* This only works because we know that section == sysdev->id -* slightly redundant with sysdev_register() -*/ -sprintf (&name[0 ],"%s%d" ,MEMORY_CLASS_NAME ,__section_nr (section)); - - kobj =kset_find_obj (&memory_sysdev_class.kset, name); -if (!kobj) -return NULL ; - - sysdev = container_of(kobj, struct sys_device, kobj); - mem = container_of(sysdev, struct memory_block, sysdev); - -return mem; -} -int remove_memory_block (unsigned long node_id,struct mem_section *section,int phys_device) {
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 1/9] v4 Move the find_memory_block() routine up
Quoted 4 lines · On Tue, 03 Aug 2010 08:36:39 -0500 Nathan Fontenot <[email protected]> wrote:
Move the
find_memory_block()routine up to avoid needing a forward declaration in subsequent patches.Signed-off-by Nathan Fontenot <[email protected]>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 2/9 v4 Add new phys_index properties
In reply to Nathan FontenotUpdate the 'phys_index' properties of a memory block to include a 'start_phys_index' which is the same as the current 'phys_index' property. The property still appears as 'phys_index' in sysfs but the memory_block struct name is updated to indicate the start and end values. This also adds an 'end_phys_index' property to indicate the id of the last section in th memory block.
--- drivers/base/memory.c | 28 ++++++++++++++++++++-------- include/linux/memory.h | 3 ++- 2 files changed, 22 insertions(+), 9 deletions(-)
drivers/base/memory.c +20 -8
@@ -109,12 +109,20 @@ unregister_memory(struct memory_block *m* uses. */ -static ssize_t show_mem_phys_index (struct sys_device *dev, +static ssize_t show_mem_start_phys_index (struct sys_device *dev,struct sysdev_attribute *attr,char *buf) {struct memory_block *mem = container_of(dev, struct memory_block, sysdev); -return sprintf (buf,"%08lx\n" , mem->phys_index); +return sprintf (buf,"%08lx\n" , mem->start_phys_index); +} + +static ssize_t show_mem_end_phys_index (struct sys_device *dev, +struct sysdev_attribute *attr,char *buf) +{ +struct memory_block *mem = + container_of(dev, struct memory_block, sysdev); +return sprintf (buf,"%08lx\n" , mem->end_phys_index); }/*
@@ -128,7 +136,7 @@ static ssize_t show_mem_removable(structstruct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn =section_nr_to_pfn (mem->phys_index); + start_pfn =section_nr_to_pfn (mem->start_phys_index); ret =is_mem_section_removable (start_pfn,PAGES_PER_SECTION );return sprintf (buf,"%d\n" , ret); }
@@ -191,7 +199,7 @@ memory_block_action(struct memory_blockint ret;int old_state = mem->state; - psection = mem->phys_index; + psection = mem->start_phys_index; first_page =pfn_to_page (psection <<PFN_SECTION_SHIFT );/*
@@ -264,7 +272,7 @@ store_mem_state(struct sys_device *dev,int ret = -EINVAL ; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->phys_index; + phys_section_nr = mem->start_phys_index;if (!present_section_nr (phys_section_nr)) goto out;
@@ -296,7 +304,8 @@ static ssize_t show_phys_device(struct sreturn sprintf (buf,"%d\n" , mem->phys_device); } -static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); +static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); +static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL);
@@ -476,16 +485,18 @@ static int add_memory_block(int nid, strif (!mem)return -ENOMEM ; - mem->phys_index =__section_nr (section); + mem->start_phys_index =__section_nr (section); mem->state = state;mutex_init (&mem->state_mutex); - start_pfn =section_nr_to_pfn (mem->phys_index); + start_pfn =section_nr_to_pfn (mem->start_phys_index); mem->phys_device =arch_get_memory_phys_device (start_pfn); ret =register_memory (mem, section);if (!ret) ret =mem_create_simple_file (mem, phys_index);if (!ret) + ret =mem_create_simple_file (mem, end_phys_index); +if (!ret) ret =mem_create_simple_file (mem, state);if (!ret) ret =mem_create_simple_file (mem, phys_device);
@@ -507,6 +518,7 @@ int remove_memory_block(unsigned long no mem =find_memory_block (section);unregister_mem_sect_under_nodes (mem);mem_remove_simple_file (mem, phys_index); +mem_remove_simple_file (mem, end_phys_index);mem_remove_simple_file (mem, state);mem_remove_simple_file (mem, phys_device);mem_remove_simple_file (mem, removable);
include/linux/memory.h +2 -1
@@ -21,7 +21,8 @@#include <linux/mutex.h> struct memory_block { -unsigned long phys_index; +unsigned long start_phys_index; +unsigned long end_phys_index;unsigned long state;/* * This serializes all state change requests. It isn't
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 2/9] v4 Add new phys_index properties
Quoted 8 lines · On Tue, 03 Aug 2010 08:37:31 -0500 Nathan Fontenot <[email protected]> wrote:
Update the '
phys_index' properties of a memory block to include a 'start_phys_index' which is the same as the current 'phys_index' property. The property still appears as 'phys_index' in sysfs but thememory_blockstruct name is updated to indicate the start and end values. This also adds an 'end_phys_index' property to indicate the id of the last section in th memory block.Signed-off-by Nathan Fontenot <[email protected]>
nitpick. After this patch, end_phys_index is added but contains 0. It's better to contain the same value with phys_index..
But, ok. Following patch will fix it.
Thanks,
-Kame
Quoted 114 lines
--- drivers/base/memory.c | 28 ++++++++++++++++++++-------- include/linux/memory.h | 3 ++- 2 files changed, 22 insertions(+), 9 deletions(-)Index:
linux-2.6/drivers/base/memory.c
===================================================================drivers/base/memory.c +20
-8@@ -109,12 +109,20 @@ unregister_memory(struct memory_block *m* uses. */ -static ssize_t show_mem_phys_index (struct sys_device *dev, +static ssize_t show_mem_start_phys_index (struct sys_device *dev,struct sysdev_attribute *attr,char *buf) {struct memory_block *mem = container_of(dev, struct memory_block, sysdev); -return sprintf (buf,"%08lx\n" , mem->phys_index); +return sprintf (buf,"%08lx\n" , mem->start_phys_index); +} + +static ssize_t show_mem_end_phys_index (struct sys_device *dev, +struct sysdev_attribute *attr,char *buf) +{ +struct memory_block *mem = + container_of(dev, struct memory_block, sysdev); +return sprintf (buf,"%08lx\n" , mem->end_phys_index); }/* @@ -128,7 +136,7 @@ static ssize_t show_mem_removable(structstruct memory_block *mem = container_of(dev, struct memory_block, sysdev); - start_pfn =section_nr_to_pfn (mem->phys_index); + start_pfn =section_nr_to_pfn (mem->start_phys_index); ret =is_mem_section_removable (start_pfn,PAGES_PER_SECTION );return sprintf (buf,"%d\n" , ret); }@@ -191,7 +199,7 @@ memory_block_action(struct memory_blockint ret;int old_state = mem->state; - psection = mem->phys_index; + psection = mem->start_phys_index; first_page =pfn_to_page (psection <<PFN_SECTION_SHIFT );/* @@ -264,7 +272,7 @@ store_mem_state(struct sys_device *dev,int ret = -EINVAL ; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->phys_index; + phys_section_nr = mem->start_phys_index;if (!present_section_nr (phys_section_nr)) goto out;@@ -296,7 +304,8 @@ static ssize_t show_phys_device(struct sreturn sprintf (buf,"%d\n" , mem->phys_device); } -static SYSDEV_ATTR(phys_index, 0444, show_mem_phys_index, NULL); +static SYSDEV_ATTR(phys_index, 0444, show_mem_start_phys_index, NULL); +static SYSDEV_ATTR(end_phys_index, 0444, show_mem_end_phys_index, NULL); static SYSDEV_ATTR(state, 0644, show_mem_state, store_mem_state); static SYSDEV_ATTR(phys_device, 0444, show_phys_device, NULL); static SYSDEV_ATTR(removable, 0444, show_mem_removable, NULL);@@ -476,16 +485,18 @@ static int add_memory_block(int nid, strif (!mem)return -ENOMEM ; - mem->phys_index =__section_nr (section); + mem->start_phys_index =__section_nr (section); mem->state = state;mutex_init (&mem->state_mutex); - start_pfn =section_nr_to_pfn (mem->phys_index); + start_pfn =section_nr_to_pfn (mem->start_phys_index); mem->phys_device =arch_get_memory_phys_device (start_pfn); ret =register_memory (mem, section);if (!ret) ret =mem_create_simple_file (mem, phys_index);if (!ret) + ret =mem_create_simple_file (mem, end_phys_index); +if (!ret) ret =mem_create_simple_file (mem, state);if (!ret) ret =mem_create_simple_file (mem, phys_device);@@ -507,6 +518,7 @@ int remove_memory_block(unsigned long no mem =find_memory_block (section);unregister_mem_sect_under_nodes (mem);mem_remove_simple_file (mem, phys_index); +mem_remove_simple_file (mem, end_phys_index);mem_remove_simple_file (mem, state);mem_remove_simple_file (mem, phys_device);mem_remove_simple_file (mem, removable);Index:
linux-2.6/include/linux/memory.h
===================================================================include/linux/memory.h +2
-2@@ -21,7 +21,8 @@#include <linux/mutex.h> struct memory_block { -unsigned long phys_index; +unsigned long start_phys_index; +unsigned long end_phys_index;unsigned long state;/* * This serializes all state change requests. It isn't --
Quoted 5 lines
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/9 v4 Add section count to memory_block
In reply to Nathan FontenotAdd a section count property to the memory_block struct to track the number of memory sections that have been added/removed from a memory block. This allows us to know when the last memory section of a memory block has been removed so we can remove the memory block.
--- drivers/base/memory.c | 18 +++++++++++------- include/linux/memory.h | 2 ++ 2 files changed, 13 insertions(+), 7 deletions(-)
drivers/base/memory.c +11 -7
@@ -487,6 +487,7 @@ static int add_memory_block(int nid, str mem->start_phys_index =__section_nr (section); mem->state = state; +atomic_inc (&mem->section_count);mutex_init (&mem->state_mutex); start_pfn =section_nr_to_pfn (mem->start_phys_index); mem->phys_device =arch_get_memory_phys_device (start_pfn);
@@ -516,13 +517,16 @@ int remove_memory_block(unsigned long nostruct memory_block *mem; mem =find_memory_block (section); -unregister_mem_sect_under_nodes (mem); -mem_remove_simple_file (mem, phys_index); -mem_remove_simple_file (mem, end_phys_index); -mem_remove_simple_file (mem, state); -mem_remove_simple_file (mem, phys_device); -mem_remove_simple_file (mem, removable); -unregister_memory (mem, section); + +if (atomic_dec_and_test (&mem->section_count)) { +unregister_mem_sect_under_nodes (mem); +mem_remove_simple_file (mem, phys_index); +mem_remove_simple_file (mem, end_phys_index); +mem_remove_simple_file (mem, state); +mem_remove_simple_file (mem, phys_device); +mem_remove_simple_file (mem, removable); +unregister_memory (mem, section); + }return 0 ; }
include/linux/memory.h +2 -0
@@ -19,11 +19,13 @@#include <linux/node.h> #include <linux/compiler.h> #include <linux/mutex.h> +#include <asm/atomic.h> struct memory_block {unsigned long start_phys_index;unsigned long end_phys_index;unsigned long state; +atomic_t section_count;/* * This serializes all state change requests. It isn't * held during creation because the control files are
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 3/9] v4 Add section count to memory_block
Quoted 6 lines · On Tue, 03 Aug 2010 08:38:37 -0500 Nathan Fontenot <[email protected]> wrote:
Add a section count property to the
memory_blockstruct to track the number of memory sections that have been added/removed from a memory block. This allows us to know when the last memory section of a memory block has been removed so we can remove the memory block.Signed-off-by Nathan Fontenot <[email protected]>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 4/9 v4 Add mutex for add/remove of memory blocks
In reply to Nathan FontenotAdd a new mutex for use in adding and removing of memory blocks. This is needed to avoid any race conditions in which the same memory block could be added and removed at the same time.
--- drivers/base/memory.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/base/memory.c +9 -0
@@ -27,6 +27,8 @@#include <asm/atomic.h> #include <asm/uaccess.h> +static struct mutex mem_sysfs_mutex; +#define MEMORY_CLASS_NAME "memory"static struct sysdev_class memory_sysdev_class = {
@@ -485,6 +487,8 @@ static int add_memory_block(int nid, strif (!mem)return -ENOMEM ; +mutex_lock (&mem_sysfs_mutex); + mem->start_phys_index =__section_nr (section); mem->state = state;atomic_inc (&mem->section_count);
@@ -508,6 +512,7 @@ static int add_memory_block(int nid, str ret =register_mem_sect_under_node (mem, nid); } +mutex_unlock (&mem_sysfs_mutex);return ret; }
@@ -516,6 +521,7 @@ int remove_memory_block(unsigned long no {struct memory_block *mem; +mutex_lock (&mem_sysfs_mutex); mem =find_memory_block (section);if (atomic_dec_and_test (&mem->section_count)) {
@@ -528,6 +534,7 @@ int remove_memory_block(unsigned long nounregister_memory (mem, section); } +mutex_unlock (&mem_sysfs_mutex);return 0 ; }
@@ -562,6 +569,8 @@ int __init memory_dev_init(void)if (ret) goto out; +mutex_init (&mem_sysfs_mutex); +/* * Create entries for memory sections that were found * during boot and have been initialized
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 4/9] v4 Add mutex for add/remove of memory blocks
Quoted 5 lines · On Tue, 03 Aug 2010 08:39:50 -0500 Nathan Fontenot <[email protected]> wrote:
Add a new mutex for use in adding and removing of memory blocks. This is needed to avoid any race conditions in which the same memory block could be added and removed at the same time.
Signed-off-by Nathan Fontenot <[email protected]>
But a nitpick (see below)
Quoted 9 lines
--- drivers/base/memory.c | 9 +++++++++ 1 file changed, 9 insertions(+)Index:
linux-2.6/drivers/base/memory.c
===================================================================
drivers/base/memory.c line 31
Quoted 5 lines
drivers/base/memory.c +2
-0@@ -27,6 +27,8 @@#include <asm/atomic.h> #include <asm/uaccess.h> +static struct mutex mem_sysfs_mutex; +
For static symbol of mutex, we usually do
static DEFINE_MUTEX(mem_sysfs_mutex);
Then, extra calls of mutex_init() is not required.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 4/9] v4 Add mutex for add/remove of memory blocks
Quoted 25 lines · KAMEZAWA Hiroyuki
Quoted 5 lines · On Tue, 03 Aug 2010 08:39:50 -0500 Nathan Fontenot <[email protected]> wrote:
Add a new mutex for use in adding and removing of memory blocks. This is needed to avoid any race conditions in which the same memory block could be added and removed at the same time.
Signed-off-by Nathan Fontenot <[email protected]>But a nitpick (see below)
Quoted 12 lines
--- drivers/base/memory.c | 9 +++++++++ 1 file changed, 9 insertions(+)Index:
linux-2.6/drivers/base/memory.c
===================================================================drivers/base/memory.c +0
-0@@ -27,6 +27,8 @@#include <asm/atomic.h> #include <asm/uaccess.h>
Quoted 8 lines
drivers/base/memory.c line 31
Quoted 2 lines
drivers/base/memory.c +2
-0+static struct mutex mem_sysfs_mutex; +For static symbol of mutex, we usually do
static DEFINE_MUTEX(mem_sysfs_mutex);Then, extra calls of
mutex_init()is not required.
ok, fixed in the next version of the patches.
-Nathan
PATCH 5/9 v4 Allow memory_block to span multiple memory sections
In reply to Nathan FontenotUpdate 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.
--- drivers/base/memory.c | 148 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 103 insertions(+), 45 deletions(-)
drivers/base/memory.c +103 -45
@@ -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(sstatic 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_blockcontinue ;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" , - __func__, mem, action, action); +WARN (1 ,KERN_WARNING "%s(%ld, %ld) unknown action: " +"%ld\n" , __func__, phys_index, action, action); ret = -EINVAL ; }
@@ -248,7 +250,7 @@ memory_block_action(struct memory_blockstatic int memory_block_change_state (struct memory_block *mem,unsigned long to_state,unsigned long from_state_req) { -int ret =0 ; +int i, ret =0 ;mutex_lock (&mem->state_mutex);if (mem->state != from_state_req) {
@@ -256,8 +258,21 @@ static int memory_block_change_state(str goto out; } - ret =memory_block_action (mem, to_state); -if (!ret) +if (to_state ==MEM_OFFLINE ) + mem->state =MEM_GOING_OFFLINE ; + +for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) { + ret =memory_section_action (i, to_state); +if (ret) +break ; + } + +if (ret) { +for (i = mem->start_phys_index; i <= mem->end_phys_index; i++) +memory_section_action (i, from_state_req); + + mem->state = from_state_req; + }else mem->state = to_state; out:
@@ -270,20 +285,15 @@ store_mem_state(struct sys_device *dev, struct sysdev_attribute *attr, const char *buf, size_t count) { struct memory_block *mem; -unsigned int phys_section_nr;int ret = -EINVAL ; mem = container_of(dev, struct memory_block, sysdev); - phys_section_nr = mem->start_phys_index; - -if (!present_section_nr (phys_section_nr)) - goto out;if (!strncmp (buf,"online" ,min ((int )count,6 ))) ret =memory_block_change_state (mem,MEM_ONLINE ,MEM_OFFLINE );else if (!strncmp (buf,"offline" ,min ((int )count,7 ))) ret =memory_block_change_state (mem,MEM_OFFLINE ,MEM_ONLINE ); -out: +if (ret)return ret;return count;
@@ -460,12 +470,13 @@ struct memory_block *find_memory_block(sstruct sys_device *sysdev;struct memory_block *mem;char name[sizeof (MEMORY_CLASS_NAME ) +9 +1 ]; +int block_id =base_memory_block_id (__section_nr (section));/* * This only works because we know that section == sysdev->id * slightly redundant with sysdev_register() */ -sprintf (&name[0 ],"%s%d" ,MEMORY_CLASS_NAME ,__section_nr (section)); +sprintf (&name[0 ],"%s%d" ,MEMORY_CLASS_NAME , block_id); kobj =kset_find_obj (&memory_sysdev_class.kset, name);if (!kobj)
@@ -477,26 +488,26 @@ struct memory_block *find_memory_block(sreturn mem; } -static int add_memory_block (int nid,struct mem_section *section, -unsigned long state,enum mem_add_context context) +static int init_memory_block (struct memory_block **memory, +struct mem_section *section,unsigned long state) { -struct memory_block *mem =kzalloc (sizeof (*mem),GFP_KERNEL ); +struct memory_block *mem;unsigned long start_pfn;int ret =0 ; + mem =kzalloc (sizeof (*mem),GFP_KERNEL );if (!mem)return -ENOMEM ; -mutex_lock (&mem_sysfs_mutex); - - mem->start_phys_index =__section_nr (section); + mem->start_phys_index =base_memory_block_id (__section_nr (section)); + mem->end_phys_index = mem->start_phys_index + sections_per_block -1 ; mem->state = state;atomic_inc (&mem->section_count);mutex_init (&mem->state_mutex); start_pfn =section_nr_to_pfn (mem->start_phys_index); mem->phys_device =arch_get_memory_phys_device (start_pfn); - ret =register_memory (mem, section); + ret =register_memory (mem);if (!ret) ret =mem_create_simple_file (mem, phys_index);if (!ret)
@@ -507,8 +518,29 @@ static int add_memory_block(int nid, str ret =mem_create_simple_file (mem, phys_device);if (!ret) ret =mem_create_simple_file (mem, removable); + + *memory = mem; +return ret; +} + +static int add_memory_section (int nid,struct mem_section *section, +unsigned long state,enum mem_add_context context) +{ +struct memory_block *mem; +int ret =0 ; + +mutex_lock (&mem_sysfs_mutex); + + mem =find_memory_block (section); +if (mem) { +atomic_inc (&mem->section_count); +kobject_put (&mem->sysdev.kobj); + }else + ret =init_memory_block (&mem, section, state); +if (!ret) { -if (context ==HOTPLUG ) +if (context ==HOTPLUG && +atomic_read (&mem->section_count) == sections_per_block) ret =register_mem_sect_under_node (mem, nid); }
@@ -531,8 +563,10 @@ int remove_memory_block(unsigned long nomem_remove_simple_file (mem, state);mem_remove_simple_file (mem, phys_device);mem_remove_simple_file (mem, removable); -unregister_memory (mem, section); - } +unregister_memory (mem); +kfree (mem); + }else +kobject_put (&mem->sysdev.kobj);mutex_unlock (&mem_sysfs_mutex);return 0 ;
@@ -544,7 +578,7 @@ int remove_memory_block(unsigned long no*/ int register_new_memory (int nid,struct mem_section *section) { -return add_memory_block (nid, section,MEM_OFFLINE ,HOTPLUG ); +return add_memory_section (nid, section,MEM_OFFLINE ,HOTPLUG ); }int unregister_memory_section (struct mem_section *section)
@@ -555,6 +589,26 @@ int unregister_memory_section(struct memreturn remove_memory_block (0 , section,0 ); } +u32 __weak memory_block_size_bytes (void ) +{ +return MIN_MEMORY_BLOCK_SIZE ; +} + +static u32 get_memory_block_size (void ) +{ +u32 block_sz; + + block_sz =memory_block_size_bytes (); + +/* Validate blk_sz is a power of 2 and not less than section size */ +if ((block_sz & (block_sz -1 )) || (block_sz <MIN_MEMORY_BLOCK_SIZE )) { +WARN_ON (1 ); + block_sz =MIN_MEMORY_BLOCK_SIZE ; + } + +return block_sz; +} +/* * Initialize the sysfs support for memory devices... */
@@ -563,6 +617,7 @@ int __init memory_dev_init(void)unsigned int i;int ret;int err; +int block_sz; memory_sysdev_class.kset.uevent_ops = &memory_uevent_ops; ret =sysdev_class_register (&memory_sysdev_class);
@@ -571,6 +626,9 @@ int __init memory_dev_init(void)mutex_init (&mem_sysfs_mutex); + block_sz =get_memory_block_size (); + sections_per_block = block_sz /MIN_MEMORY_BLOCK_SIZE ; +/* * Create entries for memory sections that were found * during boot and have been initialized
@@ -578,8 +636,8 @@ int __init memory_dev_init(void)for (i =0 ; i <NR_MEM_SECTIONS ; i++) {if (!present_section_nr (i))continue ; - err =add_memory_block (0 ,__nr_to_section (i),MEM_ONLINE , -BOOT ); + err =add_memory_section (0 ,__nr_to_section (i),MEM_ONLINE , +BOOT );if (!ret) ret = err; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 5/9] v4 Allow memory_block to span multiple memory sections
Quoted 11 lines · On Tue, 03 Aug 2010 08:40:49 -0500 Nathan Fontenot <[email protected]> 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_BITSto 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 <[email protected]>
(But maybe it's better to get ppc guy's Ack.)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 6/9 v4 Update the find_memory_block declaration
In reply to Nathan FontenotUpdate the find_memory_block declaration to to take a struct mem_section * so that it matches the definition.
--- include/linux/memory.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
include/linux/memory.h +1 -1
@@ -116,7 +116,7 @@ extern int memory_dev_init(void);extern int remove_memory_block (unsigned long ,struct mem_section *,int );extern int memory_notify (unsigned long val,void *v);extern int memory_isolate_notify (unsigned long val,void *v); -extern struct memory_block *find_memory_block (unsigned long ); +extern struct memory_block *find_memory_block (struct mem_section *);extern int memory_is_hidden (struct mem_section *);#define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT)enum mem_add_context {BOOT ,HOTPLUG };
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 6/9] v4 Update the find_memory_block declaration
Quoted 4 lines · On Tue, 03 Aug 2010 08:41:45 -0500 Nathan Fontenot <[email protected]> wrote:
Update the
find_memory_blockdeclaration to to take a structmem_section* so that it matches the definition.Signed-off-by Nathan Fontenot <[email protected]>
Hmm...my mmotm-0727 has this definition in memory.h...
extern struct memory_block *find_memory_block(struct mem_section *);
What patch makes it unsigned long ?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 6/9] v4 Update the find_memory_block declaration
Quoted 8 lines · KAMEZAWA Hiroyuki
Quoted 4 lines · On Tue, 03 Aug 2010 08:41:45 -0500 Nathan Fontenot <[email protected]> wrote:
Update the
find_memory_blockdeclaration to to take a structmem_section* so that it matches the definition.Signed-off-by Nathan Fontenot <[email protected]>
Quoted 8 lines
Hmm...my mmotm-0727 has this definition in
memory.h...extern struct
memory_block*find_memory_block(structmem_section*);What patch makes it unsigned long ?
I was basing the patches on the latest mainline tree. Looks like can drop this patch in the next version of the patchset.
-Nathan
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 7/9 v4 Update the node sysfs code
In reply to Nathan FontenotUpdate the node sysfs code to be aware of the new capability for a memory block to contain multiple memory sections. This requires an additional parameter to unregister_mem_sect_under_nodes so that we know which memory section of the memory block to unregister.
--- drivers/base/memory.c | 2 +- drivers/base/node.c | 12 ++++++++---- include/linux/node.h | 6 ++++-- 3 files changed, 13 insertions(+), 7 deletions(-)
drivers/base/node.c +8 -4
@@ -346,8 +346,10 @@ int register_mem_sect_under_node(structreturn -EFAULT ;if (!node_online (nid))return 0 ; - sect_start_pfn =section_nr_to_pfn (mem_blk->phys_index); - sect_end_pfn = sect_start_pfn +PAGES_PER_SECTION -1 ; + + sect_start_pfn =section_nr_to_pfn (mem_blk->start_phys_index); + sect_end_pfn =section_nr_to_pfn (mem_blk->end_phys_index); + sect_end_pfn +=PAGES_PER_SECTION -1 ;for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {int page_nid;
@@ -371,7 +373,8 @@ int register_mem_sect_under_node(struct }/* unregister memory section under all nodes that it spans */ -int unregister_mem_sect_under_nodes (struct memory_block *mem_blk) +int unregister_mem_sect_under_nodes (struct memory_block *mem_blk, +unsigned long phys_index) {NODEMASK_ALLOC (nodemask_t, unlinked_nodes,GFP_KERNEL );unsigned long pfn, sect_start_pfn, sect_end_pfn;
@@ -383,7 +386,8 @@ int unregister_mem_sect_under_nodes(struif (!unlinked_nodes)return -ENOMEM ;nodes_clear (*unlinked_nodes); - sect_start_pfn =section_nr_to_pfn (mem_blk->phys_index); + + sect_start_pfn =section_nr_to_pfn (phys_index); sect_end_pfn = sect_start_pfn +PAGES_PER_SECTION -1 ;for (pfn = sect_start_pfn; pfn <= sect_end_pfn; pfn++) {int nid;
drivers/base/memory.c +1 -1
@@ -555,9 +555,9 @@ int remove_memory_block(unsigned long nomutex_lock (&mem_sysfs_mutex); mem =find_memory_block (section); +unregister_mem_sect_under_nodes (mem,__section_nr (section));if (atomic_dec_and_test (&mem->section_count)) { -unregister_mem_sect_under_nodes (mem);mem_remove_simple_file (mem, phys_index);mem_remove_simple_file (mem, end_phys_index);mem_remove_simple_file (mem, state);
include/linux/node.h +4 -2
@@ -44,7 +44,8 @@ extern int register_cpu_under_node(unsigextern int unregister_cpu_under_node (unsigned int cpu,unsigned int nid);extern int register_mem_sect_under_node (struct memory_block *mem_blk,int nid); -extern int unregister_mem_sect_under_nodes (struct memory_block *mem_blk); +extern int unregister_mem_sect_under_nodes (struct memory_block *mem_blk, +unsigned long phys_index);#ifdef CONFIG_HUGETLBFS extern void register_hugetlbfs_with_node(node_registration_func_t doregister,
@@ -72,7 +73,8 @@ static inline int register_mem_sect_unde {return 0 ; } -static inline int unregister_mem_sect_under_nodes (struct memory_block *mem_blk) +static inline int unregister_mem_sect_under_nodes (struct memory_block *mem_blk, +unsigned long phys_index) {return 0 ; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 7/9] v4 Update the node sysfs code
Quoted 6 lines · On Tue, 03 Aug 2010 08:42:35 -0500 Nathan Fontenot <[email protected]> wrote:
Update the node sysfs code to be aware of the new capability for a memory block to contain multiple memory sections. This requires an additional parameter to
unregister_mem_sect_under_nodesso that we know which memory section of the memory block to unregister.Signed-off-by Nathan Fontenot <[email protected]>
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 8/9 v4 Define memory_block_size_bytes() for ppc/pseries
In reply to Nathan FontenotDefine a version of memory_block_size_bytes() for powerpc/pseries such that a memory block spans an entire lmb.
--- arch/powerpc/platforms/pseries/hotplug-memory.c | 66 +++++++++++++++++++----- 1 file changed, 53 insertions(+), 13 deletions(-)
arch/powerpc/platforms/pseries/hotplug-memory.c +53 -13
@@ -17,6 +17,54 @@#include <asm/pSeries_reconfig.h> #include <asm/sparsemem.h> +static u32 get_memblock_size (void ) +{ +struct device_node *np; +unsigned int memblock_size =0 ; + + np =of_find_node_by_path ("/ibm,dynamic-reconfiguration-memory" ); +if (np) { +const unsigned long *size; + + size =of_get_property (np,"ibm,lmb-size" ,NULL ); + memblock_size = size ? *size :0 ; + +of_node_put (np); + }else { +unsigned int memzero_size =0 ; +const unsigned int *regs; + + np =of_find_node_by_path ("/memory@0" ); +if (np) { + regs =of_get_property (np,"reg" ,NULL ); + memzero_size = regs ? regs[3 ] :0 ; +of_node_put (np); + } + +if (memzero_size) { +/* We now know the size of memory@0, use this to find +* the first memoryblock and get its size. +*/ +char buf[64 ]; + +sprintf (buf,"/memory@%x" , memzero_size); + np =of_find_node_by_path (buf); +if (np) { + regs =of_get_property (np,"reg" ,NULL ); + memblock_size = regs ? regs[3 ] :0 ; +of_node_put (np); + } + } + } + +return memblock_size; +} + +u32 memory_block_size_bytes (void ) +{ +return get_memblock_size (); +} +static int pseries_remove_memblock (unsigned long base,unsigned int memblock_size) {unsigned long start, start_pfn;
@@ -127,30 +175,22 @@ static int pseries_add_memory(struct devstatic int pseries_drconf_memory (unsigned long *base,unsigned int action) { -struct device_node *np; -const unsigned long *lmb_size; +unsigned long memblock_size;int rc; - np =of_find_node_by_path ("/ibm,dynamic-reconfiguration-memory" ); -if (!np) + memblock_size =get_memblock_size (); +if (!memblock_size)return -EINVAL ; - lmb_size =of_get_property (np,"ibm,lmb-size" ,NULL ); -if (!lmb_size) { -of_node_put (np); -return -EINVAL ; - } -if (action ==PSERIES_DRCONF_MEM_ADD ) { - rc =memblock_add (*base, *lmb_size); + rc =memblock_add (*base, memblock_size); rc = (rc <0 ) ? -EINVAL :0 ; }else if (action ==PSERIES_DRCONF_MEM_REMOVE ) { - rc =pseries_remove_memblock (*base, *lmb_size); + rc =pseries_remove_memblock (*base, memblock_size); }else { rc = -EINVAL ; } -of_node_put (np);return rc; }
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 9/9 v4 Update memory-hotplug documentation
In reply to Nathan FontenotUpdate the memory hotplug documentation to reflect the new behaviors of memory blocks reflected in sysfs.
--- Documentation/memory-hotplug.txt | 40 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-)
Documentation/memory-hotplug.txt +24 -16
@@ -126,36 +126,44 @@ config options. -------------------------------- 4 sysfs files for memory hotplug -------------------------------- -All sections have their device information under /sys/devices/system/memory as +All sections have their device information in sysfs. Each section is part of +a memory block under /sys/devices/system/memory as /sys/devices/system/memory/memoryXXX -(XXX is section id.) +(XXX is the section id.) -Now, XXX is defined as start_address_of_section / section_size. +Now, XXX is defined as (start_address_of_section / section_size) of the first +section contained in the memory block. For example, assume 1GiB section size. A device for a memory starting at 0x100000000 is /sys/device/system/memory/memory4 (0x100000000 / 1Gib = 4) This device covers address range [0x100000000 ... 0x140000000) -Under each section, you can see 4 files. +Under each section, you can see 5 files. -/sys/devices/system/memory/memoryXXX/phys_index +/sys/devices/system/memory/memoryXXX/start_phys_index +/sys/devices/system/memory/memoryXXX/end_phys_index /sys/devices/system/memory/memoryXXX/phys_device /sys/devices/system/memory/memoryXXX/state /sys/devices/system/memory/memoryXXX/removable -'phys_index' : read-only and contains section id, same as XXX. -'state' : read-write - at read: contains online/offline state of memory. - at write: user can specify "online", "offline" command -'phys_device': read-only: designed to show the name of physical memory device. - This is not well implemented now. -'removable' : read-only: contains an integer value indicating - whether the memory section is removable or not - removable. A value of 1 indicates that the memory - section is removable and a value of 0 indicates that - it is not removable. +'phys_index' : read-only and contains section id of the first section + in the memory block, same as XXX. +'end_phys_index' : read-only and contains section id of the last section + in the memory block. +'state' : read-write + at read: contains online/offline state of memory. + at write: user can specify "online", "offline" command + which will be performed on al sections in the block. +'phys_device' : read-only: designed to show the name of physical memory + device. This is not well implemented now. +'removable' : read-only: contains an integer value indicating + whether the memory block is removable or not + removable. A value of 1 indicates that the memory + block is removable and a value of 0 indicates that + it is not removable. A memory block is removable only if + every section in the block is removable. NOTE: These directories/files appear after physical memory hotplug phase.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [PATCH 9/9] v4 Update memory-hotplug documentation
Quoted 4 lines · On Tue, 03 Aug 2010 08:44:16 -0500 Nathan Fontenot <[email protected]> wrote:
Update the memory hotplug documentation to reflect the new behaviors of memory blocks reflected in sysfs.
Signed-off-by Nathan Fontenot <[email protected]>
A request from me:
Could you clarify what happens if there are memory hole in [start end)_phys_index. in Documentation ? (Or add TODO list.)
Thanks,
-Kame
Quoted 72 lines
--- Documentation/memory-hotplug.txt | 40 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-)Index:
linux-2.6/Documentation/memory-hotplug.txt
===================================================================Documentation/memory-hotplug.txt +24
-17@@ -126,36 +126,44 @@ config options. -------------------------------- 4 sysfs files for memory hotplug -------------------------------- -All sections have their device information under /sys/devices/system/memory as +All sections have their device information in sysfs. Each section is part of +a memory block under /sys/devices/system/memory as /sys/devices/system/memory/memoryXXX -(XXX is section id.) +(XXX is the section id.) -Now, XXX is defined as start_address_of_section / section_size. +Now, XXX is defined as (start_address_of_section / section_size) of the first +section contained in the memory block. For example, assume 1GiB section size. A device for a memory starting at 0x100000000 is /sys/device/system/memory/memory4 (0x100000000 / 1Gib = 4) This device covers address range [0x100000000 ... 0x140000000) -Under each section, you can see 4 files. +Under each section, you can see 5 files. -/sys/devices/system/memory/memoryXXX/phys_index +/sys/devices/system/memory/memoryXXX/start_phys_index +/sys/devices/system/memory/memoryXXX/end_phys_index /sys/devices/system/memory/memoryXXX/phys_device /sys/devices/system/memory/memoryXXX/state /sys/devices/system/memory/memoryXXX/removable -'phys_index' : read-only and contains section id, same as XXX. -'state' : read-write - at read: contains online/offline state of memory. - at write: user can specify "online", "offline" command -'phys_device': read-only: designed to show the name of physical memory device. - This is not well implemented now. -'removable' : read-only: contains an integer value indicating - whether the memory section is removable or not - removable. A value of 1 indicates that the memory - section is removable and a value of 0 indicates that - it is not removable. +'phys_index' : read-only and contains section id of the first section + in the memory block, same as XXX. +'end_phys_index' : read-only and contains section id of the last section + in the memory block. +'state' : read-write + at read: contains online/offline state of memory. + at write: user can specify "online", "offline" command + which will be performed on al sections in the block. +'phys_device' : read-only: designed to show the name of physical memory + device. This is not well implemented now. +'removable' : read-only: contains an integer value indicating + whether the memory block is removable or not + removable. A value of 1 indicates that the memory + block is removable and a value of 0 indicates that + it is not removable. A memory block is removable only if + every section in the block is removable. NOTE: These directories/files appear after physical memory hotplug phase. --
Quoted 5 lines
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>