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

*** 121,130 **** --- 121,131 ---- 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,1046 **** 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))) { mutex_exit(&ns->netstack_lock); - netstack_hold(ns); mutex_exit(&netstack_g_lock); return (ns); } mutex_exit(&ns->netstack_lock); } --- 1036,1047 ---- 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); mutex_exit(&netstack_g_lock); return (ns); } mutex_exit(&ns->netstack_lock); }
*** 1193,1210 **** netstack_reap_work(ns, is_not_intr); } } } void netstack_hold(netstack_t *ns) { mutex_enter(&ns->netstack_lock); ! ns->netstack_refcnt++; ! ASSERT(ns->netstack_refcnt > 0); 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 --- 1194,1218 ---- 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); ! netstack_hold_locked(ns); mutex_exit(&ns->netstack_lock); } /* * To support kstat_create_netstack() using kstat_zone_add we need * to track both