[RFC] [PATCH] lazy TLB: possible bug, some notes (2.3.12)

Manfred Spraul (manfreds@colorfullife.com)
Fri, 30 Jul 1999 19:34:01 +0200


This is a multi-part message in MIME format.
--------------5880E7229165EFDF351F21DD
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

1) I've attached a small patch which should fix 2 possible
problems on the i386.
* mm->cpu_vm_mask was not set on crossing TLB flushes.
* there was a race in flush_tlb_current_task() between setting
mm->cpu_vm_mask and the IPI which could modify cpu_vm_mask.

Since flush_tlb_current_task() is now identical to
flush_tlb_mm(current->mm), I'd remove flush_tlb_current_task()
and change the macro for flush_tlb(). [in include/asm/pgtable.h]

2) I think it should be possible to call start_lazy_tlb()
even if the thread is already in the lazy-tlb mode.
i.e. multiple calls to start_lazy_tlb() should be possible
as long as you call end_lazy_tlb() for every start_lazy_tlb()
call.
Curently, this would oops.

3) I noticed that 2.3.12 breaks the PPC mm implementation:
mmu_context_overflow() assumes that it can get to all
mm's by looking at tsk->mm for all tasks in the system.
(arch/ppc/mm/init.c)

This is not correct any more: if a user thread executes
sys_bdflush(), then this mm will not be referenced
from tsk->mm.
[I don't have a PPC, but it looks wrong]

--
	Manfred
--------------5880E7229165EFDF351F21DD
Content-Type: text/plain; charset=us-ascii;
 name="smp.c.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="smp.c.diff"

--- 2.3/arch/i386/kernel/smp.c Thu Jul 29 15:23:06 1999 +++ build-2.3/arch/i386/kernel/smp.c Fri Jul 30 19:27:02 1999 @@ -1617,6 +1617,8 @@ if (test_bit(cpu, &smp_invalidate_needed)) { clear_bit(cpu, &smp_invalidate_needed); local_flush_tlb(); + if(current->mm) + atomic_set_mask(1 << cpu, &current->mm->cpu_vm_mask); } --stuck; if (!stuck) { @@ -1637,14 +1639,16 @@ */ void flush_tlb_current_task(void) { - unsigned long vm_mask = 1 << current->processor; struct mm_struct *mm = current->mm; + unsigned long vm_mask = 1 << current->processor; + unsigned long cpu_mask = mm->cpu_vm_mask & ~vm_mask; - if (mm->cpu_vm_mask != vm_mask) { - flush_tlb_others(mm->cpu_vm_mask & ~vm_mask); + mm->cpu_vm_mask = 0; + if (current->active_mm == mm) { mm->cpu_vm_mask = vm_mask; + local_flush_tlb(); } - local_flush_tlb(); + flush_tlb_others(cpu_mask); } void flush_tlb_mm(struct mm_struct * mm)

--------------5880E7229165EFDF351F21DD--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/