Skip to content

Commit

Permalink
amd64: use INVLPGB for kernel pmap invalidations
Browse files Browse the repository at this point in the history
avoiding broadcast IPIs.

Reviewed by:	alc, markj
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D45191
  • Loading branch information
kostikbel committed Aug 21, 2024
1 parent bc4ffca commit 47656cc
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions sys/amd64/amd64/mp_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,6 +679,20 @@ smp_targeted_tlb_shootdown_native(pmap_t pmap, vm_offset_t addr1, vm_offset_t ad
void
smp_masked_invltlb(pmap_t pmap, smp_invl_cb_t curcpu_cb)
{
if (invlpgb_works && pmap == kernel_pmap) {
invlpgb(INVLPGB_GLOB, 0, 0);

/*
* TLBSYNC syncs only against INVLPGB executed on the
* same CPU. Since current thread is pinned by
* caller, we do not need to enter critical section to
* prevent migration.
*/
tlbsync();
sched_unpin();
return;
}

smp_targeted_tlb_shootdown(pmap, 0, 0, curcpu_cb, invl_op_tlb);
#ifdef COUNT_XINVLTLB_HITS
ipi_global++;
Expand All @@ -688,6 +702,13 @@ smp_masked_invltlb(pmap_t pmap, smp_invl_cb_t curcpu_cb)
void
smp_masked_invlpg(vm_offset_t addr, pmap_t pmap, smp_invl_cb_t curcpu_cb)
{
if (invlpgb_works && pmap == kernel_pmap) {
invlpgb(INVLPGB_GLOB | INVLPGB_VA | trunc_page(addr), 0, 0);
tlbsync();
sched_unpin();
return;
}

smp_targeted_tlb_shootdown(pmap, addr, 0, curcpu_cb, invl_op_pg);
#ifdef COUNT_XINVLTLB_HITS
ipi_page++;
Expand All @@ -698,6 +719,39 @@ void
smp_masked_invlpg_range(vm_offset_t addr1, vm_offset_t addr2, pmap_t pmap,
smp_invl_cb_t curcpu_cb)
{
if (invlpgb_works && pmap == kernel_pmap) {
vm_offset_t va;
uint64_t cnt, total;

addr1 = trunc_page(addr1);
addr2 = round_page(addr2);
total = atop(addr2 - addr1);
for (va = addr1; total > 0;) {
if ((va & PDRMASK) != 0 || total < NPDEPG) {
cnt = atop(NBPDR - (va & PDRMASK));
if (cnt > total)
cnt = total;
if (cnt > invlpgb_maxcnt + 1)
cnt = invlpgb_maxcnt + 1;
invlpgb(INVLPGB_GLOB | INVLPGB_VA | va, 0,
cnt - 1);
va += ptoa(cnt);
total -= cnt;
} else {
cnt = total / NPTEPG;
if (cnt > invlpgb_maxcnt + 1)
cnt = invlpgb_maxcnt + 1;
invlpgb(INVLPGB_GLOB | INVLPGB_VA | va, 0,
INVLPGB_2M_CNT | (cnt - 1));
va += cnt << PDRSHIFT;
total -= cnt * NPTEPG;
}
}
tlbsync();
sched_unpin();
return;
}

smp_targeted_tlb_shootdown(pmap, addr1, addr2, curcpu_cb,
invl_op_pgrng);
#ifdef COUNT_XINVLTLB_HITS
Expand Down

0 comments on commit 47656cc

Please sign in to comment.