Print this page
5981 Deadlock in dmu_objset_find_dp

@@ -1744,11 +1744,23 @@
 dmu_objset_find_dp_cb(void *arg)
 {
         dmu_objset_find_ctx_t *dcp = arg;
         dsl_pool_t *dp = dcp->dc_dp;
 
-        dsl_pool_config_enter(dp, FTAG);
+        /*
+         * We need to get a pool_config_lock here, as there are several
+         * asssert(pool_config_held) down the stack. Getting a lock via
+         * dsl_pool_config_enter is risky, as it might be stalled by a
+         * pending writer. This would deadlock, as the write lock can
+         * only be granted when our parent thread gives up the lock.
+         * The _prio interface gives us priority over a pending writer.
+         * On the other hand, we don't risk to stall any pending writers,
+         * as the parent thread already holds a config lock. We give up
+         * our lock before the parent does, so in effect we do not prolong
+         * the waiting time for the writer.
+         */
+        dsl_pool_config_enter_prio(dp, FTAG);
 
         dmu_objset_find_dp_impl(dcp);
 
         dsl_pool_config_exit(dp, FTAG);
 }