1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

reduce the number of IPIs

This commit is contained in:
Stefan Lankes 2016-08-21 19:45:25 +02:00
parent 443e607adc
commit 14a38e5207
2 changed files with 19 additions and 7 deletions

View file

@ -584,7 +584,7 @@ int ipi_tlb_flush(void);
*
* Just reads cr3 and writes the same value back into it.
*/
static inline void tlb_flush(void)
static inline void tlb_flush(uint8_t with_ipi)
{
size_t val = read_cr3();
@ -592,19 +592,21 @@ static inline void tlb_flush(void)
write_cr3(val);
#if MAX_CORES > 1
ipi_tlb_flush();
if (with_ipi)
ipi_tlb_flush();
#endif
}
/** @brief Flush a specific page entry in TLB
* @param addr The (virtual) address of the page to flush
*/
static inline void tlb_flush_one_page(size_t addr)
static inline void tlb_flush_one_page(size_t addr, uint8_t with_ipi)
{
asm volatile("invlpg (%0)" : : "r"(addr) : "memory");
#if MAX_CORES > 1
ipi_tlb_flush();
if (with_ipi)
ipi_tlb_flush();
#endif
}

View file

@ -109,6 +109,7 @@ int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
int lvl, ret = -ENOMEM;
long vpn = viraddr >> PAGE_BITS;
long first[PAGE_LEVELS], last[PAGE_LEVELS];
int8_t send_ipi = 0;
/* Calculate index boundaries for page map traversal */
for (lvl=0; lvl<PAGE_LEVELS; lvl++) {
@ -146,20 +147,23 @@ int page_map(size_t viraddr, size_t phyaddr, size_t npages, size_t bits)
/* do we have to flush the TLB? */
if (self[lvl][vpn] & PG_PRESENT)
flush = 1;
send_ipi = flush = 1;
self[lvl][vpn] = phyaddr | bits | PG_PRESENT | PG_ACCESSED;
if (flush)
/* There's already a page mapped at this address.
* We have to flush a single TLB entry. */
tlb_flush_one_page(vpn << PAGE_BITS);
tlb_flush_one_page(vpn << PAGE_BITS, 0);
phyaddr += PAGE_SIZE;
}
}
}
if (send_ipi)
ipi_tlb_flush();
ret = 0;
out:
spinlock_irqsave_unlock(&page_lock);
@ -169,6 +173,8 @@ out:
int page_unmap(size_t viraddr, size_t npages)
{
uint8_t ipi = 0;
spinlock_irqsave_lock(&page_lock);
/* Start iterating through the entries.
@ -176,9 +182,13 @@ int page_unmap(size_t viraddr, size_t npages)
size_t vpn, start = viraddr>>PAGE_BITS;
for (vpn=start; vpn<start+npages; vpn++) {
self[0][vpn] = 0;
tlb_flush_one_page(vpn << PAGE_BITS);
tlb_flush_one_page(vpn << PAGE_BITS, 0);
ipi = 1;
}
if (ipi)
ipi_tlb_flush();
spinlock_irqsave_unlock(&page_lock);
/* This can't fail because we don't make checks here */