Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d96ae530 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds
Browse files

memory-hotplug: create /sys/firmware/memmap entry for new memory



A memmap is a directory in sysfs which includes 3 text files: start, end
and type.  For example:

start: 	0x100000
end:	0x7e7b1cff
type:	System RAM

Interface firmware_map_add was not called explicitly.  Remove it and add
function firmware_map_add_hotplug as hotplug interface of memmap.

Each memory entry has a memmap in sysfs, When we hot-add new memory, sysfs
does not export memmap entry for it.  We add a call in function add_memory
to function firmware_map_add_hotplug.

Add a new function add_sysfs_fw_map_entry() to create memmap entry, it
will be called when initialize memmap and hot-add memory.

[akpm@linux-foundation.org: un-kernedoc a no longer kerneldoc comment]
Signed-off-by: default avatarShaohui Zheng <shaohui.zheng@intel.com>
Acked-by: default avatarAndi Kleen <ak@linux.intel.com>
Acked-by: default avatarYasunori Goto <y-goto@jp.fujitsu.com>
Reviewed-by: default avatarWu Fengguang <fengguang.wu@intel.com>
Cc: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 9d8cebd4
Loading
Loading
Loading
Loading
+36 −21
Original line number Diff line number Diff line
@@ -122,29 +122,53 @@ static int firmware_map_add_entry(u64 start, u64 end,
	return 0;
}

/*
 * Add memmap entry on sysfs
 */
static int add_sysfs_fw_map_entry(struct firmware_map_entry *entry)
{
	static int map_entries_nr;
	static struct kset *mmap_kset;

	if (!mmap_kset) {
		mmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
		if (!mmap_kset)
			return -ENOMEM;
	}

	entry->kobj.kset = mmap_kset;
	if (kobject_add(&entry->kobj, NULL, "%d", map_entries_nr++))
		kobject_put(&entry->kobj);

	return 0;
}

/**
 * firmware_map_add() - Adds a firmware mapping entry.
 * firmware_map_add_hotplug() - Adds a firmware mapping entry when we do
 * memory hotplug.
 * @start: Start of the memory range.
 * @end:   End of the memory range (inclusive).
 * @type:  Type of the memory range.
 *
 * This function uses kmalloc() for memory
 * allocation. Use firmware_map_add_early() if you want to use the bootmem
 * allocator.
 *
 * That function must be called before late_initcall.
 * Adds a firmware mapping entry. This function is for memory hotplug, it is
 * similar to function firmware_map_add_early(). The only difference is that
 * it will create the syfs entry dynamically.
 *
 * Returns 0 on success, or -ENOMEM if no memory could be allocated.
 **/
int firmware_map_add(u64 start, u64 end, const char *type)
int __meminit firmware_map_add_hotplug(u64 start, u64 end, const char *type)
{
	struct firmware_map_entry *entry;

	entry = kmalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
	entry = kzalloc(sizeof(struct firmware_map_entry), GFP_ATOMIC);
	if (!entry)
		return -ENOMEM;

	return firmware_map_add_entry(start, end, type, entry);
	firmware_map_add_entry(start, end, type, entry);
	/* create the memmap entry */
	add_sysfs_fw_map_entry(entry);

	return 0;
}

/**
@@ -154,7 +178,7 @@ int firmware_map_add(u64 start, u64 end, const char *type)
 * @type:  Type of the memory range.
 *
 * Adds a firmware mapping entry. This function uses the bootmem allocator
 * for memory allocation. Use firmware_map_add() if you want to use kmalloc().
 * for memory allocation.
 *
 * That function must be called before late_initcall.
 *
@@ -214,19 +238,10 @@ static ssize_t memmap_attr_show(struct kobject *kobj,
 */
static int __init memmap_init(void)
{
	int i = 0;
	struct firmware_map_entry *entry;
	struct kset *memmap_kset;

	memmap_kset = kset_create_and_add("memmap", NULL, firmware_kobj);
	if (WARN_ON(!memmap_kset))
		return -ENOMEM;

	list_for_each_entry(entry, &map_entries, list) {
		entry->kobj.kset = memmap_kset;
		if (kobject_add(&entry->kobj, NULL, "%d", i++))
			kobject_put(&entry->kobj);
	}
	list_for_each_entry(entry, &map_entries, list)
		add_sysfs_fw_map_entry(entry);

	return 0;
}
+3 −3
Original line number Diff line number Diff line
@@ -24,17 +24,17 @@
 */
#ifdef CONFIG_FIRMWARE_MEMMAP

int firmware_map_add(u64 start, u64 end, const char *type);
int firmware_map_add_early(u64 start, u64 end, const char *type);
int firmware_map_add_hotplug(u64 start, u64 end, const char *type);

#else /* CONFIG_FIRMWARE_MEMMAP */

static inline int firmware_map_add(u64 start, u64 end, const char *type)
static inline int firmware_map_add_early(u64 start, u64 end, const char *type)
{
	return 0;
}

static inline int firmware_map_add_early(u64 start, u64 end, const char *type)
static inline int firmware_map_add_hotplug(u64 start, u64 end, const char *type)
{
	return 0;
}
+4 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/pfn.h>
#include <linux/suspend.h>
#include <linux/mm_inline.h>
#include <linux/firmware-map.h>

#include <asm/tlbflush.h>

@@ -523,6 +524,9 @@ int __ref add_memory(int nid, u64 start, u64 size)
		BUG_ON(ret);
	}

	/* create new memmap entry */
	firmware_map_add_hotplug(start, start + size, "System RAM");

	goto out;

error: