Subject: x86, UV: fixes to tlb shootdown
Subsystems (2)
v5 cover Subject: x86, UV: fixes to tlb shootdown
Version 1 was a series of 6 patches, submitted Jun14 2011.
Version 2 of this series: 8 patches
- Adds more explanation to "UV: smp_processor_id in a preemptable region"
- Splits "UV: correct reset_with_ipi()" into its 3 logical changes
- Adds statement of importance to "UV: correct UV2 BAU destination timeout"
Version 3 of this series:
- Uses get_cpu()/put_cpu() to bound the region in which cpu number is used in "UV: smp_processor_id in a preemptable region"
Version 4 of this series:
- cc's [email protected]
- Moves non-change notes out of the changelog text
Version 5 of this series:
- removes the Diffed against tags
[PATCH 1/8 v5] x86, UV: smp_processor_id in a preemptable region [PATCH 2/8 v5] x86, UV: inline header file functions [PATCH 3/8 v5] x86, UV: allow for non-consecutive sockets [PATCH 4/8 v5] x86, UV: correct reset_with_ipi() [PATCH 5/8 v5] x86, UV: rename hubmask to pnmask [PATCH 6/8 v5] x86, UV: remove cpumask_t from the stack [PATCH 7/8 v5] x86, UV: correct failed topology memory leak [PATCH 8/8 v5] x86, UV: correct UV2 BAU destination timeout
Signature · 4 lines
Cliff Wickman SGI [email protected] (651) 683-3824
PATCH v5 1/8 x86, UV: smp_processor_id in a preemptable region
Fix a call by tunables_write() to smp_processor_id() within a preemptable region.
Call get_cpu()/put_cpu() around the region where the returned cpu number is actually used, which makes it non-preemptable.
---
A DEBUG_PREEMPT warning is prevented.
UV does not support cpu hotplug yet, but this is a step toward that ability.
arch/x86/platform/uv/tlb_uv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
arch/x86/platform/uv/tlb_uv.c +3 -2
@@ -1334,9 +1334,10 @@ static ssize_t tunables_write(struct fil instr[count] ='\0' ; - bcp = &per_cpu (bau_control,smp_processor_id ()); - + cpu =get_cpu (); + bcp = &per_cpu (bau_control, cpu); ret =parse_tunables_write (bcp, instr, count); +put_cpu ();if (ret)return ret;
[tip:x86/uv] x86, UV: Fix smp_processor_id() use in a preemptable region
Commit-ID: 00b30cf04a775b5292ab704f782394e36e25617d Gitweb: http://git.kernel.org/tip/00b30cf04a775b5292ab704f782394e36e25617d Author: [email protected] <[email protected]> AuthorDate: Tue, 21 Jun 2011 07:21:26 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 21 Jun 2011 14:50:31 +0200
x86, UV: Fix smp_processor_id() use in a preemptable region
Fix a call by tunables_write() to smp_processor_id() within a preemptable region.
Call get_cpu()/put_cpu() around the region where the returned cpu number is actually used, which makes it non-preemptable.
A DEBUG_PREEMPT warning is prevented.
UV does not support cpu hotplug yet, but this is a step toward that ability as well.
--- arch/x86/platform/uv/tlb_uv.c | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-)
arch/x86/platform/uv/tlb_uv.c +3 -2
@@ -1334,9 +1334,10 @@ static ssize_t tunables_write(struct file *file, const char __user *user, instr[count] ='\0' ; - bcp = &per_cpu (bau_control,smp_processor_id ()); - + cpu =get_cpu (); + bcp = &per_cpu (bau_control, cpu); ret =parse_tunables_write (bcp, instr, count); +put_cpu ();if (ret)return ret;
PATCH v5 2/8 x86, UV: inline header file functions
In reply to [email protected]Make all the functions in uv_bau.h inline so that it can be included in the fake prom (used in simulations).
---
If not inlined the unused functions will generate compiler warnings.
arch/x86/include/asm/uv/uv_bau.h | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +14 -14
@@ -526,72 +526,72 @@ struct bau_control {struct hub_and_pnode *thp; }; -static unsigned long read_mmr_uv2_status (void ) +static inline unsigned long read_mmr_uv2_status (void ) {return read_lmmr (UV2H_LB_BAU_SB_ACTIVATION_STATUS_2 ); } -static void write_mmr_data_broadcast (int pnode,unsigned long mmr_image) +static inline void write_mmr_data_broadcast (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_BAU_DATA_BROADCAST , mmr_image); } -static void write_mmr_descriptor_base (int pnode,unsigned long mmr_image) +static inline void write_mmr_descriptor_base (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_SB_DESCRIPTOR_BASE , mmr_image); } -static void write_mmr_activation (unsigned long index) +static inline void write_mmr_activation (unsigned long index) {write_lmmr (UVH_LB_BAU_SB_ACTIVATION_CONTROL , index); } -static void write_gmmr_activation (int pnode,unsigned long mmr_image) +static inline void write_gmmr_activation (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_SB_ACTIVATION_CONTROL , mmr_image); } -static void write_mmr_payload_first (int pnode,unsigned long mmr_image) +static inline void write_mmr_payload_first (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST , mmr_image); } -static void write_mmr_payload_tail (int pnode,unsigned long mmr_image) +static inline void write_mmr_payload_tail (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL , mmr_image); } -static void write_mmr_payload_last (int pnode,unsigned long mmr_image) +static inline void write_mmr_payload_last (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST , mmr_image); } -static void write_mmr_misc_control (int pnode,unsigned long mmr_image) +static inline void write_mmr_misc_control (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_MISC_CONTROL , mmr_image); } -static unsigned long read_mmr_misc_control (int pnode) +static inline unsigned long read_mmr_misc_control (int pnode) {return read_gmmr (pnode,UVH_LB_BAU_MISC_CONTROL ); } -static void write_mmr_sw_ack (unsigned long mr) +static inline void write_mmr_sw_ack (unsigned long mr) {uv_write_local_mmr (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS , mr); } -static unsigned long read_mmr_sw_ack (void ) +static inline unsigned long read_mmr_sw_ack (void ) {return read_lmmr (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE ); } -static unsigned long read_gmmr_sw_ack (int pnode) +static inline unsigned long read_gmmr_sw_ack (int pnode) {return read_gmmr (pnode,UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE ); } -static void write_mmr_data_config (int pnode,unsigned long mr) +static inline void write_mmr_data_config (int pnode,unsigned long mr) {uv_write_global_mmr64 (pnode,UVH_BAU_DATA_CONFIG , mr); }
[tip:x86/uv] x86, UV: Inline header file functions
Commit-ID: b18fb2c04ac46885f5b0226cd945e763eae51567 Gitweb: http://git.kernel.org/tip/b18fb2c04ac46885f5b0226cd945e763eae51567 Author: [email protected] <[email protected]> AuthorDate: Tue, 21 Jun 2011 07:21:27 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 21 Jun 2011 14:50:31 +0200
x86, UV: Inline header file functions
Make all the functions in uv_bau.h inline so that it can be included in the fake prom (used in simulations).
If not inlined the unused functions will generate compiler warnings.
--- arch/x86/include/asm/uv/uv_bau.h | 28 ++++++++++++++-------------- 1 files changed, 14 insertions(+), 14 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +14 -14
@@ -526,72 +526,72 @@ struct bau_control {struct hub_and_pnode *thp; }; -static unsigned long read_mmr_uv2_status (void ) +static inline unsigned long read_mmr_uv2_status (void ) {return read_lmmr (UV2H_LB_BAU_SB_ACTIVATION_STATUS_2 ); } -static void write_mmr_data_broadcast (int pnode,unsigned long mmr_image) +static inline void write_mmr_data_broadcast (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_BAU_DATA_BROADCAST , mmr_image); } -static void write_mmr_descriptor_base (int pnode,unsigned long mmr_image) +static inline void write_mmr_descriptor_base (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_SB_DESCRIPTOR_BASE , mmr_image); } -static void write_mmr_activation (unsigned long index) +static inline void write_mmr_activation (unsigned long index) {write_lmmr (UVH_LB_BAU_SB_ACTIVATION_CONTROL , index); } -static void write_gmmr_activation (int pnode,unsigned long mmr_image) +static inline void write_gmmr_activation (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_SB_ACTIVATION_CONTROL , mmr_image); } -static void write_mmr_payload_first (int pnode,unsigned long mmr_image) +static inline void write_mmr_payload_first (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST , mmr_image); } -static void write_mmr_payload_tail (int pnode,unsigned long mmr_image) +static inline void write_mmr_payload_tail (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL , mmr_image); } -static void write_mmr_payload_last (int pnode,unsigned long mmr_image) +static inline void write_mmr_payload_last (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST , mmr_image); } -static void write_mmr_misc_control (int pnode,unsigned long mmr_image) +static inline void write_mmr_misc_control (int pnode,unsigned long mmr_image) {write_gmmr (pnode,UVH_LB_BAU_MISC_CONTROL , mmr_image); } -static unsigned long read_mmr_misc_control (int pnode) +static inline unsigned long read_mmr_misc_control (int pnode) {return read_gmmr (pnode,UVH_LB_BAU_MISC_CONTROL ); } -static void write_mmr_sw_ack (unsigned long mr) +static inline void write_mmr_sw_ack (unsigned long mr) {uv_write_local_mmr (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS , mr); } -static unsigned long read_mmr_sw_ack (void ) +static inline unsigned long read_mmr_sw_ack (void ) {return read_lmmr (UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE ); } -static unsigned long read_gmmr_sw_ack (int pnode) +static inline unsigned long read_gmmr_sw_ack (int pnode) {return read_gmmr (pnode,UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE ); } -static void write_mmr_data_config (int pnode,unsigned long mr) +static inline void write_mmr_data_config (int pnode,unsigned long mr) {uv_write_global_mmr64 (pnode,UVH_BAU_DATA_CONFIG , mr); }
PATCH v5 3/8 x86, UV: allow for non-consecutive sockets
In reply to [email protected]Fix for the topology in which there is a socket 1 on a blade with no socket 0.
---
Only call make_per_cpu_thp() for present sockets. We have only seen this fail for internal configurations.
arch/x86/platform/uv/tlb_uv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/platform/uv/tlb_uv.c +1 -1
@@ -1752,10 +1752,10 @@ static int __init summarize_uvhub_socket sdp = &bdp->socket[socket];if (scan_sock (sdp, bdp, &smaster, &hmaster))return 1 ; +make_per_cpu_thp (smaster); } socket++; socket_mask = (socket_mask >>1 ); -make_per_cpu_thp (smaster); } }return 0 ;
[tip:x86/uv] x86, UV: Allow for non-consecutive sockets
Commit-ID: 9c9153db22870c3f37add83bea30500fcc268a73 Gitweb: http://git.kernel.org/tip/9c9153db22870c3f37add83bea30500fcc268a73 Author: [email protected] <[email protected]> AuthorDate: Tue, 21 Jun 2011 07:21:28 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 21 Jun 2011 14:50:32 +0200
x86, UV: Allow for non-consecutive sockets
Fix for the topology in which there is a socket 1 on a blade with no socket 0.
Only call make_per_cpu_thp() for present sockets. We have only seen this fail for internal configurations.
--- arch/x86/platform/uv/tlb_uv.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
arch/x86/platform/uv/tlb_uv.c +1 -1
@@ -1752,10 +1752,10 @@ static int __init summarize_uvhub_sockets(int nuvhubs, sdp = &bdp->socket[socket];if (scan_sock (sdp, bdp, &smaster, &hmaster))return 1 ; +make_per_cpu_thp (smaster); } socket++; socket_mask = (socket_mask >>1 ); -make_per_cpu_thp (smaster); } }return 0 ;
PATCH v5 4/8 x86, UV: correct reset_with_ipi()
In reply to [email protected]Fix reset_with_ipi() to look up a cpu for a blade based on the distribution map being indexed by the potentially sparsely numbered pnode.
This patch is critical to tlb shootdown on a partitioned UV system, or one with nonconsecutive blade numbers.
---
The distribution map bits represent pnodes relative to the partition base pnode. Previous to this patch it had been assuming bits based on 0-based, consecutive blade ids.
arch/x86/platform/uv/tlb_uv.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-)
arch/x86/platform/uv/tlb_uv.c +21 -12
@@ -296,14 +296,18 @@ static void bau_process_message(struct m }/* -* Determine the first cpu on a uvhub. +* Determine the first cpu on a pnode. */ -static int uvhub_to_first_cpu (int uvhub) +static int pnode_to_first_cpu (int pnode,struct bau_control *smaster) {int cpu; -for_each_present_cpu (cpu) -if (uvhub ==uv_cpu_to_blade_id (cpu)) +struct hub_and_pnode *hpp; + +for_each_present_cpu (cpu) { + hpp = &smaster->thp[cpu]; +if (pnode == hpp->pnode)return cpu; + }return -1 ; }
@@ -366,23 +370,28 @@ static void do_reset(void *ptr)* Use IPI to get all target uvhubs to release resources held by * a given sending cpu number. */ -static void reset_with_ipi (struct bau_targ_hubmask *distribution,int sender) +static void reset_with_ipi (struct bau_targ_hubmask *distribution, +struct bau_control *bcp) { -int uvhub; +int pnode; +int apnode;int maskbits;cpumask_t mask; +int sender = bcp->cpu; +struct bau_control *smaster = bcp->socket_master;struct reset_args reset_args; reset_args.sender = sender;cpus_clear (mask);/* find a single cpu for each uvhub in this distribution mask */ maskbits =sizeof (struct bau_targ_hubmask ) *BITSPERBYTE ; -for (uvhub =0 ; uvhub < maskbits; uvhub++) { +/* each bit is a pnode relative to the partition base pnode */ +for (pnode =0 ; pnode < maskbits; pnode++) {int cpu; -if (!bau_uvhub_isset (uvhub, distribution)) +if (!bau_uvhub_isset (pnode, distribution))continue ; -/* find a cpu for this uvhub */ - cpu =uvhub_to_first_cpu (uvhub); + apnode = pnode + bcp->partition_base_pnode; + cpu =pnode_to_first_cpu (apnode, smaster);cpu_set (cpu, mask); }
@@ -604,7 +613,7 @@ static void destination_plugged(struct bquiesce_local_uvhub (hmaster);spin_lock (&hmaster->queue_lock); -reset_with_ipi (&bau_desc->distribution, bcp->cpu); +reset_with_ipi (&bau_desc->distribution, bcp);spin_unlock (&hmaster->queue_lock);end_uvhub_quiesce (hmaster);
@@ -626,7 +635,7 @@ static void destination_timeout(struct bquiesce_local_uvhub (hmaster);spin_lock (&hmaster->queue_lock); -reset_with_ipi (&bau_desc->distribution, bcp->cpu); +reset_with_ipi (&bau_desc->distribution, bcp);spin_unlock (&hmaster->queue_lock);end_uvhub_quiesce (hmaster);
[tip:x86/uv] x86, UV: Correct reset_with_ipi()
Commit-ID: 485f07d349a3e5059413b886a3bc1996c4b3d14d Gitweb: http://git.kernel.org/tip/485f07d349a3e5059413b886a3bc1996c4b3d14d Author: [email protected] <[email protected]> AuthorDate: Tue, 21 Jun 2011 07:21:29 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 21 Jun 2011 14:50:32 +0200
x86, UV: Correct reset_with_ipi()
Fix reset_with_ipi() to look up a cpu for a blade based on the distribution map being indexed by the potentially sparsely numbered pnode.
This patch is critical to tlb shootdown on a partitioned UV system, or one with nonconsecutive blade numbers.
The distribution map bits represent pnodes relative to the partition base pnode. Previous to this patch it had been assuming bits based on 0-based, consecutive blade ids.
--- arch/x86/platform/uv/tlb_uv.c | 33 +++++++++++++++++++++------------ 1 files changed, 21 insertions(+), 12 deletions(-)
arch/x86/platform/uv/tlb_uv.c +21 -12
@@ -296,14 +296,18 @@ static void bau_process_message(struct msg_desc *mdp, }/* -* Determine the first cpu on a uvhub. +* Determine the first cpu on a pnode. */ -static int uvhub_to_first_cpu (int uvhub) +static int pnode_to_first_cpu (int pnode,struct bau_control *smaster) {int cpu; -for_each_present_cpu (cpu) -if (uvhub ==uv_cpu_to_blade_id (cpu)) +struct hub_and_pnode *hpp; + +for_each_present_cpu (cpu) { + hpp = &smaster->thp[cpu]; +if (pnode == hpp->pnode)return cpu; + }return -1 ; }
@@ -366,23 +370,28 @@ static void do_reset(void *ptr)* Use IPI to get all target uvhubs to release resources held by * a given sending cpu number. */ -static void reset_with_ipi (struct bau_targ_hubmask *distribution,int sender) +static void reset_with_ipi (struct bau_targ_hubmask *distribution, +struct bau_control *bcp) { -int uvhub; +int pnode; +int apnode;int maskbits;cpumask_t mask; +int sender = bcp->cpu; +struct bau_control *smaster = bcp->socket_master;struct reset_args reset_args; reset_args.sender = sender;cpus_clear (mask);/* find a single cpu for each uvhub in this distribution mask */ maskbits =sizeof (struct bau_targ_hubmask ) *BITSPERBYTE ; -for (uvhub =0 ; uvhub < maskbits; uvhub++) { +/* each bit is a pnode relative to the partition base pnode */ +for (pnode =0 ; pnode < maskbits; pnode++) {int cpu; -if (!bau_uvhub_isset (uvhub, distribution)) +if (!bau_uvhub_isset (pnode, distribution))continue ; -/* find a cpu for this uvhub */ - cpu =uvhub_to_first_cpu (uvhub); + apnode = pnode + bcp->partition_base_pnode; + cpu =pnode_to_first_cpu (apnode, smaster);cpu_set (cpu, mask); }
@@ -604,7 +613,7 @@ static void destination_plugged(struct bau_desc *bau_desc,quiesce_local_uvhub (hmaster);spin_lock (&hmaster->queue_lock); -reset_with_ipi (&bau_desc->distribution, bcp->cpu); +reset_with_ipi (&bau_desc->distribution, bcp);spin_unlock (&hmaster->queue_lock);end_uvhub_quiesce (hmaster);
@@ -626,7 +635,7 @@ static void destination_timeout(struct bau_desc *bau_desc,quiesce_local_uvhub (hmaster);spin_lock (&hmaster->queue_lock); -reset_with_ipi (&bau_desc->distribution, bcp->cpu); +reset_with_ipi (&bau_desc->distribution, bcp);spin_unlock (&hmaster->queue_lock);end_uvhub_quiesce (hmaster);
PATCH v5 5/8 x86, UV: rename hubmask to pnmask
In reply to [email protected]Rename 'bau_targ_hubmask' to 'pnmask' for clarity.
---
The BAU distribution bit mask is indexed by pnode number, not hub or blade number. This important fact is not clear while the mask is called a 'hubmask'.
arch/x86/include/asm/uv/uv_bau.h | 12 ++++++------ arch/x86/platform/uv/tlb_uv.c | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +6 -6
@@ -183,7 +183,7 @@* 'base_dest_nasid' field of the header corresponds to the * destination nodeID associated with that specified bit. */ -struct bau_targ_hubmask { +struct pnmask {unsigned long bits[BITS_TO_LONGS (UV_DISTRIBUTION_SIZE )]; };
@@ -314,7 +314,7 @@ struct bau_msg_header {* Should be 64 bytes */ struct bau_desc { -struct bau_targ_hubmask distribution; +struct pnmask distribution;/* * message template, consisting of header and payload: */
@@ -596,20 +596,20 @@ static inline void write_mmr_data_configuv_write_global_mmr64 (pnode,UVH_BAU_DATA_CONFIG , mr); } -static inline int bau_uvhub_isset (int uvhub,struct bau_targ_hubmask *dstp) +static inline int bau_uvhub_isset (int uvhub,struct pnmask *dstp) {return constant_test_bit (uvhub, &dstp->bits[0 ]); } -static inline void bau_uvhub_set (int pnode,struct bau_targ_hubmask *dstp) +static inline void bau_uvhub_set (int pnode,struct pnmask *dstp) {__set_bit (pnode, &dstp->bits[0 ]); } -static inline void bau_uvhubs_clear (struct bau_targ_hubmask *dstp, +static inline void bau_uvhubs_clear (struct pnmask *dstp,int nbits) {bitmap_zero (&dstp->bits[0 ], nbits); } -static inline int bau_uvhub_weight (struct bau_targ_hubmask *dstp) +static inline int bau_uvhub_weight (struct pnmask *dstp) {return bitmap_weight ((unsigned long *)&dstp->bits[0 ],UV_DISTRIBUTION_SIZE );
arch/x86/platform/uv/tlb_uv.c +2 -3
@@ -370,8 +370,7 @@ static void do_reset(void *ptr)* Use IPI to get all target uvhubs to release resources held by * a given sending cpu number. */ -static void reset_with_ipi (struct bau_targ_hubmask *distribution, -struct bau_control *bcp) +static void reset_with_ipi (struct pnmask *distribution,struct bau_control *bcp) {int pnode;int apnode;
@@ -384,7 +383,7 @@ static void reset_with_ipi(struct bau_ta reset_args.sender = sender;cpus_clear (mask);/* find a single cpu for each uvhub in this distribution mask */ - maskbits =sizeof (struct bau_targ_hubmask ) *BITSPERBYTE ; + maskbits =sizeof (struct pnmask ) *BITSPERBYTE ;/* each bit is a pnode relative to the partition base pnode */ for (pnode =0 ; pnode < maskbits; pnode++) {int cpu;
[tip:x86/uv] x86, UV: Rename hubmask to pnmask
Commit-ID: a456eaab87461e33d94e748565eabd474283a475 Gitweb: http://git.kernel.org/tip/a456eaab87461e33d94e748565eabd474283a475 Author: [email protected] <[email protected]> AuthorDate: Tue, 21 Jun 2011 07:21:30 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 21 Jun 2011 14:50:32 +0200
x86, UV: Rename hubmask to pnmask
Rename 'bau_targ_hubmask' to 'pnmask' for clarity.
The BAU distribution bit mask is indexed by pnode number, not hub or blade number. This important fact is not clear while the mask is called a 'hubmask'.
--- arch/x86/include/asm/uv/uv_bau.h | 12 ++++++------ arch/x86/platform/uv/tlb_uv.c | 5 ++--- 2 files changed, 8 insertions(+), 9 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +6 -6
@@ -183,7 +183,7 @@* 'base_dest_nasid' field of the header corresponds to the * destination nodeID associated with that specified bit. */ -struct bau_targ_hubmask { +struct pnmask {unsigned long bits[BITS_TO_LONGS (UV_DISTRIBUTION_SIZE )]; };
@@ -314,7 +314,7 @@ struct bau_msg_header {* Should be 64 bytes */ struct bau_desc { -struct bau_targ_hubmask distribution; +struct pnmask distribution;/* * message template, consisting of header and payload: */
@@ -596,20 +596,20 @@ static inline void write_mmr_data_config(int pnode, unsigned long mr)uv_write_global_mmr64 (pnode,UVH_BAU_DATA_CONFIG , mr); } -static inline int bau_uvhub_isset (int uvhub,struct bau_targ_hubmask *dstp) +static inline int bau_uvhub_isset (int uvhub,struct pnmask *dstp) {return constant_test_bit (uvhub, &dstp->bits[0 ]); } -static inline void bau_uvhub_set (int pnode,struct bau_targ_hubmask *dstp) +static inline void bau_uvhub_set (int pnode,struct pnmask *dstp) {__set_bit (pnode, &dstp->bits[0 ]); } -static inline void bau_uvhubs_clear (struct bau_targ_hubmask *dstp, +static inline void bau_uvhubs_clear (struct pnmask *dstp,int nbits) {bitmap_zero (&dstp->bits[0 ], nbits); } -static inline int bau_uvhub_weight (struct bau_targ_hubmask *dstp) +static inline int bau_uvhub_weight (struct pnmask *dstp) {return bitmap_weight ((unsigned long *)&dstp->bits[0 ],UV_DISTRIBUTION_SIZE );
arch/x86/platform/uv/tlb_uv.c +2 -3
@@ -370,8 +370,7 @@ static void do_reset(void *ptr)* Use IPI to get all target uvhubs to release resources held by * a given sending cpu number. */ -static void reset_with_ipi (struct bau_targ_hubmask *distribution, -struct bau_control *bcp) +static void reset_with_ipi (struct pnmask *distribution,struct bau_control *bcp) {int pnode;int apnode;
@@ -384,7 +383,7 @@ static void reset_with_ipi(struct bau_targ_hubmask *distribution, reset_args.sender = sender;cpus_clear (mask);/* find a single cpu for each uvhub in this distribution mask */ - maskbits =sizeof (struct bau_targ_hubmask ) *BITSPERBYTE ; + maskbits =sizeof (struct pnmask ) *BITSPERBYTE ;/* each bit is a pnode relative to the partition base pnode */ for (pnode =0 ; pnode < maskbits; pnode++) {int cpu;
PATCH v5 6/8 x86, UV: remove cpumask_t from the stack
In reply to [email protected]Remove the large stack-resident cpumask_t from reset_with_ipi()'s stack by allocating one per uvhub.
---
Due to the limited size of the stack the potentially huge cpumask_t may cause stack overrun. We haven't seen it happen yet, but we need to make it a practice not to push such structures onto the stack.
arch/x86/include/asm/uv/uv_bau.h | 1 + arch/x86/platform/uv/tlb_uv.c | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +1 -0
@@ -488,6 +488,7 @@ struct bau_control {struct bau_control *uvhub_master;struct bau_control *socket_master;struct ptc_stats *statp; +cpumask_t *cpumask;unsigned long timeout_interval;unsigned long set_bau_on_time;atomic_t active_descriptor_count;
arch/x86/platform/uv/tlb_uv.c +15 -4
@@ -375,13 +375,13 @@ static void reset_with_ipi(struct pnmaskint pnode;int apnode;int maskbits; -cpumask_t mask;int sender = bcp->cpu; +cpumask_t *mask = bcp->uvhub_master->cpumask;struct bau_control *smaster = bcp->socket_master;struct reset_args reset_args; reset_args.sender = sender; -cpus_clear (mask); +cpus_clear (*mask);/* find a single cpu for each uvhub in this distribution mask */ maskbits =sizeof (struct pnmask ) *BITSPERBYTE ;/* each bit is a pnode relative to the partition base pnode */
@@ -391,11 +391,11 @@ static void reset_with_ipi(struct pnmaskcontinue ; apnode = pnode + bcp->partition_base_pnode; cpu =pnode_to_first_cpu (apnode, smaster); -cpu_set (cpu, mask); +cpu_set (cpu, *mask); }/* IPI all cpus; preemption is already disabled */ -smp_call_function_many (&mask, do_reset, (void *)&reset_args,1 ); +smp_call_function_many (mask, do_reset, (void *)&reset_args,1 );return ; }
@@ -1696,6 +1696,16 @@ static void make_per_cpu_thp(struct bau_ }/* +* Each uvhub is to get a local cpumask. +*/ +static void make_per_hub_cpumask (struct bau_control *hmaster) +{ +int sz =sizeof (cpumask_t); + + hmaster->cpumask =kzalloc_node (sz,GFP_KERNEL , hmaster->osnode); +} + +/* * Initialize all the per_cpu information for the cpu's on a given socket, * given what has been gathered into the socket_desc struct. * And reports the chosen hub and socket masters back to the caller.
@@ -1765,6 +1775,7 @@ static int __init summarize_uvhub_socket socket++; socket_mask = (socket_mask >>1 ); } +make_per_hub_cpumask (hmaster); }return 0 ; }
[tip:x86/uv] x86, UV: Remove cpumask_t from the stack
Commit-ID: 442d3924926c62741912d8a930220af253922007 Gitweb: http://git.kernel.org/tip/442d3924926c62741912d8a930220af253922007 Author: [email protected] <[email protected]> AuthorDate: Tue, 21 Jun 2011 07:21:31 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 21 Jun 2011 14:50:33 +0200
x86, UV: Remove cpumask_t from the stack
Remove the large stack-resident cpumask_t from reset_with_ipi()'s stack by allocating one per uvhub.
Due to the limited size of the stack the potentially huge cpumask_t may cause stack overrun. We haven't seen it happen yet, but we need to make it a practice not to push such structures onto the stack.
--- arch/x86/include/asm/uv/uv_bau.h | 1 + arch/x86/platform/uv/tlb_uv.c | 19 +++++++++++++++---- 2 files changed, 16 insertions(+), 4 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +1 -0
@@ -488,6 +488,7 @@ struct bau_control {struct bau_control *uvhub_master;struct bau_control *socket_master;struct ptc_stats *statp; +cpumask_t *cpumask;unsigned long timeout_interval;unsigned long set_bau_on_time;atomic_t active_descriptor_count;
arch/x86/platform/uv/tlb_uv.c +15 -4
@@ -375,13 +375,13 @@ static void reset_with_ipi(struct pnmask *distribution, struct bau_control *bcp)int pnode;int apnode;int maskbits; -cpumask_t mask;int sender = bcp->cpu; +cpumask_t *mask = bcp->uvhub_master->cpumask;struct bau_control *smaster = bcp->socket_master;struct reset_args reset_args; reset_args.sender = sender; -cpus_clear (mask); +cpus_clear (*mask);/* find a single cpu for each uvhub in this distribution mask */ maskbits =sizeof (struct pnmask ) *BITSPERBYTE ;/* each bit is a pnode relative to the partition base pnode */
@@ -391,11 +391,11 @@ static void reset_with_ipi(struct pnmask *distribution, struct bau_control *bcp)continue ; apnode = pnode + bcp->partition_base_pnode; cpu =pnode_to_first_cpu (apnode, smaster); -cpu_set (cpu, mask); +cpu_set (cpu, *mask); }/* IPI all cpus; preemption is already disabled */ -smp_call_function_many (&mask, do_reset, (void *)&reset_args,1 ); +smp_call_function_many (mask, do_reset, (void *)&reset_args,1 );return ; }
@@ -1696,6 +1696,16 @@ static void make_per_cpu_thp(struct bau_control *smaster) }/* +* Each uvhub is to get a local cpumask. +*/ +static void make_per_hub_cpumask (struct bau_control *hmaster) +{ +int sz =sizeof (cpumask_t); + + hmaster->cpumask =kzalloc_node (sz,GFP_KERNEL , hmaster->osnode); +} + +/* * Initialize all the per_cpu information for the cpu's on a given socket, * given what has been gathered into the socket_desc struct. * And reports the chosen hub and socket masters back to the caller.
@@ -1765,6 +1775,7 @@ static int __init summarize_uvhub_sockets(int nuvhubs, socket++; socket_mask = (socket_mask >>1 ); } +make_per_hub_cpumask (hmaster); }return 0 ; }
PATCH v5 7/8 x86, UV: correct failed topology memory leak
In reply to [email protected]Fix a memory leak in init_per_cpu() when the topology check fails.
---
The leak should never occur after development. It would only occur in an unexpected topology that would make the BAU unuseable as a result.
arch/x86/platform/uv/tlb_uv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
arch/x86/platform/uv/tlb_uv.c +7 -2
@@ -1797,15 +1797,20 @@ static int __init init_per_cpu(int nuvhu uvhub_mask =kzalloc ((nuvhubs+7 )/8 ,GFP_KERNEL );if (get_cpu_topology (base_part_pnode, uvhub_descs, uvhub_mask)) -return 1 ; + goto fail;if (summarize_uvhub_sockets (nuvhubs, uvhub_descs, uvhub_mask)) -return 1 ; + goto fail;kfree (uvhub_descs);kfree (uvhub_mask);init_per_cpu_tunables ();return 0 ; + +fail: +kfree (uvhub_descs); +kfree (uvhub_mask); +return 1 ; }/*
[tip:x86/uv] x86, UV: Correct failed topology memory leak
Commit-ID: bbd270e6f45a5ca30e1d3b6133c516a9dc9dd6c0 Gitweb: http://git.kernel.org/tip/bbd270e6f45a5ca30e1d3b6133c516a9dc9dd6c0 Author: [email protected] <[email protected]> AuthorDate: Tue, 21 Jun 2011 07:21:32 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 21 Jun 2011 14:50:33 +0200
x86, UV: Correct failed topology memory leak
Fix a memory leak in init_per_cpu() when the topology check fails.
The leak should never occur on deployed systems. It would only occur in an unexpected topology that would make the BAU unuseable as a result.
--- arch/x86/platform/uv/tlb_uv.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
arch/x86/platform/uv/tlb_uv.c +7 -2
@@ -1797,15 +1797,20 @@ static int __init init_per_cpu(int nuvhubs, int base_part_pnode) uvhub_mask =kzalloc ((nuvhubs+7 )/8 ,GFP_KERNEL );if (get_cpu_topology (base_part_pnode, uvhub_descs, uvhub_mask)) -return 1 ; + goto fail;if (summarize_uvhub_sockets (nuvhubs, uvhub_descs, uvhub_mask)) -return 1 ; + goto fail;kfree (uvhub_descs);kfree (uvhub_mask);init_per_cpu_tunables ();return 0 ; + +fail: +kfree (uvhub_descs); +kfree (uvhub_mask); +return 1 ; }/*
PATCH v5 8/8 x86, UV: correct UV2 BAU destination timeout
In reply to [email protected]Correct the UV2 broacast assist unit's destination timeout period. And the activation status register in UV2 should be tested for a destination timeout with a 4, not a 2. The values for Active versus Timeout were reversed.
This patch is critical for TLB shootdown on an Altix UV2 system (i.e. the follow-on to the current Altix UV).
---
Destination timeout period:
The period is set in 4 bits of memory-mapped register MISC_CONTROL. The left bit toggles base period between 10us and 80us. The other 3 bits are the multiplier.
Decimal 15, hex f, gives the maximum: 7 * 80us
arch/x86/include/asm/uv/uv_bau.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +13 -5
@@ -67,7 +67,7 @@* we're using 655us, similar to UV1: 65 units of 10us */ #define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL) -#define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (65*10UL) +#define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (15UL)#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD (is_uv1_hub() ? \ UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \
@@ -106,12 +106,20 @@#define DS_SOURCE_TIMEOUT 3/* * bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 -* values 1 and 5 will not occur +* values 1 and 3 will not occur +* Decoded meaning ERROR BUSY AUX ERR +* ------------------------------- ---- ----- ------- +* IDLE 0 0 0 +* BUSY (active) 0 1 0 +* SW Ack Timeout (destination) 1 0 0 +* SW Ack INTD rejected (strong NACK) 1 0 1 +* Source Side Time Out Detected 1 1 0 +* Destination Side PUT Failed 1 1 1 */ #define UV2H_DESC_IDLE 0 -#define UV2H_DESC_DEST_TIMEOUT 2 -#define UV2H_DESC_DEST_STRONG_NACK 3 -#define UV2H_DESC_BUSY 4 +#define UV2H_DESC_BUSY 2 +#define UV2H_DESC_DEST_TIMEOUT 4 +#define UV2H_DESC_DEST_STRONG_NACK 5#define UV2H_DESC_SOURCE_TIMEOUT 6#define UV2H_DESC_DEST_PUT_ERR 7
[tip:x86/uv] x86, UV: Correct UV2 BAU destination timeout
Commit-ID: ae90c232be376bd8a283f3b6fb37cb5bd2635d67 Gitweb: http://git.kernel.org/tip/ae90c232be376bd8a283f3b6fb37cb5bd2635d67 Author: [email protected] <[email protected]> AuthorDate: Tue, 21 Jun 2011 07:21:33 -0500 Committer: Ingo Molnar <[email protected]> CommitDate: Tue, 21 Jun 2011 14:50:34 +0200
x86, UV: Correct UV2 BAU destination timeout
Correct the UV2 broacast assist unit's destination timeout period. And the activation status register in UV2 should be tested for a destination timeout with a 4, not a 2. The values for Active versus Timeout were reversed.
This patch is critical for TLB shootdown on an Altix UV2 system (i.e. the follow-on to the current Altix UV).
Destination timeout period:
The period is set in 4 bits of memory-mapped register MISC_CONTROL. The left bit toggles base period between 10us and 80us. The other 3 bits are the multiplier.
Decimal 15, hex f, gives the maximum: 7 * 80us
--- arch/x86/include/asm/uv/uv_bau.h | 18 +++++++++++++----- 1 files changed, 13 insertions(+), 5 deletions(-)
arch/x86/include/asm/uv/uv_bau.h +13 -5
@@ -67,7 +67,7 @@* we're using 655us, similar to UV1: 65 units of 10us */ #define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL) -#define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (65*10UL) +#define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (15UL)#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD (is_uv1_hub() ? \ UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD : \
@@ -106,12 +106,20 @@#define DS_SOURCE_TIMEOUT 3/* * bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2 -* values 1 and 5 will not occur +* values 1 and 3 will not occur +* Decoded meaning ERROR BUSY AUX ERR +* ------------------------------- ---- ----- ------- +* IDLE 0 0 0 +* BUSY (active) 0 1 0 +* SW Ack Timeout (destination) 1 0 0 +* SW Ack INTD rejected (strong NACK) 1 0 1 +* Source Side Time Out Detected 1 1 0 +* Destination Side PUT Failed 1 1 1 */ #define UV2H_DESC_IDLE 0 -#define UV2H_DESC_DEST_TIMEOUT 2 -#define UV2H_DESC_DEST_STRONG_NACK 3 -#define UV2H_DESC_BUSY 4 +#define UV2H_DESC_BUSY 2 +#define UV2H_DESC_DEST_TIMEOUT 4 +#define UV2H_DESC_DEST_STRONG_NACK 5#define UV2H_DESC_SOURCE_TIMEOUT 6#define UV2H_DESC_DEST_PUT_ERR 7