From: Tomas Hruby Date: Wed, 15 Sep 2010 14:11:17 +0000 (+0000) Subject: SMP - Force TLB flush before scheduling a process X-Git-Tag: v3.2.0~842 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/rndc.html?a=commitdiff_plain;h=e4283176ae373ed617bddf068d363fd858e61423;p=minix.git SMP - Force TLB flush before scheduling a process - this makes sure that each process always run with updated TLB - this is the simplest way how to achieve the consistency. As it means significant performace degradation when not require, this is nto the final solution and will be refined --- diff --git a/kernel/arch/i386/include/arch_proto.h b/kernel/arch/i386/include/arch_proto.h index 0d9238999..89c57bc82 100644 --- a/kernel/arch/i386/include/arch_proto.h +++ b/kernel/arch/i386/include/arch_proto.h @@ -109,6 +109,8 @@ _PROTOTYPE(void __switch_address_space, (struct proc * p, #define switch_address_space(proc) \ __switch_address_space(proc, get_cpulocal_var_ptr(ptproc)) +_PROTOTYPE(void refresh_tlb, (void)); + /* protect.c */ struct tss_s { reg_t backlink; diff --git a/kernel/arch/i386/klib.S b/kernel/arch/i386/klib.S index decb55a7d..e7e7feb89 100644 --- a/kernel/arch/i386/klib.S +++ b/kernel/arch/i386/klib.S @@ -803,9 +803,11 @@ ENTRY(__switch_address_space) * test if the cr3 is loaded with the current value to avoid unnecessary * TLB flushes */ +#if 0 mov %cr3, %ecx cmp %ecx, %eax je 0f +#endif mov %eax, %cr3 /* get ptproc */ mov 8(%esp), %eax @@ -872,10 +874,12 @@ ENTRY(eoi_8259_slave) outb $INT2_CTL ret -.data -idt_ptr: - .short 0x3ff - .long 0x0 +/* in some cases we need to force TLB update, reloading cr3 does the trick */ +ENTRY(refresh_tlb) + mov %cr3, %eax + mov %eax, %cr3 + ret + #ifdef CONFIG_SMP /*===========================================================================*/ @@ -1043,3 +1047,8 @@ ENTRY(switch_k_stack) /* NOT_REACHABLE */ 0: jmp 0b + +.data +idt_ptr: + .short 0x3ff + .long 0x0 diff --git a/kernel/proc.c b/kernel/proc.c index 7f36fc728..3728a3c55 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -356,6 +356,8 @@ check_misc_flags: */ p->p_misc_flags &= ~MF_CONTEXT_SET; + assert(!(p->p_misc_flags & MF_FULLVM) || p->p_seg.p_cr3 != 0); + refresh_tlb(); /* * restore_user_context() carries out the actual mode switch from kernel * to userspace. This function does not return