Re: [PATCH v4 3/7] x86/flush_tlb: try flush_tlb_single one by onein flush_tlb_range

From: Alex Shi
Date: Mon May 14 2012 - 21:07:39 EST



> --
>
> Oh well, enough games :-).
>




Thanks for your input. but actually, total 3 labels doesn't looks good.
Maybe the following lines can meet your expectation.

---
void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
unsigned long end, unsigned long vmflag)
{
unsigned long addr;
unsigned act_entries, tlb_entries = 0;

preempt_disable();
if (current->active_mm != mm)
goto flush_all;

if (!current->mm) {
leave_mm(smp_processor_id());
goto flush_all;
}

if (end == TLB_FLUSH_ALL ||
tlb_flushall_shift == (u16)TLB_FLUSH_ALL) {
local_flush_tlb();
goto flush_all;
}

if (vmflag & VM_EXEC)
tlb_entries = tlb_lli_4k[ENTRIES];
else
tlb_entries = tlb_lld_4k[ENTRIES];
act_entries = mm->total_vm > tlb_entries ? tlb_entries : mm->total_vm;

if ((end - start) >> PAGE_SHIFT > act_entries >> tlb_flushall_shift)
local_flush_tlb();
else {
if (has_large_page(mm, start, end)) {
local_flush_tlb();
goto flush_all;
}
for (addr = start; addr <= end; addr += PAGE_SIZE)
__flush_tlb_single(addr);

if (cpumask_any_but(mm_cpumask(mm),
smp_processor_id()) < nr_cpu_ids)
flush_tlb_others(mm_cpumask(mm), mm, start, end);
preempt_enable();
return;
}

flush_all:
if (cpumask_any_but(mm_cpumask(mm), smp_processor_id()) < nr_cpu_ids)
flush_tlb_others(mm_cpumask(mm), mm, 0UL, TLB_FLUSH_ALL);
preempt_enable();
}


--
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/