As per the IA32 specification we can save TLB invalidations in at least two
situations: * When mapping the page the page table entry should not have been marked "present" before, i.e. it would not have been cached anyway. * When the page table entry's accessed flag wasn't set, the entry hadn't been cached either. Speeds up the -j8 Haiku image build only minimally, but the total kernel time drops about 9%. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35062 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
58f1b1311f
commit
30f423606d
@ -165,7 +165,7 @@ put_page_table_entry_in_pgtable(page_table_entry* entry,
|
||||
page |= X86_PTE_WRITABLE;
|
||||
|
||||
// put it in the page table
|
||||
*entry = page;
|
||||
*(volatile page_table_entry*)entry = page;
|
||||
}
|
||||
|
||||
|
||||
@ -379,17 +379,15 @@ map_tmap(vm_translation_map *map, addr_t va, addr_t pa, uint32 attributes)
|
||||
pd[index] & X86_PDE_ADDRESS_MASK);
|
||||
index = VADDR_TO_PTENT(va);
|
||||
|
||||
ASSERT((pt[index] & X86_PTE_PRESENT) == 0);
|
||||
|
||||
put_page_table_entry_in_pgtable(&pt[index], pa, attributes,
|
||||
IS_KERNEL_MAP(map));
|
||||
|
||||
pinner.Unlock();
|
||||
|
||||
if (map->arch_data->num_invalidate_pages < PAGE_INVALIDATE_CACHE_SIZE) {
|
||||
map->arch_data->pages_to_invalidate[
|
||||
map->arch_data->num_invalidate_pages] = va;
|
||||
}
|
||||
|
||||
map->arch_data->num_invalidate_pages++;
|
||||
// Note: We don't need to invalidate the TLB for this address, as previously
|
||||
// the entry was not present and the TLB doesn't cache those entries.
|
||||
|
||||
map->map_count++;
|
||||
|
||||
@ -433,15 +431,22 @@ restart:
|
||||
|
||||
TRACE(("unmap_tmap: removing page 0x%lx\n", start));
|
||||
|
||||
clear_page_table_entry_flags(&pt[index], X86_PTE_PRESENT);
|
||||
page_table_entry oldEntry = clear_page_table_entry_flags(&pt[index],
|
||||
X86_PTE_PRESENT);
|
||||
map->map_count--;
|
||||
|
||||
if (map->arch_data->num_invalidate_pages < PAGE_INVALIDATE_CACHE_SIZE) {
|
||||
map->arch_data->pages_to_invalidate[
|
||||
map->arch_data->num_invalidate_pages] = start;
|
||||
}
|
||||
if ((oldEntry & X86_PTE_ACCESSED) != 0) {
|
||||
// Note, that we only need to invalidate the address, if the
|
||||
// accessed flags was set, since only then the entry could have been
|
||||
// in any TLB.
|
||||
if (map->arch_data->num_invalidate_pages
|
||||
< PAGE_INVALIDATE_CACHE_SIZE) {
|
||||
map->arch_data->pages_to_invalidate[
|
||||
map->arch_data->num_invalidate_pages] = start;
|
||||
}
|
||||
|
||||
map->arch_data->num_invalidate_pages++;
|
||||
map->arch_data->num_invalidate_pages++;
|
||||
}
|
||||
}
|
||||
|
||||
pinner.Unlock();
|
||||
@ -585,18 +590,21 @@ restart:
|
||||
} else if ((attributes & B_KERNEL_WRITE_AREA) != 0)
|
||||
entry |= X86_PTE_WRITABLE;
|
||||
|
||||
set_page_table_entry(&pt[index], entry);
|
||||
page_table_entry oldEntry = set_page_table_entry(&pt[index], entry);
|
||||
// TODO: We might have cleared accessed/modified flags!
|
||||
|
||||
// TODO: Optimize: If the accessed flag was clear, we don't need to
|
||||
// invalidate the TLB for that address.
|
||||
if ((oldEntry & X86_PTE_ACCESSED) != 0) {
|
||||
// Note, that we only need to invalidate the address, if the
|
||||
// accessed flags was set, since only then the entry could have been
|
||||
// in any TLB.
|
||||
if (map->arch_data->num_invalidate_pages
|
||||
< PAGE_INVALIDATE_CACHE_SIZE) {
|
||||
map->arch_data->pages_to_invalidate[
|
||||
map->arch_data->num_invalidate_pages] = start;
|
||||
}
|
||||
|
||||
if (map->arch_data->num_invalidate_pages < PAGE_INVALIDATE_CACHE_SIZE) {
|
||||
map->arch_data->pages_to_invalidate[
|
||||
map->arch_data->num_invalidate_pages] = start;
|
||||
map->arch_data->num_invalidate_pages++;
|
||||
}
|
||||
|
||||
map->arch_data->num_invalidate_pages++;
|
||||
}
|
||||
|
||||
pinner.Unlock();
|
||||
@ -929,12 +937,12 @@ arch_vm_translation_map_early_map(kernel_args *args, addr_t va, addr_t pa,
|
||||
+ (va / B_PAGE_SIZE / 1024) * B_PAGE_SIZE), 0, B_PAGE_SIZE);
|
||||
}
|
||||
|
||||
ASSERT((sPageHole[va / B_PAGE_SIZE] & X86_PTE_PRESENT) == 0);
|
||||
|
||||
// now, fill in the pentry
|
||||
put_page_table_entry_in_pgtable(sPageHole + va / B_PAGE_SIZE, pa,
|
||||
attributes, IS_KERNEL_ADDRESS(va));
|
||||
|
||||
arch_cpu_invalidate_TLB_range(va, va);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user