Date: Sun, 17 Nov 2019 17:38:53 +0000 (UTC) From: Alan Cox <alc@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r354792 - head/sys/arm64/arm64 Message-ID: <201911171738.xAHHcrPN061433@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: alc Date: Sun Nov 17 17:38:53 2019 New Revision: 354792 URL: https://svnweb.freebsd.org/changeset/base/354792 Log: Achieve two goals at once: (1) Avoid an unnecessary broadcast TLB invalidation in pmap_remove_all(). (2) Prevent an "invalid ASID" assertion failure in pmap_remove_all(). The architecture definition specifies that the TLB will not cache mappings that don't have the "AF" bit set, so pmap_remove_all() needn't issue a TLB invalidation for mappings that don't have the "AF" bit set. We allocate ASIDs lazily. Specifically, we don't allocate an ASID for a pmap until we are activating it. Now, consider what happens on a fork(). Before we activate the child's pmap, we use pmap_copy() to copy mappings from the parent's pmap to the child's. These new mappings have their "AF" bits cleared. Suppose that the page daemon decides to reclaim a page that underlies one of these new mappings. Previously, the pmap_invalidate_page() performed by pmap_remove_all() on a mapping in the child's pmap would fail an assertion because that pmap hasn't yet been assigned an ASID. However, we don't need to issue a TLB invalidation for such mappings because they can't possibly be cached in the TLB. Reported by: bob prohaska <fbsd@www.zefox.net> Reviewed by: markj MFC after: 1 week X-MFC-before: r354286 Differential Revision: https://reviews.freebsd.org/D22388 Modified: head/sys/arm64/arm64/pmap.c Modified: head/sys/arm64/arm64/pmap.c ============================================================================== --- head/sys/arm64/arm64/pmap.c Sun Nov 17 14:54:43 2019 (r354791) +++ head/sys/arm64/arm64/pmap.c Sun Nov 17 17:38:53 2019 (r354792) @@ -2879,11 +2879,12 @@ retry: pte = pmap_l2_to_l3(pde, pv->pv_va); tpte = pmap_load_clear(pte); - pmap_invalidate_page(pmap, pv->pv_va); if (tpte & ATTR_SW_WIRED) pmap->pm_stats.wired_count--; - if ((tpte & ATTR_AF) != 0) + if ((tpte & ATTR_AF) != 0) { + pmap_invalidate_page(pmap, pv->pv_va); vm_page_aflag_set(m, PGA_REFERENCED); + } /* * Update the vm_page_t clean and reference bits.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201911171738.xAHHcrPN061433>