6925762 zios blocked on mutex, holder blocked on read
authorGeorge Wilson <George.Wilson@Sun.COM>
Tue, 16 Mar 2010 00:09:25 -0700
changeset 11932 197b866a8e44
parent 11931 9e8f8685d975
child 11933 76670fc4178f
6925762 zios blocked on mutex, holder blocked on read
usr/src/uts/common/fs/zfs/bplist.c
usr/src/uts/common/fs/zfs/spa.c
usr/src/uts/common/fs/zfs/sys/bplist.h
--- a/usr/src/uts/common/fs/zfs/bplist.c	Mon Mar 15 23:01:29 2010 -0700
+++ b/usr/src/uts/common/fs/zfs/bplist.c	Tue Mar 16 00:09:25 2010 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -31,12 +31,17 @@
 {
 	bzero(bpl, sizeof (*bpl));
 	mutex_init(&bpl->bpl_lock, NULL, MUTEX_DEFAULT, NULL);
+	mutex_init(&bpl->bpl_q_lock, NULL, MUTEX_DEFAULT, NULL);
+	list_create(&bpl->bpl_queue, sizeof (bplist_q_t),
+	    offsetof(bplist_q_t, bpq_node));
 }
 
 void
 bplist_fini(bplist_t *bpl)
 {
-	ASSERT(bpl->bpl_queue == NULL);
+	ASSERT(list_is_empty(&bpl->bpl_queue));
+	list_destroy(&bpl->bpl_queue);
+	mutex_destroy(&bpl->bpl_q_lock);
 	mutex_destroy(&bpl->bpl_lock);
 }
 
@@ -87,7 +92,7 @@
 	ASSERT(bpl->bpl_dbuf == NULL);
 	ASSERT(bpl->bpl_phys == NULL);
 	ASSERT(bpl->bpl_cached_dbuf == NULL);
-	ASSERT(bpl->bpl_queue == NULL);
+	ASSERT(list_is_empty(&bpl->bpl_queue));
 	ASSERT(object != 0);
 	ASSERT3U(doi.doi_type, ==, DMU_OT_BPLIST);
 	ASSERT3U(doi.doi_bonus_type, ==, DMU_OT_BPLIST_HDR);
@@ -107,7 +112,7 @@
 {
 	mutex_enter(&bpl->bpl_lock);
 
-	ASSERT(bpl->bpl_queue == NULL);
+	ASSERT(list_is_empty(&bpl->bpl_queue));
 
 	if (bpl->bpl_cached_dbuf) {
 		dmu_buf_rele(bpl->bpl_cached_dbuf, bpl);
@@ -253,11 +258,10 @@
 	bplist_q_t *bpq = kmem_alloc(sizeof (*bpq), KM_SLEEP);
 
 	ASSERT(!BP_IS_HOLE(bp));
-	mutex_enter(&bpl->bpl_lock);
+	mutex_enter(&bpl->bpl_q_lock);
 	bpq->bpq_blk = *bp;
-	bpq->bpq_next = bpl->bpl_queue;
-	bpl->bpl_queue = bpq;
-	mutex_exit(&bpl->bpl_lock);
+	list_insert_tail(&bpl->bpl_queue, bpq);
+	mutex_exit(&bpl->bpl_q_lock);
 }
 
 void
@@ -265,22 +269,22 @@
 {
 	bplist_q_t *bpq;
 
-	mutex_enter(&bpl->bpl_lock);
-	while ((bpq = bpl->bpl_queue) != NULL) {
-		bpl->bpl_queue = bpq->bpq_next;
-		mutex_exit(&bpl->bpl_lock);
+	mutex_enter(&bpl->bpl_q_lock);
+	while (bpq = list_head(&bpl->bpl_queue)) {
+		list_remove(&bpl->bpl_queue, bpq);
+		mutex_exit(&bpl->bpl_q_lock);
 		func(arg, &bpq->bpq_blk, tx);
 		kmem_free(bpq, sizeof (*bpq));
-		mutex_enter(&bpl->bpl_lock);
+		mutex_enter(&bpl->bpl_q_lock);
 	}
-	mutex_exit(&bpl->bpl_lock);
+	mutex_exit(&bpl->bpl_q_lock);
 }
 
 void
 bplist_vacate(bplist_t *bpl, dmu_tx_t *tx)
 {
 	mutex_enter(&bpl->bpl_lock);
-	ASSERT3P(bpl->bpl_queue, ==, NULL);
+	ASSERT(list_is_empty(&bpl->bpl_queue));
 	VERIFY(0 == bplist_hold(bpl));
 	dmu_buf_will_dirty(bpl->bpl_dbuf, tx);
 	VERIFY(0 == dmu_free_range(bpl->bpl_mos,
--- a/usr/src/uts/common/fs/zfs/spa.c	Mon Mar 15 23:01:29 2010 -0700
+++ b/usr/src/uts/common/fs/zfs/spa.c	Tue Mar 16 00:09:25 2010 -0700
@@ -5315,7 +5315,7 @@
 
 	} while (dmu_objset_is_dirty(mos, txg));
 
-	ASSERT(free_bpl->bpl_queue == NULL);
+	ASSERT(list_is_empty(&free_bpl->bpl_queue));
 
 	bplist_close(defer_bpl);
 
@@ -5405,8 +5405,8 @@
 	ASSERT(txg_list_empty(&dp->dp_dirty_datasets, txg));
 	ASSERT(txg_list_empty(&dp->dp_dirty_dirs, txg));
 	ASSERT(txg_list_empty(&spa->spa_vdev_txg_list, txg));
-	ASSERT(defer_bpl->bpl_queue == NULL);
-	ASSERT(free_bpl->bpl_queue == NULL);
+	ASSERT(list_is_empty(&defer_bpl->bpl_queue));
+	ASSERT(list_is_empty(&free_bpl->bpl_queue));
 
 	spa->spa_sync_pass = 0;
 
--- a/usr/src/uts/common/fs/zfs/sys/bplist.h	Mon Mar 15 23:01:29 2010 -0700
+++ b/usr/src/uts/common/fs/zfs/sys/bplist.h	Tue Mar 16 00:09:25 2010 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -52,7 +52,7 @@
 
 typedef struct bplist_q {
 	blkptr_t	bpq_blk;
-	void		*bpq_next;
+	list_node_t	bpq_node;
 } bplist_q_t;
 
 typedef struct bplist {
@@ -62,7 +62,8 @@
 	uint8_t		bpl_blockshift;
 	uint8_t		bpl_bpshift;
 	uint8_t		bpl_havecomp;
-	bplist_q_t	*bpl_queue;
+	kmutex_t	bpl_q_lock;
+	list_t		bpl_queue;
 	bplist_phys_t	*bpl_phys;
 	dmu_buf_t	*bpl_dbuf;
 	dmu_buf_t	*bpl_cached_dbuf;