mirror of https://gitee.com/openkylin/linux.git
arch/x86/platform/uv: Fix incorrect tlb flush all issue
The flush tlb optimization code has logical issue on UV platform. It doesn't flush the full range at all, since it simply ignores its 'end' parameter (and hence also the "all" indicator) in uv_flush_tlb_others() function. Cliff's notes: | I tested the patch on a UV. It has the effect of either | clearing 1 or all TLBs in a cpu. I added some debugging to | test for the cases when clearing all TLBs is overkill, and in | practice it happens very seldom. Reported-by: Jan Beulich <jbeulich@suse.com> Signed-off-by: Alex Shi <alex.shi@intel.com> Signed-off-by: Cliff Wickman <cpw@sgi.com> Tested-by: Cliff Wickman <cpw@sgi.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
parent
444723dccc
commit
57c4f43043
|
@ -16,7 +16,7 @@ extern void uv_system_init(void);
|
|||
extern const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
||||
struct mm_struct *mm,
|
||||
unsigned long start,
|
||||
unsigned end,
|
||||
unsigned long end,
|
||||
unsigned int cpu);
|
||||
|
||||
#else /* X86_UV */
|
||||
|
|
|
@ -1034,7 +1034,8 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp,
|
|||
* globally purge translation cache of a virtual address or all TLB's
|
||||
* @cpumask: mask of all cpu's in which the address is to be removed
|
||||
* @mm: mm_struct containing virtual address range
|
||||
* @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu)
|
||||
* @start: start virtual address to be removed from TLB
|
||||
* @end: end virtual address to be remove from TLB
|
||||
* @cpu: the current cpu
|
||||
*
|
||||
* This is the entry point for initiating any UV global TLB shootdown.
|
||||
|
@ -1056,7 +1057,7 @@ static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp,
|
|||
*/
|
||||
const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
||||
struct mm_struct *mm, unsigned long start,
|
||||
unsigned end, unsigned int cpu)
|
||||
unsigned long end, unsigned int cpu)
|
||||
{
|
||||
int locals = 0;
|
||||
int remotes = 0;
|
||||
|
@ -1113,7 +1114,10 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
|
|||
|
||||
record_send_statistics(stat, locals, hubs, remotes, bau_desc);
|
||||
|
||||
bau_desc->payload.address = start;
|
||||
if (!end || (end - start) <= PAGE_SIZE)
|
||||
bau_desc->payload.address = start;
|
||||
else
|
||||
bau_desc->payload.address = TLB_FLUSH_ALL;
|
||||
bau_desc->payload.sending_cpu = cpu;
|
||||
/*
|
||||
* uv_flush_send_and_wait returns 0 if all cpu's were messaged,
|
||||
|
|
Loading…
Reference in New Issue