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,34 ****
/*
* Copyright (c) 2010, Intel Corporation.
* All rights reserved.
*/
/*
! * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014, 2015 by Delphix. All rights reserved.
*/
/*
* VM - Hardware Address Translation management for i386 and amd64
--- 24,35 ----
/*
* Copyright (c) 2010, Intel Corporation.
* 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,272 ****
--- 264,274 ----
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,409 ****
* 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)
cv_wait(&hat_list_cv, &hat_list_lock);
hat->hat_flags |= HAT_FREEING;
mutex_exit(&hat_list_lock);
}
--- 401,411 ----
* 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) || (hat->hat_unmaps > 0))
cv_wait(&hat_list_cv, &hat_list_lock);
hat->hat_flags |= HAT_FREEING;
mutex_exit(&hat_list_lock);
}
*** 2460,2495 ****
handle_ranges(hat, cb, r_cnt, r);
XPV_ALLOW_MIGRATE();
}
/*
! * Invalidate a virtual address translation on a slave CPU during
! * panic() dumps.
*/
void
! hat_flush_range(hat_t *hat, caddr_t va, size_t size)
{
- 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
*
--- 2462,2482 ----
handle_ranges(hat, cb, r_cnt, r);
XPV_ALLOW_MIGRATE();
}
/*
! * Flush the TLB for the local CPU
! * Invoked from a slave CPU during panic() dumps.
*/
void
! hat_flush(void)
{
#ifdef __xpv
xen_flush_tlb();
#else
flush_all_tlb_entries();
#endif
}
/*
* synchronize mapping with software data structures
*
*** 3319,3340 ****
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;
/*
* 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.
*/
--- 3306,3344 ----
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,3381 ****
* 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.
*/
x86_hm_exit(pp);
htable_release(ht);
return (hm);
}
extern int vpm_enable;
/*
--- 3371,3389 ----
* 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
*/
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;
/*