summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortrevtom <none@none>2006-11-10 04:08:54 -0800
committertrevtom <none@none>2006-11-10 04:08:54 -0800
commita359d6b10060521dfb798db6da99bff792cb55cb (patch)
tree8abd561d7bb1d5f94c8f60b1d6ee0fe6a436038e
parent6a7a4430ffcf3f13f9241382d0772b35a60b5802 (diff)
downloadillumos-joyent-a359d6b10060521dfb798db6da99bff792cb55cb.tar.gz
6358047 sfmmu_mlist_enter() and hrm_init() deadlock
-rw-r--r--usr/src/uts/common/vm/hat_refmod.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/usr/src/uts/common/vm/hat_refmod.c b/usr/src/uts/common/vm/hat_refmod.c
index 4ef63538b0..1f2fe5d059 100644
--- a/usr/src/uts/common/vm/hat_refmod.c
+++ b/usr/src/uts/common/vm/hat_refmod.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -238,6 +237,7 @@ void
hat_freestat(struct as *as, int id)
{
struct hrmstat *hrm, *prev_ahrm;
+ struct hrmstat **hashtab;
hat_stats_disable(as->a_hat); /* tell the hat layer to stop */
hat_enter(as->a_hat);
@@ -284,16 +284,26 @@ hat_freestat(struct as *as, int id)
hrm_blist = NULL;
hrm_blist_num = 0;
hrm_blist_total = 0;
- while (hrm_memlist) {
- hrm = hrm_memlist;
- hrm_memlist = hrm->hrm_hnext;
- kmem_free(hrm, hrm->hrm_base);
- }
- ASSERT(hrm_memlist == NULL);
- kmem_free(hrm_hashtab, HRM_HASHSIZE * sizeof (char *));
+ hrm = hrm_memlist;
+ hrm_memlist = NULL;
+ hashtab = hrm_hashtab;
hrm_hashtab = NULL;
+ } else {
+ hashtab = NULL;
}
+
mutex_exit(&hat_statlock);
+
+ if (hashtab != NULL) {
+ struct hrmstat *next;
+
+ kmem_free(hashtab, HRM_HASHSIZE * sizeof (char *));
+ while (hrm != NULL) {
+ next = hrm->hrm_hnext;
+ kmem_free(hrm, hrm->hrm_base);
+ hrm = next;
+ }
+ }
}
/*