lkml.org 
[lkml]   [1999]   [Jul]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[RFC] [PATCH] lazy TLB: possible bug, some notes (2.3.12)
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--- 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)


\
 
 \ /
  Last update: 2005-03-22 13:53    [W:0.042 / U:0.076 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site