Skip to content

Commit

Permalink
arch/x86/platform/uv: Fix incorrect tlb flush all issue
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alex Shi authored and Ingo Molnar committed Jan 24, 2013
1 parent 444723d commit 57c4f43
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 4 deletions.
2 changes: 1 addition & 1 deletion arch/x86/include/asm/uv/uv.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
10 changes: 7 additions & 3 deletions arch/x86/platform/uv/tlb_uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 57c4f43

Please sign in to comment.