Re: [PATCH x86/mm] x86-64, NUMA: Don't call numa_set_distanc() forall possible node combinations during emulation

From: Yinghai Lu
Date: Fri Mar 11 2011 - 10:45:01 EST


On 03/11/2011 01:31 AM, Tejun Heo wrote:
> The distance transforming in numa_emulation() used to call
> numa_set_distance() for all MAX_NUMNODES * MAX_NUMNODES node
> combinations regardless of which are enabled. As numa_set_distance()
> ignores all out-of-bound distance settings, this doesn't cause any
> problem other than looping unnecessarily many times during boot.
>
> However, as MAX_NUMNODES * MAX_NUMNODES can be pretty high, update the
> code such that it iterates through only the enabled combinations.
>
> Yinghai Lu identified the issue and provided an initial patch to
> address the issue; however, the patch was incorrect in that it didn't
> build emulated distance table when there's no physical distance table
> and unnecessarily complex.
>
> http://thread.gmane.org/gmane.linux.kernel/1107986/focus=1107988
>
> Signed-off-by: Tejun Heo <tj@xxxxxxxxxx>
> Reported-by: Yinghai Lu <yinghai@xxxxxxxxxx>
> ---
> arch/x86/mm/numa_emulation.c | 23 ++++++++++++-----------
> 1 file changed, 12 insertions(+), 11 deletions(-)
>
> diff --git a/arch/x86/mm/numa_emulation.c b/arch/x86/mm/numa_emulation.c
> index 3696be0..ad091e4 100644
> --- a/arch/x86/mm/numa_emulation.c
> +++ b/arch/x86/mm/numa_emulation.c
> @@ -301,7 +301,7 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
> const u64 max_addr = max_pfn << PAGE_SHIFT;
> u8 *phys_dist = NULL;
> size_t phys_size = numa_dist_cnt * numa_dist_cnt * sizeof(phys_dist[0]);
> - int dfl_phys_nid;
> + int max_emu_nid, dfl_phys_nid;
> int i, j, ret;
>
> if (!emu_cmdline)
> @@ -358,12 +358,17 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
> node_distance(i, j);
> }
>
> - /* determine the default phys nid to use for unmapped nodes */
> + /*
> + * Determine the max emulated nid and the default phys nid to use
> + * for unmapped nodes.
> + */
> + max_emu_nid = 0;
> dfl_phys_nid = NUMA_NO_NODE;
> for (i = 0; i < ARRAY_SIZE(emu_nid_to_phys); i++) {
> if (emu_nid_to_phys[i] != NUMA_NO_NODE) {
> - dfl_phys_nid = emu_nid_to_phys[i];
> - break;
> + max_emu_nid = i;
> + if (dfl_phys_nid == NUMA_NO_NODE)
> + dfl_phys_nid = emu_nid_to_phys[i];
> }
> }
> if (dfl_phys_nid == NUMA_NO_NODE) {
> @@ -393,14 +398,10 @@ void __init numa_emulation(struct numa_meminfo *numa_meminfo, int numa_dist_cnt)
> if (emu_nid_to_phys[i] == NUMA_NO_NODE)
> emu_nid_to_phys[i] = dfl_phys_nid;
>
> - /*
> - * Transform distance table. numa_set_distance() ignores all
> - * out-of-bound distances. Just call it for every possible node
> - * combination.
> - */
> + /* transform distance table */
> numa_reset_distance();
> - for (i = 0; i < MAX_NUMNODES; i++) {
> - for (j = 0; j < MAX_NUMNODES; j++) {
> + for (i = 0; i < max_emu_nid + 1; i++) {
> + for (j = 0; j < max_emu_nid + 1; j++) {

using num_emu_nids would be better?

Yinghai

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/