SMP - reduced TLB flushing
- flush TLB of processes only if the page tables has been changed and the page tables of this process are already loaded on this cpu which means that there might be stale entries in TLB. Until now SMP was always flushing TLB to make sure everything is consistent.
This commit is contained in:
parent
7f7822aebd
commit
9e01a83636
4 changed files with 18 additions and 3 deletions
|
@ -803,11 +803,9 @@ ENTRY(__switch_address_space)
|
|||
* test if the cr3 is loaded with the current value to avoid unnecessary
|
||||
* TLB flushes
|
||||
*/
|
||||
#ifndef CONFIG_SMP
|
||||
mov %cr3, %ecx
|
||||
cmp %ecx, %eax
|
||||
je 0f
|
||||
#endif
|
||||
mov %eax, %cr3
|
||||
/* get ptproc */
|
||||
mov 8(%esp), %eax
|
||||
|
|
|
@ -242,6 +242,9 @@ PUBLIC void switch_to_user(void)
|
|||
* to be scheduled again.
|
||||
*/
|
||||
struct proc * p;
|
||||
#ifdef CONFIG_SMP
|
||||
int tlb_must_refresh = 0;
|
||||
#endif
|
||||
|
||||
p = get_cpulocal_var(proc_ptr);
|
||||
/*
|
||||
|
@ -279,6 +282,10 @@ not_runnable_pick_new:
|
|||
/* update the global variable */
|
||||
get_cpulocal_var(proc_ptr) = p;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (p->p_misc_flags & MF_FLUSH_TLB && get_cpulocal_var(ptproc) == p)
|
||||
tlb_must_refresh = 1;
|
||||
#endif
|
||||
switch_address_space(p);
|
||||
|
||||
check_misc_flags:
|
||||
|
@ -385,7 +392,11 @@ check_misc_flags:
|
|||
|
||||
assert(!(p->p_misc_flags & MF_FULLVM) || p->p_seg.p_cr3 != 0);
|
||||
#ifdef CONFIG_SMP
|
||||
refresh_tlb();
|
||||
if (p->p_misc_flags & MF_FLUSH_TLB) {
|
||||
if (tlb_must_refresh)
|
||||
refresh_tlb();
|
||||
p->p_misc_flags &= ~MF_FLUSH_TLB;
|
||||
}
|
||||
#endif
|
||||
|
||||
restart_local_timer();
|
||||
|
|
|
@ -242,6 +242,9 @@ struct proc {
|
|||
#define MF_SENDING_FROM_KERNEL 0x2000 /* message of this process is from kernel */
|
||||
#define MF_CONTEXT_SET 0x4000 /* don't touch context */
|
||||
#define MF_SPROF_SEEN 0x8000 /* profiling has seen this process */
|
||||
#define MF_FLUSH_TLB 0x10000 /* if set, TLB must be flushed before letting
|
||||
this process run again. Currently it only
|
||||
applies to SMP */
|
||||
|
||||
/* Magic process table addresses. */
|
||||
#define BEG_PROC_ADDR (&proc[0])
|
||||
|
|
|
@ -148,6 +148,9 @@ PUBLIC int do_vmctl(struct proc * caller, message * m_ptr)
|
|||
} else
|
||||
#endif
|
||||
RTS_SET(p, RTS_VMINHIBIT);
|
||||
#if CONFIG_SMP
|
||||
p->p_misc_flags |= MF_FLUSH_TLB;
|
||||
#endif
|
||||
return OK;
|
||||
case VMCTL_VMINHIBIT_CLEAR:
|
||||
assert(RTS_ISSET(p, RTS_VMINHIBIT));
|
||||
|
|
Loading…
Reference in a new issue