* [PATCH] x86/UV: GRU distributed mode mappings @ 2013-05-23 15:50 Dimitri Sivanich 2013-05-28 7:59 ` Ingo Molnar 0 siblings, 1 reply; 6+ messages in thread From: Dimitri Sivanich @ 2013-05-23 15:50 UTC (permalink / raw) To: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Alexander Gordeev, Suresh Siddha Cc: linux-kernel, x86, Russ Anderson, Mike Travis Setup mappings for GRU distributed mode and include them as untracked pat ranges. Signed-off-by: Dimitri Sivanich <sivanich@sgi.com> --- arch/x86/kernel/apic/x2apic_uv_x.c | 63 +++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) Index: linux/arch/x86/kernel/apic/x2apic_uv_x.c =================================================================== --- linux.orig/arch/x86/kernel/apic/x2apic_uv_x.c +++ linux/arch/x86/kernel/apic/x2apic_uv_x.c @@ -51,6 +51,8 @@ DEFINE_PER_CPU(int, x2apic_extra_bits); static enum uv_system_type uv_system_type; static u64 gru_start_paddr, gru_end_paddr; +static u64 gru_dist_base, gru_first_node_paddr = -1LL, gru_last_node_paddr; +static u64 gru_dist_lmask, gru_dist_umask; static union uvh_apicid uvh_apicid; int uv_min_hub_revision_id; EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); @@ -72,7 +74,19 @@ static unsigned long __init uv_early_rea static inline bool is_GRU_range(u64 start, u64 end) { - return start >= gru_start_paddr && end <= gru_end_paddr; + if (gru_dist_base) { + u64 su = start & gru_dist_umask; /* upper (incl pnode) bits */ + u64 sl = start & gru_dist_lmask; /* base offset bits */ + u64 eu = end & gru_dist_umask; + u64 el = end & gru_dist_lmask; + + /* Must reside completely within a single GRU range */ + return (sl == gru_dist_base && el == gru_dist_base && + su >= gru_first_node_paddr && + su <= gru_last_node_paddr && + eu == su); + } else + return start >= gru_start_paddr && end <= gru_end_paddr; } static bool uv_is_untracked_pat_range(u64 start, u64 end) @@ -470,19 +484,56 @@ static __init void map_high(char *id, un init_extra_mapping_wb(paddr, bytes); } +static __init void map_gru_distributed(unsigned long c) +{ + union uvh_rh_gam_gru_overlay_config_mmr_u gru; + u64 paddr; + unsigned long bytes; + int nid; + + gru.v = c; + /* only base bits 42:28 relevant in dist mode */ + gru_dist_base = gru.v & 0x000007fff0000000UL; + if (!gru_dist_base) { + pr_info("UV: Map GRU_DIST base address NULL\n"); + return; + } + bytes = 1UL << UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; + gru_dist_lmask = ((1UL << uv_hub_info->m_val) - 1) & ~(bytes - 1); + gru_dist_umask = ~((1UL << uv_hub_info->m_val) - 1); + gru_dist_base &= gru_dist_lmask; /* Clear bits above M */ + for_each_online_node(nid) { + paddr = ((u64)uv_node_to_pnode(nid) << uv_hub_info->m_val) | + gru_dist_base; + init_extra_mapping_wb(paddr, bytes); + gru_first_node_paddr = min(paddr, gru_first_node_paddr); + gru_last_node_paddr = max(paddr, gru_last_node_paddr); + } + /* Save upper (63:M) bits of address only for is_GRU_range */ + gru_first_node_paddr &= gru_dist_umask; + gru_last_node_paddr &= gru_dist_umask; + pr_info("UV: Map GRU_DIST base 0x%016llx 0x%016llx - 0x%016llx\n", + gru_dist_base, gru_first_node_paddr, gru_last_node_paddr); +} + static __init void map_gru_high(int max_pnode) { union uvh_rh_gam_gru_overlay_config_mmr_u gru; int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); - if (gru.s.enable) { - map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb); - gru_start_paddr = ((u64)gru.s.base << shift); - gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1); - } else { + if (!gru.s.enable) { pr_info("UV: GRU disabled\n"); + return; + } + + if (is_uv3_hub() && gru.s3.mode) { + map_gru_distributed(gru.v); + return; } + map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb); + gru_start_paddr = ((u64)gru.s.base << shift); + gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1); } static __init void map_mmr_high(int max_pnode) ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86/UV: GRU distributed mode mappings 2013-05-23 15:50 [PATCH] x86/UV: GRU distributed mode mappings Dimitri Sivanich @ 2013-05-28 7:59 ` Ingo Molnar 2013-05-28 13:41 ` Dimitri Sivanich 0 siblings, 1 reply; 6+ messages in thread From: Ingo Molnar @ 2013-05-28 7:59 UTC (permalink / raw) To: Dimitri Sivanich Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Alexander Gordeev, Suresh Siddha, linux-kernel, x86, Russ Anderson, Mike Travis * Dimitri Sivanich <sivanich@sgi.com> wrote: > Setup mappings for GRU distributed mode and include them as untracked > pat ranges. Would be nice to have the customary changelog content: " Current code does (A), this has a problem when (B). We can improve this doing (C), because (D)." Or so - your changelog is pretty light on the 'why' aspect. Thanks, Ingo ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86/UV: GRU distributed mode mappings 2013-05-28 7:59 ` Ingo Molnar @ 2013-05-28 13:41 ` Dimitri Sivanich 2013-05-29 8:15 ` Ingo Molnar 0 siblings, 1 reply; 6+ messages in thread From: Dimitri Sivanich @ 2013-05-28 13:41 UTC (permalink / raw) To: Ingo Molnar Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Alexander Gordeev, Suresh Siddha, linux-kernel, x86, Russ Anderson, Mike Travis On Tue, May 28, 2013 at 09:59:12AM +0200, Ingo Molnar wrote: > > * Dimitri Sivanich <sivanich@sgi.com> wrote: > > > Setup mappings for GRU distributed mode and include them as untracked > > pat ranges. > > Would be nice to have the customary changelog content: > > " Current code does (A), this has a problem when (B). > We can improve this doing (C), because (D)." > > Or so - your changelog is pretty light on the 'why' aspect. > How about the following? UV GRU hardware will support an optional distributed mode that will allow per-node address mapping of local GRU space, as opposed to mapping all GRU hardware to the same contiguous high space. If GRU distributed mode is selected, setup per-node page table mappings and include them as untracked pat ranges. Signed-off-by: Dimitri Sivanich <sivanich@sgi.com> --- arch/x86/kernel/apic/x2apic_uv_x.c | 63 +++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 6 deletions(-) Index: linux/arch/x86/kernel/apic/x2apic_uv_x.c =================================================================== --- linux.orig/arch/x86/kernel/apic/x2apic_uv_x.c +++ linux/arch/x86/kernel/apic/x2apic_uv_x.c @@ -51,6 +51,8 @@ DEFINE_PER_CPU(int, x2apic_extra_bits); static enum uv_system_type uv_system_type; static u64 gru_start_paddr, gru_end_paddr; +static u64 gru_dist_base, gru_first_node_paddr = -1LL, gru_last_node_paddr; +static u64 gru_dist_lmask, gru_dist_umask; static union uvh_apicid uvh_apicid; int uv_min_hub_revision_id; EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); @@ -72,7 +74,19 @@ static unsigned long __init uv_early_rea static inline bool is_GRU_range(u64 start, u64 end) { - return start >= gru_start_paddr && end <= gru_end_paddr; + if (gru_dist_base) { + u64 su = start & gru_dist_umask; /* upper (incl pnode) bits */ + u64 sl = start & gru_dist_lmask; /* base offset bits */ + u64 eu = end & gru_dist_umask; + u64 el = end & gru_dist_lmask; + + /* Must reside completely within a single GRU range */ + return (sl == gru_dist_base && el == gru_dist_base && + su >= gru_first_node_paddr && + su <= gru_last_node_paddr && + eu == su); + } else + return start >= gru_start_paddr && end <= gru_end_paddr; } static bool uv_is_untracked_pat_range(u64 start, u64 end) @@ -470,19 +484,56 @@ static __init void map_high(char *id, un init_extra_mapping_wb(paddr, bytes); } +static __init void map_gru_distributed(unsigned long c) +{ + union uvh_rh_gam_gru_overlay_config_mmr_u gru; + u64 paddr; + unsigned long bytes; + int nid; + + gru.v = c; + /* only base bits 42:28 relevant in dist mode */ + gru_dist_base = gru.v & 0x000007fff0000000UL; + if (!gru_dist_base) { + pr_info("UV: Map GRU_DIST base address NULL\n"); + return; + } + bytes = 1UL << UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; + gru_dist_lmask = ((1UL << uv_hub_info->m_val) - 1) & ~(bytes - 1); + gru_dist_umask = ~((1UL << uv_hub_info->m_val) - 1); + gru_dist_base &= gru_dist_lmask; /* Clear bits above M */ + for_each_online_node(nid) { + paddr = ((u64)uv_node_to_pnode(nid) << uv_hub_info->m_val) | + gru_dist_base; + init_extra_mapping_wb(paddr, bytes); + gru_first_node_paddr = min(paddr, gru_first_node_paddr); + gru_last_node_paddr = max(paddr, gru_last_node_paddr); + } + /* Save upper (63:M) bits of address only for is_GRU_range */ + gru_first_node_paddr &= gru_dist_umask; + gru_last_node_paddr &= gru_dist_umask; + pr_info("UV: Map GRU_DIST base 0x%016llx 0x%016llx - 0x%016llx\n", + gru_dist_base, gru_first_node_paddr, gru_last_node_paddr); +} + static __init void map_gru_high(int max_pnode) { union uvh_rh_gam_gru_overlay_config_mmr_u gru; int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); - if (gru.s.enable) { - map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb); - gru_start_paddr = ((u64)gru.s.base << shift); - gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1); - } else { + if (!gru.s.enable) { pr_info("UV: GRU disabled\n"); + return; + } + + if (is_uv3_hub() && gru.s3.mode) { + map_gru_distributed(gru.v); + return; } + map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb); + gru_start_paddr = ((u64)gru.s.base << shift); + gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1); } static __init void map_mmr_high(int max_pnode) ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86/UV: GRU distributed mode mappings 2013-05-28 13:41 ` Dimitri Sivanich @ 2013-05-29 8:15 ` Ingo Molnar 2013-05-29 15:56 ` Dimitri Sivanich 0 siblings, 1 reply; 6+ messages in thread From: Ingo Molnar @ 2013-05-29 8:15 UTC (permalink / raw) To: Dimitri Sivanich Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Alexander Gordeev, Suresh Siddha, linux-kernel, x86, Russ Anderson, Mike Travis * Dimitri Sivanich <sivanich@sgi.com> wrote: > On Tue, May 28, 2013 at 09:59:12AM +0200, Ingo Molnar wrote: > > > > * Dimitri Sivanich <sivanich@sgi.com> wrote: > > > > > Setup mappings for GRU distributed mode and include them as untracked > > > pat ranges. > > > > Would be nice to have the customary changelog content: > > > > " Current code does (A), this has a problem when (B). > > We can improve this doing (C), because (D)." > > > > Or so - your changelog is pretty light on the 'why' aspect. > > > How about the following? Looks good to me. > UV GRU hardware will support an optional distributed mode that will allow > per-node address mapping of local GRU space, as opposed to mapping all GRU > hardware to the same contiguous high space. > > If GRU distributed mode is selected, setup per-node page table mappings and > include them as untracked pat ranges. > > Signed-off-by: Dimitri Sivanich <sivanich@sgi.com> > --- > arch/x86/kernel/apic/x2apic_uv_x.c | 63 +++++++++++++++++++++++++++++---- > 1 file changed, 57 insertions(+), 6 deletions(-) So this looks like suitable v3.11 material - not an urgent fix needed for v3.10, right? Noticed this detail: > + } else > + return start >= gru_start_paddr && end <= gru_end_paddr; in the kernel we generally try to balance curly braces - either all branches are curly or none. > + /* Save upper (63:M) bits of address only for is_GRU_range */ > + gru_first_node_paddr &= gru_dist_umask; > + gru_last_node_paddr &= gru_dist_umask; > + pr_info("UV: Map GRU_DIST base 0x%016llx 0x%016llx - 0x%016llx\n", > + gru_dist_base, gru_first_node_paddr, gru_last_node_paddr); I suspect this should be pr_debug()? Thanks, Ingo ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] x86/UV: GRU distributed mode mappings 2013-05-29 8:15 ` Ingo Molnar @ 2013-05-29 15:56 ` Dimitri Sivanich 2013-05-31 12:26 ` [tip:x86/uv] x86/UV: Add " tip-bot for Dimitri Sivanich 0 siblings, 1 reply; 6+ messages in thread From: Dimitri Sivanich @ 2013-05-29 15:56 UTC (permalink / raw) To: Ingo Molnar Cc: Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Alexander Gordeev, Suresh Siddha, linux-kernel, x86, Russ Anderson, Mike Travis On Wed, May 29, 2013 at 10:15:39AM +0200, Ingo Molnar wrote: > > So this looks like suitable v3.11 material - not an urgent fix needed for > v3.10, right? Correct, v3.11 is fine. > > Noticed this detail: > > > + } else > > + return start >= gru_start_paddr && end <= gru_end_paddr; > > in the kernel we generally try to balance curly braces - either all > branches are curly or none. Fixed, see patch below. > > > + /* Save upper (63:M) bits of address only for is_GRU_range */ > > + gru_first_node_paddr &= gru_dist_umask; > > + gru_last_node_paddr &= gru_dist_umask; > > + pr_info("UV: Map GRU_DIST base 0x%016llx 0x%016llx - 0x%016llx\n", > > + gru_dist_base, gru_first_node_paddr, gru_last_node_paddr); > > I suspect this should be pr_debug()? > I had set it to what was being used in map_high(), but pr_debug should be OK, so I changed both instances. GRU hardware will support an optional distributed mode that will allow per-node address mapping of local GRU space, as opposed to mapping all GRU hardware to the same contiguous high space. If GRU distributed mode is selected, setup per-node page table mappings. Signed-off-by: Dimitri Sivanich <sivanich@sgi.com> --- arch/x86/kernel/apic/x2apic_uv_x.c | 66 +++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 7 deletions(-) Index: linux/arch/x86/kernel/apic/x2apic_uv_x.c =================================================================== --- linux.orig/arch/x86/kernel/apic/x2apic_uv_x.c +++ linux/arch/x86/kernel/apic/x2apic_uv_x.c @@ -51,6 +51,8 @@ DEFINE_PER_CPU(int, x2apic_extra_bits); static enum uv_system_type uv_system_type; static u64 gru_start_paddr, gru_end_paddr; +static u64 gru_dist_base, gru_first_node_paddr = -1LL, gru_last_node_paddr; +static u64 gru_dist_lmask, gru_dist_umask; static union uvh_apicid uvh_apicid; int uv_min_hub_revision_id; EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); @@ -72,7 +74,20 @@ static unsigned long __init uv_early_rea static inline bool is_GRU_range(u64 start, u64 end) { - return start >= gru_start_paddr && end <= gru_end_paddr; + if (gru_dist_base) { + u64 su = start & gru_dist_umask; /* upper (incl pnode) bits */ + u64 sl = start & gru_dist_lmask; /* base offset bits */ + u64 eu = end & gru_dist_umask; + u64 el = end & gru_dist_lmask; + + /* Must reside completely within a single GRU range */ + return (sl == gru_dist_base && el == gru_dist_base && + su >= gru_first_node_paddr && + su <= gru_last_node_paddr && + eu == su); + } else { + return start >= gru_start_paddr && end <= gru_end_paddr; + } } static bool uv_is_untracked_pat_range(u64 start, u64 end) @@ -463,26 +478,63 @@ static __init void map_high(char *id, un pr_info("UV: Map %s_HI base address NULL\n", id); return; } - pr_info("UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, paddr + bytes); + pr_debug("UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, paddr + bytes); if (map_type == map_uc) init_extra_mapping_uc(paddr, bytes); else init_extra_mapping_wb(paddr, bytes); } +static __init void map_gru_distributed(unsigned long c) +{ + union uvh_rh_gam_gru_overlay_config_mmr_u gru; + u64 paddr; + unsigned long bytes; + int nid; + + gru.v = c; + /* only base bits 42:28 relevant in dist mode */ + gru_dist_base = gru.v & 0x000007fff0000000UL; + if (!gru_dist_base) { + pr_info("UV: Map GRU_DIST base address NULL\n"); + return; + } + bytes = 1UL << UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; + gru_dist_lmask = ((1UL << uv_hub_info->m_val) - 1) & ~(bytes - 1); + gru_dist_umask = ~((1UL << uv_hub_info->m_val) - 1); + gru_dist_base &= gru_dist_lmask; /* Clear bits above M */ + for_each_online_node(nid) { + paddr = ((u64)uv_node_to_pnode(nid) << uv_hub_info->m_val) | + gru_dist_base; + init_extra_mapping_wb(paddr, bytes); + gru_first_node_paddr = min(paddr, gru_first_node_paddr); + gru_last_node_paddr = max(paddr, gru_last_node_paddr); + } + /* Save upper (63:M) bits of address only for is_GRU_range */ + gru_first_node_paddr &= gru_dist_umask; + gru_last_node_paddr &= gru_dist_umask; + pr_debug("UV: Map GRU_DIST base 0x%016llx 0x%016llx - 0x%016llx\n", + gru_dist_base, gru_first_node_paddr, gru_last_node_paddr); +} + static __init void map_gru_high(int max_pnode) { union uvh_rh_gam_gru_overlay_config_mmr_u gru; int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); - if (gru.s.enable) { - map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb); - gru_start_paddr = ((u64)gru.s.base << shift); - gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1); - } else { + if (!gru.s.enable) { pr_info("UV: GRU disabled\n"); + return; + } + + if (is_uv3_hub() && gru.s3.mode) { + map_gru_distributed(gru.v); + return; } + map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb); + gru_start_paddr = ((u64)gru.s.base << shift); + gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1); } static __init void map_mmr_high(int max_pnode) ^ permalink raw reply [flat|nested] 6+ messages in thread
* [tip:x86/uv] x86/UV: Add GRU distributed mode mappings 2013-05-29 15:56 ` Dimitri Sivanich @ 2013-05-31 12:26 ` tip-bot for Dimitri Sivanich 0 siblings, 0 replies; 6+ messages in thread From: tip-bot for Dimitri Sivanich @ 2013-05-31 12:26 UTC (permalink / raw) To: linux-tip-commits Cc: linux-kernel, agordeev, hpa, mingo, travis, sivanich, rja, suresh.b.siddha, tglx Commit-ID: 879d5ad0dc3b096170c8f985b1465de5dca88de8 Gitweb: http://git.kernel.org/tip/879d5ad0dc3b096170c8f985b1465de5dca88de8 Author: Dimitri Sivanich <sivanich@sgi.com> AuthorDate: Wed, 29 May 2013 10:56:09 -0500 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Thu, 30 May 2013 09:46:09 +0200 x86/UV: Add GRU distributed mode mappings GRU hardware will support an optional distributed mode that will allow per-node address mapping of local GRU space, as opposed to mapping all GRU hardware to the same contiguous high space. If GRU distributed mode is selected, setup per-node page table mappings. Signed-off-by: Dimitri Sivanich <sivanich@sgi.com> Cc: Alexander Gordeev <agordeev@redhat.com> Cc: Suresh Siddha <suresh.b.siddha@intel.com> Cc: Russ Anderson <rja@sgi.com> Cc: Mike Travis <travis@sgi.com> Link: http://lkml.kernel.org/r/20130529155609.GB22917@sgi.com Signed-off-by: Ingo Molnar <mingo@kernel.org> --- arch/x86/kernel/apic/x2apic_uv_x.c | 66 ++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/arch/x86/kernel/apic/x2apic_uv_x.c b/arch/x86/kernel/apic/x2apic_uv_x.c index 794f6eb..39cc7f7 100644 --- a/arch/x86/kernel/apic/x2apic_uv_x.c +++ b/arch/x86/kernel/apic/x2apic_uv_x.c @@ -51,6 +51,8 @@ DEFINE_PER_CPU(int, x2apic_extra_bits); static enum uv_system_type uv_system_type; static u64 gru_start_paddr, gru_end_paddr; +static u64 gru_dist_base, gru_first_node_paddr = -1LL, gru_last_node_paddr; +static u64 gru_dist_lmask, gru_dist_umask; static union uvh_apicid uvh_apicid; int uv_min_hub_revision_id; EXPORT_SYMBOL_GPL(uv_min_hub_revision_id); @@ -72,7 +74,20 @@ static unsigned long __init uv_early_read_mmr(unsigned long addr) static inline bool is_GRU_range(u64 start, u64 end) { - return start >= gru_start_paddr && end <= gru_end_paddr; + if (gru_dist_base) { + u64 su = start & gru_dist_umask; /* upper (incl pnode) bits */ + u64 sl = start & gru_dist_lmask; /* base offset bits */ + u64 eu = end & gru_dist_umask; + u64 el = end & gru_dist_lmask; + + /* Must reside completely within a single GRU range */ + return (sl == gru_dist_base && el == gru_dist_base && + su >= gru_first_node_paddr && + su <= gru_last_node_paddr && + eu == su); + } else { + return start >= gru_start_paddr && end <= gru_end_paddr; + } } static bool uv_is_untracked_pat_range(u64 start, u64 end) @@ -463,26 +478,63 @@ static __init void map_high(char *id, unsigned long base, int pshift, pr_info("UV: Map %s_HI base address NULL\n", id); return; } - pr_info("UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, paddr + bytes); + pr_debug("UV: Map %s_HI 0x%lx - 0x%lx\n", id, paddr, paddr + bytes); if (map_type == map_uc) init_extra_mapping_uc(paddr, bytes); else init_extra_mapping_wb(paddr, bytes); } +static __init void map_gru_distributed(unsigned long c) +{ + union uvh_rh_gam_gru_overlay_config_mmr_u gru; + u64 paddr; + unsigned long bytes; + int nid; + + gru.v = c; + /* only base bits 42:28 relevant in dist mode */ + gru_dist_base = gru.v & 0x000007fff0000000UL; + if (!gru_dist_base) { + pr_info("UV: Map GRU_DIST base address NULL\n"); + return; + } + bytes = 1UL << UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; + gru_dist_lmask = ((1UL << uv_hub_info->m_val) - 1) & ~(bytes - 1); + gru_dist_umask = ~((1UL << uv_hub_info->m_val) - 1); + gru_dist_base &= gru_dist_lmask; /* Clear bits above M */ + for_each_online_node(nid) { + paddr = ((u64)uv_node_to_pnode(nid) << uv_hub_info->m_val) | + gru_dist_base; + init_extra_mapping_wb(paddr, bytes); + gru_first_node_paddr = min(paddr, gru_first_node_paddr); + gru_last_node_paddr = max(paddr, gru_last_node_paddr); + } + /* Save upper (63:M) bits of address only for is_GRU_range */ + gru_first_node_paddr &= gru_dist_umask; + gru_last_node_paddr &= gru_dist_umask; + pr_debug("UV: Map GRU_DIST base 0x%016llx 0x%016llx - 0x%016llx\n", + gru_dist_base, gru_first_node_paddr, gru_last_node_paddr); +} + static __init void map_gru_high(int max_pnode) { union uvh_rh_gam_gru_overlay_config_mmr_u gru; int shift = UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT; gru.v = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR); - if (gru.s.enable) { - map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb); - gru_start_paddr = ((u64)gru.s.base << shift); - gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1); - } else { + if (!gru.s.enable) { pr_info("UV: GRU disabled\n"); + return; + } + + if (is_uv3_hub() && gru.s3.mode) { + map_gru_distributed(gru.v); + return; } + map_high("GRU", gru.s.base, shift, shift, max_pnode, map_wb); + gru_start_paddr = ((u64)gru.s.base << shift); + gru_end_paddr = gru_start_paddr + (1UL << shift) * (max_pnode + 1); } static __init void map_mmr_high(int max_pnode) ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-05-31 12:27 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-05-23 15:50 [PATCH] x86/UV: GRU distributed mode mappings Dimitri Sivanich 2013-05-28 7:59 ` Ingo Molnar 2013-05-28 13:41 ` Dimitri Sivanich 2013-05-29 8:15 ` Ingo Molnar 2013-05-29 15:56 ` Dimitri Sivanich 2013-05-31 12:26 ` [tip:x86/uv] x86/UV: Add " tip-bot for Dimitri Sivanich
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).