Print this page
6470 mac_unregister() needs to mod_hash_remove() BEFORE holding the perimeter.
Reviewed by: Ryan Zezeski <ryan@zinascii.com>

*** 19,28 **** --- 19,29 ---- * CDDL HEADER END */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved. */ #include <sys/types.h> #include <sys/conf.h> #include <sys/id_space.h>
*** 512,521 **** --- 513,534 ---- /* * Clean up notification thread and wait for it to exit. */ i_mac_notify_exit(mip); + /* + * Prior to acquiring the MAC perimeter, remove the MAC instance from + * the internal hash table. Such removal means table-walkers that + * acquire the perimeter will not do so on behalf of what we are + * unregistering, which prevents a deadlock. + */ + rw_enter(&i_mac_impl_lock, RW_WRITER); + (void) mod_hash_remove(i_mac_impl_hash, + (mod_hash_key_t)mip->mi_name, &val); + rw_exit(&i_mac_impl_lock); + ASSERT(mip == (mac_impl_t *)val); + i_mac_perim_enter(mip); /* * There is still resource properties configured over this mac. */
*** 531,544 **** ASSERT(mip->mi_nactiveclients == 0 && !(mip->mi_state_flags & MIS_EXCLUSIVE)); mac_driver_stat_delete(mip); - (void) mod_hash_remove(i_mac_impl_hash, - (mod_hash_key_t)mip->mi_name, &val); - ASSERT(mip == (mac_impl_t *)val); - ASSERT(i_mac_impl_count > 0); atomic_dec_32(&i_mac_impl_count); if (mip->mi_pdata != NULL) kmem_free(mip->mi_pdata, mip->mi_pdata_size); --- 544,553 ----