mirror of https://gitee.com/openkylin/linux.git
x86/mm/numa: Clean up numa_clear_kernel_node_hotplug()
So we fixed an overflow bug in numa_clear_kernel_node_hotplug(): 2b54ab3c66d4 ("x86/mm/numa: Fix memory corruption on 32-bit NUMA kernels") ... and the bug was indirectly caused by poor coding style, such as using start/end local variables unnecessarily, which lost the physaddr_t type. So make the code more readable and try to fully comment all the thinking behind the logic. No change in functionality. Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Brad Spengler <spender@grsecurity.net> Cc: Chen Tang <imtangchen@gmail.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Lai Jiangshan <laijs@cn.fujitsu.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: PaX Team <pageexec@freemail.hu> Cc: Taku Izumi <izumi.taku@jp.fujitsu.com> Cc: Tang Chen <tangchen@cn.fujitsu.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Wen Congyang <wency@cn.fujitsu.com> Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Cc: y14sg1 <y14sg1@comcast.net> Cc: Zhang Yanfei <zhangyanfei@cn.fujitsu.com> Cc: linux-kernel@vger.kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
b349e9a916
commit
c1a0bf347c
|
@ -465,46 +465,65 @@ static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark all currently memblock-reserved physical memory (which covers the
|
||||
* kernel's own memory ranges) as hot-unswappable.
|
||||
*/
|
||||
static void __init numa_clear_kernel_node_hotplug(void)
|
||||
{
|
||||
int i, nid;
|
||||
nodemask_t numa_kernel_nodes = NODE_MASK_NONE;
|
||||
phys_addr_t start, end;
|
||||
struct memblock_region *r;
|
||||
nodemask_t reserved_nodemask = NODE_MASK_NONE;
|
||||
struct memblock_region *mb_region;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* We have to do some preprocessing of memblock regions, to
|
||||
* make them suitable for reservation.
|
||||
*
|
||||
* At this time, all memory regions reserved by memblock are
|
||||
* used by the kernel. Set the nid in memblock.reserved will
|
||||
* mark out all the nodes the kernel resides in.
|
||||
* used by the kernel, but those regions are not split up
|
||||
* along node boundaries yet, and don't necessarily have their
|
||||
* node ID set yet either.
|
||||
*
|
||||
* So iterate over all memory known to the x86 architecture,
|
||||
* and use those ranges to set the nid in memblock.reserved.
|
||||
* This will split up the memblock regions along node
|
||||
* boundaries and will set the node IDs as well.
|
||||
*/
|
||||
for (i = 0; i < numa_meminfo.nr_blks; i++) {
|
||||
struct numa_memblk *mb = &numa_meminfo.blk[i];
|
||||
struct numa_memblk *mb = numa_meminfo.blk + i;
|
||||
|
||||
memblock_set_node(mb->start, mb->end - mb->start,
|
||||
&memblock.reserved, mb->nid);
|
||||
memblock_set_node(mb->start, mb->end - mb->start, &memblock.reserved, mb->nid);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark all kernel nodes.
|
||||
* Now go over all reserved memblock regions, to construct a
|
||||
* node mask of all kernel reserved memory areas.
|
||||
*
|
||||
* When booting with mem=nn[kMG] or in a kdump kernel, numa_meminfo
|
||||
* may not include all the memblock.reserved memory ranges because
|
||||
* trim_snb_memory() reserves specific pages for Sandy Bridge graphics.
|
||||
* [ Note, when booting with mem=nn[kMG] or in a kdump kernel,
|
||||
* numa_meminfo might not include all memblock.reserved
|
||||
* memory ranges, because quirks such as trim_snb_memory()
|
||||
* reserve specific pages for Sandy Bridge graphics. ]
|
||||
*/
|
||||
for_each_memblock(reserved, r)
|
||||
if (r->nid != MAX_NUMNODES)
|
||||
node_set(r->nid, numa_kernel_nodes);
|
||||
for_each_memblock(reserved, mb_region) {
|
||||
if (mb_region->nid != MAX_NUMNODES)
|
||||
node_set(mb_region->nid, reserved_nodemask);
|
||||
}
|
||||
|
||||
/* Clear MEMBLOCK_HOTPLUG flag for memory in kernel nodes. */
|
||||
/*
|
||||
* Finally, clear the MEMBLOCK_HOTPLUG flag for all memory
|
||||
* belonging to the reserved node mask.
|
||||
*
|
||||
* Note that this will include memory regions that reside
|
||||
* on nodes that contain kernel memory - entire nodes
|
||||
* become hot-unpluggable:
|
||||
*/
|
||||
for (i = 0; i < numa_meminfo.nr_blks; i++) {
|
||||
nid = numa_meminfo.blk[i].nid;
|
||||
if (!node_isset(nid, numa_kernel_nodes))
|
||||
struct numa_memblk *mb = numa_meminfo.blk + i;
|
||||
|
||||
if (!node_isset(mb->nid, reserved_nodemask))
|
||||
continue;
|
||||
|
||||
start = numa_meminfo.blk[i].start;
|
||||
end = numa_meminfo.blk[i].end;
|
||||
|
||||
memblock_clear_hotplug(start, end - start);
|
||||
memblock_clear_hotplug(mb->start, mb->end - mb->start);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue