From: Tang Chen <tangchen@cn.fujitsu.com>
To: rjw@sisk.pl, lenb@kernel.org, tglx@linutronix.de, mingo@elte.hu,
hpa@zytor.com, akpm@linux-foundation.org, tj@kernel.org,
trenn@suse.de, yinghai@kernel.org, jiang.liu@huawei.com,
wency@cn.fujitsu.com, laijs@cn.fujitsu.com,
isimatu.yasuaki@jp.fujitsu.com, izumi.taku@jp.fujitsu.com,
mgorman@suse.de, minchan@kernel.org, mina86@mina86.com,
gong.chen@linux.intel.com, vasilis.liaskovitis@profitbricks.com,
lwoodman@redhat.com, riel@redhat.com, jweiner@redhat.com,
prarit@redhat.com, zhangyanfei@cn.fujitsu.com,
yanghy@cn.fujitsu.com
Cc: x86@kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
linux-acpi@vger.kernel.org
Subject: [PATCH v2 12/18] x86, acpi, numa, mem_hotplug: Find hotpluggable memory in SRAT memory affinities.
Date: Thu, 1 Aug 2013 15:06:34 +0800 [thread overview]
Message-ID: <1375340800-19332-13-git-send-email-tangchen@cn.fujitsu.com> (raw)
In-Reply-To: <1375340800-19332-1-git-send-email-tangchen@cn.fujitsu.com>
In ACPI SRAT(System Resource Affinity Table), there is a memory affinity for each
memory range in the system. In each memory affinity, there is a field indicating
that if the memory range is hotpluggable.
This patch parses all the memory affinities in SRAT only, and find out all the
hotpluggable memory ranges in the system.
This patch doesn't mark hotpluggable memory in memblock. Memory marked as hotplug
won't be allocated to the kernel. If all the memory in the system is hotpluggable,
then the system won't have enough memory to boot. The basic idea to solve this
problem is making the nodes the kerenl resides in unhotpluggable. So, before we do
this, we don't mark any hotpluggable memory in memory so that to keep memblock
working as before.
Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
Reviewed-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
---
drivers/acpi/osl.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/acpi.h | 2 +
mm/memory_hotplug.c | 22 ++++++++++++-
3 files changed, 107 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 319a274..5063574 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -777,6 +777,91 @@ phys_addr_t __init early_acpi_firmware_srat(void)
return table_desc.address;
}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_hotplug_mem_affinity
+ *
+ * PARAMETERS: Srat_vaddr - Virt addr of SRAT
+ * Base - The base address of the found hotpluggable
+ * memory region
+ * Size - The size of the found hotpluggable memory
+ * region
+ * Offset - Offset of the found memory affinity
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: This function iterates SRAT affinities list to find memory
+ * affinities with hotpluggable memory one by one. Return the
+ * offset of the found memory affinity through @offset. @offset
+ * can be used to iterate the SRAT affinities list to find all the
+ * hotpluggable memory affinities. If @offset is 0, it is the first
+ * time of the iteration.
+ *
+ ******************************************************************************/
+acpi_status __init
+acpi_hotplug_mem_affinity(void *srat_vaddr, u64 *base, u64 *size,
+ unsigned long *offset)
+{
+ struct acpi_table_header *table_header;
+ struct acpi_subtable_header *entry;
+ struct acpi_srat_mem_affinity *ma;
+ unsigned long table_end, curr;
+
+ if (!offset)
+ return_ACPI_STATUS(AE_BAD_PARAMETER);
+
+ table_header = (struct acpi_table_header *)srat_vaddr;
+ table_end = (unsigned long)table_header + table_header->length;
+
+ entry = (struct acpi_subtable_header *)
+ ((unsigned long)table_header + *offset);
+
+ if (*offset) {
+ /*
+ * @offset is the offset of the last affinity found in the
+ * last call. So need to move to the next affinity.
+ */
+ entry = (struct acpi_subtable_header *)
+ ((unsigned long)entry + entry->length);
+ } else {
+ /*
+ * Offset of the first affinity is the size of SRAT
+ * table header.
+ */
+ entry = (struct acpi_subtable_header *)
+ ((unsigned long)entry + sizeof(struct acpi_table_srat));
+ }
+
+ while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
+ table_end) {
+ if (entry->length == 0)
+ break;
+
+ if (entry->type != ACPI_SRAT_TYPE_MEMORY_AFFINITY)
+ goto next;
+
+ ma = (struct acpi_srat_mem_affinity *)entry;
+
+ if (!(ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE))
+ goto next;
+
+ if (base)
+ *base = ma->base_address;
+
+ if (size)
+ *size = ma->length;
+
+ *offset = (unsigned long)entry - (unsigned long)srat_vaddr;
+ return_ACPI_STATUS(AE_OK);
+
+next:
+ entry = (struct acpi_subtable_header *)
+ ((unsigned long)entry + entry->length);
+ }
+
+ return_ACPI_STATUS(AE_NOT_FOUND);
+}
#endif /* CONFIG_ACPI_NUMA */
static void acpi_table_taint(struct acpi_table_header *table)
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 6fa7543..06f6e15 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -99,6 +99,8 @@ static inline phys_addr_t early_acpi_override_srat(void)
#ifdef CONFIG_ACPI_NUMA
phys_addr_t early_acpi_firmware_srat(void);
+acpi_status acpi_hotplug_mem_affinity(void *srat_vaddr, u64 *base,
+ u64 *size, unsigned long *offset);
#endif /* CONFIG_ACPI_NUMA */
char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index 4ccffe6..326e2f2 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -103,7 +103,11 @@ static void release_memory_resource(struct resource *res)
*/
void __init find_hotpluggable_memory(void)
{
- phys_addr_t srat_paddr;
+ void *srat_vaddr;
+ phys_addr_t srat_paddr, base, size;
+ u32 length;
+ struct acpi_table_header *srat_header;
+ unsigned long offset = 0;
/* Try to find if SRAT is overridden */
srat_paddr = early_acpi_override_srat();
@@ -114,7 +118,21 @@ void __init find_hotpluggable_memory(void)
return;
}
- /* Will parse SRAT and find out hotpluggable memory here */
+ /* Get the length of SRAT */
+ srat_header = early_ioremap(srat_paddr,
+ sizeof(struct acpi_table_header));
+ length = srat_header->length;
+ early_iounmap(srat_header, sizeof(struct acpi_table_header));
+
+ /* Find all the hotpluggable memory regions */
+ srat_vaddr = early_ioremap(srat_paddr, length);
+
+ while (ACPI_SUCCESS(acpi_hotplug_mem_affinity(srat_vaddr, &base,
+ &size, &offset))) {
+ /* Will mark hotpluggable memory regions here */
+ }
+
+ early_iounmap(srat_vaddr, length);
}
#endif /* CONFIG_ACPI_NUMA */
--
1.7.1
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
next prev parent reply other threads:[~2013-08-01 7:08 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-01 7:06 [PATCH v2 00/18] Arrange hotpluggable memory as ZONE_MOVABLE Tang Chen
2013-08-01 7:06 ` [PATCH v2 01/18] acpi: Print Hot-Pluggable Field in SRAT Tang Chen
2013-08-01 21:55 ` Toshi Kani
2013-08-01 7:06 ` [PATCH v2 02/18] earlycpio.c: Fix the confusing comment of find_cpio_data() Tang Chen
2013-08-01 21:57 ` Toshi Kani
2013-08-02 4:48 ` Tang Chen
2013-08-01 7:06 ` [PATCH v2 03/18] acpi: Remove "continue" in macro INVALID_TABLE() Tang Chen
2013-08-01 20:26 ` Rafael J. Wysocki
2013-08-01 22:06 ` Toshi Kani
2013-08-02 1:32 ` Tang Chen
2013-08-01 7:06 ` [PATCH v2 04/18] acpi: Introduce acpi_invalid_table() to check if a table is invalid Tang Chen
2013-08-01 20:27 ` Rafael J. Wysocki
2013-08-01 22:26 ` Toshi Kani
2013-08-02 1:34 ` Tang Chen
2013-08-01 7:06 ` [PATCH v2 05/18] x86, acpi: Split acpi_boot_table_init() into two parts Tang Chen
2013-08-01 23:32 ` Toshi Kani
2013-08-02 5:25 ` Zheng, Lv
2013-08-02 7:01 ` Tang Chen
2013-08-02 8:11 ` Zheng, Lv
2013-08-02 8:23 ` Zheng, Lv
2013-08-02 8:29 ` Tang Chen
2013-08-02 8:54 ` Zheng, Lv
2013-08-02 9:13 ` Tang Chen
2013-08-01 7:06 ` [PATCH v2 06/18] x86, acpi: Initialize ACPI root table list earlier Tang Chen
2013-08-01 23:54 ` Toshi Kani
2013-08-02 7:49 ` Tang Chen
2013-08-02 16:57 ` Toshi Kani
2013-08-01 7:06 ` [PATCH v2 07/18] x86, acpi: Also initialize signature and length when parsing root table Tang Chen
2013-08-02 0:10 ` Toshi Kani
2013-08-02 5:28 ` Zheng, Lv
2013-08-01 7:06 ` [PATCH v2 08/18] x86: get pg_data_t's memory from other node Tang Chen
2013-08-02 0:23 ` Toshi Kani
2013-08-01 7:06 ` [PATCH v2 09/18] x86: Make get_ramdisk_{image|size}() global Tang Chen
2013-08-01 7:06 ` [PATCH v2 10/18] x86, acpi: Try to find if SRAT is overrided earlier Tang Chen
2013-08-02 1:19 ` Toshi Kani
2013-08-02 5:49 ` Tang Chen
2013-08-02 16:05 ` Toshi Kani
2013-08-01 7:06 ` [PATCH v2 11/18] x86, acpi: Try to find SRAT in firmware earlier Tang Chen
2013-08-01 7:06 ` Tang Chen [this message]
2013-08-01 7:06 ` [PATCH v2 13/18] x86, numa, mem_hotplug: Skip all the regions the kernel resides in Tang Chen
2013-08-01 13:42 ` Tejun Heo
2013-08-02 5:51 ` Tang Chen
2013-08-01 7:06 ` [PATCH v2 14/18] memblock, numa: Introduce flag into memblock Tang Chen
2013-08-01 7:06 ` [PATCH v2 15/18] memblock, mem_hotplug: Introduce MEMBLOCK_HOTPLUG flag to mark hotpluggable regions Tang Chen
2013-08-01 7:06 ` [PATCH v2 16/18] memblock, mem_hotplug: Make memblock skip hotpluggable regions by default Tang Chen
2013-08-01 7:06 ` [PATCH v2 17/18] mem-hotplug: Introduce movablenode boot option to {en|dis}able using SRAT Tang Chen
2013-08-01 7:06 ` [PATCH v2 18/18] x86, numa, acpi, memory-hotplug: Make movablenode have higher priority Tang Chen
2013-08-05 13:07 ` [PATCH v2 00/18] Arrange hotpluggable memory as ZONE_MOVABLE H. Peter Anvin
2013-08-05 13:38 ` Tang Chen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1375340800-19332-13-git-send-email-tangchen@cn.fujitsu.com \
--to=tangchen@cn.fujitsu.com \
--cc=akpm@linux-foundation.org \
--cc=gong.chen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=isimatu.yasuaki@jp.fujitsu.com \
--cc=izumi.taku@jp.fujitsu.com \
--cc=jiang.liu@huawei.com \
--cc=jweiner@redhat.com \
--cc=laijs@cn.fujitsu.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=lwoodman@redhat.com \
--cc=mgorman@suse.de \
--cc=mina86@mina86.com \
--cc=minchan@kernel.org \
--cc=mingo@elte.hu \
--cc=prarit@redhat.com \
--cc=riel@redhat.com \
--cc=rjw@sisk.pl \
--cc=tglx@linutronix.de \
--cc=tj@kernel.org \
--cc=trenn@suse.de \
--cc=vasilis.liaskovitis@profitbricks.com \
--cc=wency@cn.fujitsu.com \
--cc=x86@kernel.org \
--cc=yanghy@cn.fujitsu.com \
--cc=yinghai@kernel.org \
--cc=zhangyanfei@cn.fujitsu.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).