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
This commit is contained in:
Tomas Hruby 2010-09-15 14:11:17 +00:00
parent 6513d20744
commit e4283176ae
3 changed files with 17 additions and 4 deletions

View File

@ -109,6 +109,8 @@ _PROTOTYPE(void __switch_address_space, (struct proc * p,
#define switch_address_space(proc) \ #define switch_address_space(proc) \
__switch_address_space(proc, get_cpulocal_var_ptr(ptproc)) __switch_address_space(proc, get_cpulocal_var_ptr(ptproc))
_PROTOTYPE(void refresh_tlb, (void));
/* protect.c */ /* protect.c */
struct tss_s { struct tss_s {
reg_t backlink; reg_t backlink;

View File

@ -803,9 +803,11 @@ ENTRY(__switch_address_space)
* test if the cr3 is loaded with the current value to avoid unnecessary * test if the cr3 is loaded with the current value to avoid unnecessary
* TLB flushes * TLB flushes
*/ */
#if 0
mov %cr3, %ecx mov %cr3, %ecx
cmp %ecx, %eax cmp %ecx, %eax
je 0f je 0f
#endif
mov %eax, %cr3 mov %eax, %cr3
/* get ptproc */ /* get ptproc */
mov 8(%esp), %eax mov 8(%esp), %eax
@ -872,10 +874,12 @@ ENTRY(eoi_8259_slave)
outb $INT2_CTL outb $INT2_CTL
ret ret
.data /* in some cases we need to force TLB update, reloading cr3 does the trick */
idt_ptr: ENTRY(refresh_tlb)
.short 0x3ff mov %cr3, %eax
.long 0x0 mov %eax, %cr3
ret
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/*===========================================================================*/ /*===========================================================================*/
@ -1043,3 +1047,8 @@ ENTRY(switch_k_stack)
/* NOT_REACHABLE */ /* NOT_REACHABLE */
0: jmp 0b 0: jmp 0b
.data
idt_ptr:
.short 0x3ff
.long 0x0

View File

@ -356,6 +356,8 @@ check_misc_flags:
*/ */
p->p_misc_flags &= ~MF_CONTEXT_SET; 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 * restore_user_context() carries out the actual mode switch from kernel
* to userspace. This function does not return * to userspace. This function does not return