Print this page
NEX-19598 HAT panic
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-16970 assertion failed: ht->ht_valid_cnt >= 0, file: ../../i86pc/vm/htable.c, line: 1204
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-18463 Parallel dump produces corrupted dump file
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-5164 backport illumos 6514 AS_* lock macros simplification
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
6514 AS_* lock macros simplification
Reviewed by: Piotr Jasiukajtis <estibi@me.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Albert Lee <trisk@omniti.com>
Approved by: Dan McDonald <danmcd@omniti.com>
@@ -24,11 +24,12 @@
/*
* Copyright (c) 2010, Intel Corporation.
* All rights reserved.
*/
/*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2019 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Joyent, Inc. All rights reserved.
* Copyright (c) 2014, 2015 by Delphix. All rights reserved.
*/
/*
* VM - Hardware Address Translation management for i386 and amd64
@@ -263,10 +264,11 @@
ASSERT(AS_WRITE_HELD(as));
hat = kmem_cache_alloc(hat_cache, KM_SLEEP);
hat->hat_as = as;
mutex_init(&hat->hat_mutex, NULL, MUTEX_DEFAULT, NULL);
ASSERT(hat->hat_flags == 0);
+ hat->hat_unmaps = 0;
#if defined(__xpv)
/*
* No VLP stuff on the hypervisor due to the 64-bit split top level
* page tables. On 32-bit it's not needed as the hypervisor takes
@@ -399,11 +401,11 @@
* If the hat is currently a stealing victim, wait for the stealing
* to finish. Once we mark it as HAT_FREEING, htable_steal()
* won't look at its pagetables anymore.
*/
mutex_enter(&hat_list_lock);
- while (hat->hat_flags & HAT_VICTIM)
+ while ((hat->hat_flags & HAT_VICTIM) || (hat->hat_unmaps > 0))
cv_wait(&hat_list_cv, &hat_list_lock);
hat->hat_flags |= HAT_FREEING;
mutex_exit(&hat_list_lock);
}
@@ -2460,36 +2462,21 @@
handle_ranges(hat, cb, r_cnt, r);
XPV_ALLOW_MIGRATE();
}
/*
- * Invalidate a virtual address translation on a slave CPU during
- * panic() dumps.
+ * Flush the TLB for the local CPU
+ * Invoked from a slave CPU during panic() dumps.
*/
void
-hat_flush_range(hat_t *hat, caddr_t va, size_t size)
+hat_flush(void)
{
- ssize_t sz;
- caddr_t endva = va + size;
-
- while (va < endva) {
- sz = hat_getpagesize(hat, va);
- if (sz < 0) {
#ifdef __xpv
xen_flush_tlb();
#else
flush_all_tlb_entries();
#endif
- break;
- }
-#ifdef __xpv
- xen_flush_va(va);
-#else
- mmu_tlbflush_entry(va);
-#endif
- va += sz;
- }
}
/*
* synchronize mapping with software data structures
*
@@ -3319,22 +3306,39 @@
hat_page_getattr(struct page *pp, uint_t flag)
{
return (PP_GETRM(pp, flag));
}
-
/*
* common code used by hat_pageunload() and hment_steal()
*/
hment_t *
hati_page_unmap(page_t *pp, htable_t *ht, uint_t entry)
{
x86pte_t old_pte;
pfn_t pfn = pp->p_pagenum;
hment_t *hm;
+ hat_t *hat = ht->ht_hat;
/*
+ * There is a race between this function and the freeing of a HAT
+ * whose owning process is exiting; process exit code ignores htable
+ * reference counts.
+ * If the HAT is already freeing (HAT_FREEING) no-op this function.
+ * Otherwise increment hat_unmaps to block the hat from being free'd
+ * until this function completes.
+ */
+ mutex_enter(&hat_list_lock);
+ if (hat->hat_flags & HAT_FREEING) {
+ mutex_exit(&hat_list_lock);
+ x86_hm_exit(pp);
+ return (NULL);
+ }
+ ++(hat->hat_unmaps);
+ mutex_exit(&hat_list_lock);
+
+ /*
* We need to acquire a hold on the htable in order to
* do the invalidate. We know the htable must exist, since
* unmap's don't release the htable until after removing any
* hment. Having x86_hm_enter() keeps that from proceeding.
*/
@@ -3367,15 +3371,19 @@
* Remove the mapping list entry for this page.
*/
hm = hment_remove(pp, ht, entry);
/*
- * drop the mapping list lock so that we might free the
- * hment and htable.
+ * drop the mapping list lock so that we might free the hment and htable
*/
x86_hm_exit(pp);
htable_release(ht);
+
+ mutex_enter(&hat_list_lock);
+ --(hat->hat_unmaps);
+ cv_broadcast(&hat_list_cv);
+ mutex_exit(&hat_list_lock);
return (hm);
}
extern int vpm_enable;
/*