From: dennis.chen@arm.com (Dennis Chen)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] mm: memblock Add some new functions to address the mem limit issue
Date: Fri, 24 Jun 2016 10:28:28 +0800 [thread overview]
Message-ID: <20160624022826.GA12969@arm.com> (raw)
In-Reply-To: <20160623125748.GF8836@leverpostej>
On Thu, Jun 23, 2016 at 01:57:48PM +0100, Mark Rutland wrote:
> On Thu, Jun 23, 2016 at 07:30:14PM +0800, Dennis Chen wrote:
> > Two major changes in this patch:
> > [1] Add memblock_mem_limit_mark_nomap(phys_addr_t limit) function to
> > mark memblock regions above the @limit as NOMAP region, which will
> > be used to address the observed 'mem=x' kernel parameter issue.
> >
> > [2] Add 'size' and 'flag' debug output in the memblock debugfs.
> > The '/sys/kernel/debug/memblock/memory' output looks like before:
> > 0: 0x0000008000000000..0x0000008001e7ffff
> > 1: 0x0000008001e80000..0x00000083ff184fff
> > 2: 0x00000083ff185000..0x00000083ff1c2fff
> > 3: 0x00000083ff1c3000..0x00000083ff222fff
> > 4: 0x00000083ff223000..0x00000083ffe42fff
> > 5: 0x00000083ffe43000..0x00000083ffffffff
> >
> > With this patch applied:
> > 0: 0x0000008000000000..0x0000008001e7ffff 0x0000000001e80000 0x4
> > 1: 0x0000008001e80000..0x00000083ff184fff 0x00000003fd305000 0x0
> > 2: 0x00000083ff185000..0x00000083ff1c2fff 0x000000000003e000 0x4
> > 3: 0x00000083ff1c3000..0x00000083ff222fff 0x0000000000060000 0x0
> > 4: 0x00000083ff223000..0x00000083ffe42fff 0x0000000000c20000 0x4
> > 5: 0x00000083ffe43000..0x00000083ffffffff 0x00000000001bd000 0x0
>
> Please explain in the commit message what the problem being solved is,
> and how this solves it. e.g.
>
> In some cases, memblock is queried to determine whether a physical
> address corresponds to memory present in a system even if unused by the
> OS for the linear mapping, highmem, etc. For example, the ACPI core
> needs this information to determine which attributes to use when mapping
> ACPI regions. Use of incorrect memory types can result in faults, data
> corruption, or other issues.
>
> Removing memory with memblock_enforce_memory_limit throws away this
> information, and so a kernel booted with mem= may suffer from the issues
> described above. To avoid this, we can mark regions as nomap rather than
> removing them, which preserves the information we need while preventing
> other use of the regions.
>
> This patch adds new insfrastructure to mark all memblock regions in an
> address range as nomap, to cater for this. Similarly we add
> infrastructure to clear the flag for an address range, which makes
> handling some overlap cases simpler.
>
> Other than that, the patch itself looks fine to me.
>
The above commit message is very clear to describe why we need to add
those new infrastructures in this patch. Thanks Mark, you're saving
my time :) I will apply it in the next version.
Thanks,
Dennis
>
> Thanks,
> Mark.
>
> > Signed-off-by: Dennis Chen <dennis.chen@arm.com>
> > Cc: Catalin Marinas <catalin.marinas@arm.com>
> > Cc: Steve Capper <steve.capper@arm.com>
> > Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> > Cc: Will Deacon <will.deacon@arm.com>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > Cc: Matt Fleming <matt@codeblueprint.co.uk>
> > Cc: linux-mm at kvack.org
> > Cc: linux-acpi at vger.kernel.org
> > Cc: linux-efi at vger.kernel.org
> > ---
> > include/linux/memblock.h | 2 ++
> > mm/memblock.c | 50 ++++++++++++++++++++++++++++++++++++++++--------
> > 2 files changed, 44 insertions(+), 8 deletions(-)
> >
> > diff --git a/include/linux/memblock.h b/include/linux/memblock.h
> > index 6c14b61..5e069c8 100644
> > --- a/include/linux/memblock.h
> > +++ b/include/linux/memblock.h
> > @@ -92,6 +92,7 @@ int memblock_mark_hotplug(phys_addr_t base, phys_addr_t size);
> > int memblock_clear_hotplug(phys_addr_t base, phys_addr_t size);
> > int memblock_mark_mirror(phys_addr_t base, phys_addr_t size);
> > int memblock_mark_nomap(phys_addr_t base, phys_addr_t size);
> > +int memblock_clear_nomap(phys_addr_t base, phys_addr_t size);
> > ulong choose_memblock_flags(void);
> >
> > /* Low level functions */
> > @@ -332,6 +333,7 @@ phys_addr_t memblock_mem_size(unsigned long limit_pfn);
> > phys_addr_t memblock_start_of_DRAM(void);
> > phys_addr_t memblock_end_of_DRAM(void);
> > void memblock_enforce_memory_limit(phys_addr_t memory_limit);
> > +void memblock_mem_limit_mark_nomap(phys_addr_t limit);
> > bool memblock_is_memory(phys_addr_t addr);
> > int memblock_is_map_memory(phys_addr_t addr);
> > int memblock_is_region_memory(phys_addr_t base, phys_addr_t size);
> > diff --git a/mm/memblock.c b/mm/memblock.c
> > index ca09915..60930ac 100644
> > --- a/mm/memblock.c
> > +++ b/mm/memblock.c
> > @@ -814,6 +814,18 @@ int __init_memblock memblock_mark_nomap(phys_addr_t base, phys_addr_t size)
> > }
> >
> > /**
> > + * memblock_clear_nomap - Clear flag MEMBLOCK_NOMAP for a specified region.
> > + * @base: the base phys addr of the region
> > + * @size: the size of the region
> > + *
> > + * Return 0 on success, -errno on failure.
> > + */
> > +int __init_memblock memblock_clear_nomap(phys_addr_t base, phys_addr_t size)
> > +{
> > + return memblock_setclr_flag(base, size, 0, MEMBLOCK_NOMAP);
> > +}
> > +
> > +/**
> > * __next_reserved_mem_region - next function for for_each_reserved_region()
> > * @idx: pointer to u64 loop variable
> > * @out_start: ptr to phys_addr_t for start address of the region, can be %NULL
> > @@ -1465,14 +1477,11 @@ phys_addr_t __init_memblock memblock_end_of_DRAM(void)
> > return (memblock.memory.regions[idx].base + memblock.memory.regions[idx].size);
> > }
> >
> > -void __init memblock_enforce_memory_limit(phys_addr_t limit)
> > +static phys_addr_t __find_max_addr(phys_addr_t limit)
> > {
> > phys_addr_t max_addr = (phys_addr_t)ULLONG_MAX;
> > struct memblock_region *r;
> >
> > - if (!limit)
> > - return;
> > -
> > /* find out max address */
> > for_each_memblock(memory, r) {
> > if (limit <= r->size) {
> > @@ -1482,6 +1491,18 @@ void __init memblock_enforce_memory_limit(phys_addr_t limit)
> > limit -= r->size;
> > }
> >
> > + return max_addr;
> > +}
> > +
> > +void __init memblock_enforce_memory_limit(phys_addr_t limit)
> > +{
> > + phys_addr_t max_addr;
> > +
> > + if (!limit)
> > + return;
> > +
> > + max_addr = __find_max_addr(limit);
> > +
> > /* truncate both memory and reserved regions */
> > memblock_remove_range(&memblock.memory, max_addr,
> > (phys_addr_t)ULLONG_MAX);
> > @@ -1489,6 +1510,17 @@ void __init memblock_enforce_memory_limit(phys_addr_t limit)
> > (phys_addr_t)ULLONG_MAX);
> > }
> >
> > +void __init memblock_mem_limit_mark_nomap(phys_addr_t limit)
> > +{
> > + phys_addr_t max_addr;
> > +
> > + if (!limit)
> > + return;
> > +
> > + max_addr = __find_max_addr(limit);
> > + memblock_mark_nomap(max_addr, (phys_addr_t)ULLONG_MAX);
> > +}
> > +
> > static int __init_memblock memblock_search(struct memblock_type *type, phys_addr_t addr)
> > {
> > unsigned int left = 0, right = type->cnt;
> > @@ -1677,13 +1709,15 @@ static int memblock_debug_show(struct seq_file *m, void *private)
> > reg = &type->regions[i];
> > seq_printf(m, "%4d: ", i);
> > if (sizeof(phys_addr_t) == 4)
> > - seq_printf(m, "0x%08lx..0x%08lx\n",
> > + seq_printf(m, "0x%08lx..0x%08lx 0x%08lx 0x%lx\n",
> > (unsigned long)reg->base,
> > - (unsigned long)(reg->base + reg->size - 1));
> > + (unsigned long)(reg->base + reg->size - 1),
> > + (unsigned long)reg->size, reg->flags);
> > else
> > - seq_printf(m, "0x%016llx..0x%016llx\n",
> > + seq_printf(m, "0x%016llx..0x%016llx 0x%016llx 0x%lx\n",
> > (unsigned long long)reg->base,
> > - (unsigned long long)(reg->base + reg->size - 1));
> > + (unsigned long long)(reg->base + reg->size - 1),
> > + (unsigned long long)reg->size, reg->flags);
> >
> > }
> > return 0;
> > --
> > 1.8.3.1
> >
>
next prev parent reply other threads:[~2016-06-24 2:28 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-06-23 11:30 [PATCH 1/2] mm: memblock Add some new functions to address the mem limit issue Dennis Chen
2016-06-23 11:30 ` [PATCH 2/2] arm64:acpi Fix the acpi alignment exeception when 'mem=' specified Dennis Chen
2016-06-23 12:42 ` Mark Rutland
2016-06-24 2:31 ` Dennis Chen
2016-06-23 12:57 ` [PATCH 1/2] mm: memblock Add some new functions to address the mem limit issue Mark Rutland
2016-06-24 2:28 ` Dennis Chen [this message]
2016-06-23 15:26 ` kbuild test robot
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=20160624022826.GA12969@arm.com \
--to=dennis.chen@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/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).