From e4283176ae373ed617bddf068d363fd858e61423 Mon Sep 17 00:00:00 2001 From: Tomas Hruby Date: Wed, 15 Sep 2010 14:11:17 +0000 Subject: [PATCH] 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 --- kernel/arch/i386/include/arch_proto.h | 2 ++ kernel/arch/i386/klib.S | 17 +++++++++++++---- kernel/proc.c | 2 ++ 3 files changed, 17 insertions(+), 4 deletions(-) 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 -- 2.44.0