Print this page
OS-XXXX netstack_find_by_stackid() drops-and-reacquires

@@ -121,10 +121,11 @@
 static boolean_t netstack_apply_destroy(kmutex_t *, netstack_t *, int);
 static boolean_t wait_for_zone_creator(netstack_t *, kmutex_t *);
 static boolean_t wait_for_nms_inprogress(netstack_t *, nm_state_t *,
     kmutex_t *);
 
+static void netstack_hold_locked(netstack_t *);
 static void netstack_reap_work(netstack_t *, boolean_t);
 ksema_t netstack_reap_limiter;
 
 void
 netstack_init(void)

@@ -1035,12 +1036,12 @@
         mutex_enter(&netstack_g_lock);
         for (ns = netstack_head; ns != NULL; ns = ns->netstack_next) {
                 mutex_enter(&ns->netstack_lock);
                 if (ns->netstack_stackid == stackid &&
                     !(ns->netstack_flags & (NSF_UNINIT|NSF_CLOSING))) {
+                        netstack_hold_locked(ns);
                         mutex_exit(&ns->netstack_lock);
-                        netstack_hold(ns);
                         mutex_exit(&netstack_g_lock);
                         return (ns);
                 }
                 mutex_exit(&ns->netstack_lock);
         }

@@ -1193,18 +1194,25 @@
                         netstack_reap_work(ns, is_not_intr);
                 }
         }
 }
 
+static void
+netstack_hold_locked(netstack_t *ns)
+{
+        ASSERT(MUTEX_HELD(&ns->netstack_lock));
+        ns->netstack_refcnt++;
+        ASSERT(ns->netstack_refcnt > 0);
+        DTRACE_PROBE1(netstack__inc__ref, netstack_t *, ns);
+}
+
 void
 netstack_hold(netstack_t *ns)
 {
         mutex_enter(&ns->netstack_lock);
-        ns->netstack_refcnt++;
-        ASSERT(ns->netstack_refcnt > 0);
+        netstack_hold_locked(ns);
         mutex_exit(&ns->netstack_lock);
-        DTRACE_PROBE1(netstack__inc__ref, netstack_t *, ns);
 }
 
 /*
  * To support kstat_create_netstack() using kstat_zone_add we need
  * to track both