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:
parent
443e607adc
commit
14a38e5207
2 changed files with 19 additions and 7 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue