kernel/x86: Avoid unnecessary TLB invalidations.
If a context switch happened between the messsage being sent and received, we don't need to invalidate. Brief testing on a 4-core VM shows this happens relatively rarely during compile jobs (expected, most processes are single-threaded), but very often while running multiprocess web browsers. Some INVALIDATE_PAGES are skipped, but mostly INVALIDATE_PAGE_LIST is (by the thousands.) Change-Id: If32ed95139e0db3770054f6ef3f72c9aecb9394d Reviewed-on: https://review.haiku-os.org/c/haiku/+/10350 Reviewed-by: waddlesplash <[email protected]> Tested-by: Commit checker robot <[email protected]> Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
3e1ccaf329
commit
3214eedc80
@@ -1981,8 +1981,11 @@ arch_cpu_init_post_modules(kernel_args* args)
|
||||
|
||||
|
||||
void
|
||||
arch_cpu_user_tlb_invalidate(intptr_t)
|
||||
arch_cpu_user_tlb_invalidate(intptr_t context)
|
||||
{
|
||||
if (context != 0 && (intptr_t)x86_read_cr3() != context)
|
||||
return;
|
||||
|
||||
x86_write_cr3(x86_read_cr3());
|
||||
}
|
||||
|
||||
@@ -2006,10 +2009,12 @@ arch_cpu_global_tlb_invalidate()
|
||||
|
||||
|
||||
void
|
||||
arch_cpu_invalidate_tlb_range(intptr_t, addr_t start, addr_t end)
|
||||
arch_cpu_invalidate_tlb_range(intptr_t context, addr_t start, addr_t end)
|
||||
{
|
||||
int32 num_pages = end / B_PAGE_SIZE - start / B_PAGE_SIZE;
|
||||
while (num_pages-- >= 0) {
|
||||
if (context != 0 && (intptr_t)x86_read_cr3() != context)
|
||||
return;
|
||||
|
||||
while (start <= end) {
|
||||
invalidate_TLB(start);
|
||||
start += B_PAGE_SIZE;
|
||||
}
|
||||
@@ -2017,12 +2022,13 @@ arch_cpu_invalidate_tlb_range(intptr_t, addr_t start, addr_t end)
|
||||
|
||||
|
||||
void
|
||||
arch_cpu_invalidate_tlb_list(intptr_t, addr_t pages[], int num_pages)
|
||||
arch_cpu_invalidate_tlb_list(intptr_t context, addr_t pages[], int num_pages)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < num_pages; i++) {
|
||||
if (context != 0 && (intptr_t)x86_read_cr3() != context)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < num_pages; i++)
|
||||
invalidate_TLB(pages[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ X86VMTranslationMap::Flush()
|
||||
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
smp_send_multicast_ici(cpuMask, SMP_MSG_USER_INVALIDATE_PAGES,
|
||||
0, 0, 0, NULL, SMP_MSG_FLAG_SYNC);
|
||||
x86_read_cr3(), 0, 0, NULL, SMP_MSG_FLAG_SYNC);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -138,7 +138,7 @@ X86VMTranslationMap::Flush()
|
||||
|
||||
if (!cpuMask.IsEmpty()) {
|
||||
smp_send_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST,
|
||||
0, (addr_t)fInvalidPages, fInvalidPagesCount,
|
||||
x86_read_cr3(), (addr_t)fInvalidPages, fInvalidPagesCount,
|
||||
NULL, SMP_MSG_FLAG_SYNC);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user