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
|
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());
|
x86_write_cr3(x86_read_cr3());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2006,10 +2009,12 @@ arch_cpu_global_tlb_invalidate()
|
|||||||
|
|
||||||
|
|
||||||
void
|
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;
|
if (context != 0 && (intptr_t)x86_read_cr3() != context)
|
||||||
while (num_pages-- >= 0) {
|
return;
|
||||||
|
|
||||||
|
while (start <= end) {
|
||||||
invalidate_TLB(start);
|
invalidate_TLB(start);
|
||||||
start += B_PAGE_SIZE;
|
start += B_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
@@ -2017,12 +2022,13 @@ arch_cpu_invalidate_tlb_range(intptr_t, addr_t start, addr_t end)
|
|||||||
|
|
||||||
|
|
||||||
void
|
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;
|
if (context != 0 && (intptr_t)x86_read_cr3() != context)
|
||||||
for (i = 0; i < num_pages; i++) {
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; i < num_pages; i++)
|
||||||
invalidate_TLB(pages[i]);
|
invalidate_TLB(pages[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ X86VMTranslationMap::Flush()
|
|||||||
|
|
||||||
if (!cpuMask.IsEmpty()) {
|
if (!cpuMask.IsEmpty()) {
|
||||||
smp_send_multicast_ici(cpuMask, SMP_MSG_USER_INVALIDATE_PAGES,
|
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 {
|
} else {
|
||||||
@@ -138,7 +138,7 @@ X86VMTranslationMap::Flush()
|
|||||||
|
|
||||||
if (!cpuMask.IsEmpty()) {
|
if (!cpuMask.IsEmpty()) {
|
||||||
smp_send_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST,
|
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);
|
NULL, SMP_MSG_FLAG_SYNC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user