Print this page
Fix NFS design problems re. multiple zone keys
Make NFS server zone-specific data all have the same lifetime
Fix rfs4_clean_state_exi
Fix exi_cache_reclaim
Fix mistakes in zone keys work
More fixes re. exi_zoneid and exi_tree
(danmcd -> Keep some ASSERT()s around for readability.)

*** 50,63 **** #include <nfs/nfs_clnt.h> #include <nfs/auth.h> static struct kmem_cache *exi_cache_handle; static void exi_cache_reclaim(void *); static void exi_cache_trim(struct exportinfo *exi); - static void *nfsauth_zone_init(zoneid_t); - static void nfsauth_zone_shutdown(zoneid_t zoneid, void *data); - static void nfsauth_zone_fini(zoneid_t, void *); extern pri_t minclsyspri; /* NFS auth cache statistics */ volatile uint_t nfsauth_cache_hit; --- 50,61 ---- #include <nfs/nfs_clnt.h> #include <nfs/auth.h> static struct kmem_cache *exi_cache_handle; static void exi_cache_reclaim(void *); + static void exi_cache_reclaim_zone(nfs_globals_t *); static void exi_cache_trim(struct exportinfo *exi); extern pri_t minclsyspri; /* NFS auth cache statistics */ volatile uint_t nfsauth_cache_hit;
*** 174,191 **** static void nfsauth_free_node(struct auth_cache *); static void nfsauth_refresh_thread(nfsauth_globals_t *); static int nfsauth_cache_compar(const void *, const void *); ! static zone_key_t nfsauth_zone_key; void mountd_args(uint_t did) { nfsauth_globals_t *nag; ! nag = zone_getspecific(nfsauth_zone_key, curzone); mutex_enter(&nag->mountd_lock); if (nag->mountd_dh != NULL) door_ki_rele(nag->mountd_dh); nag->mountd_dh = door_ki_lookup(did); mutex_exit(&nag->mountd_lock); --- 172,196 ---- static void nfsauth_free_node(struct auth_cache *); static void nfsauth_refresh_thread(nfsauth_globals_t *); static int nfsauth_cache_compar(const void *, const void *); ! static nfsauth_globals_t * ! nfsauth_get_zg(void) ! { ! nfs_globals_t *ng = zone_getspecific(nfssrv_zone_key, curzone); ! nfsauth_globals_t *nag = ng->nfs_auth; ! ASSERT(nag != NULL); ! return (nag); ! } void mountd_args(uint_t did) { nfsauth_globals_t *nag; ! nag = nfsauth_get_zg(); mutex_enter(&nag->mountd_lock); if (nag->mountd_dh != NULL) door_ki_rele(nag->mountd_dh); nag->mountd_dh = door_ki_lookup(did); mutex_exit(&nag->mountd_lock);
*** 192,204 **** } void nfsauth_init(void) { - zone_key_create(&nfsauth_zone_key, nfsauth_zone_init, - nfsauth_zone_shutdown, nfsauth_zone_fini); - exi_cache_handle = kmem_cache_create("exi_cache_handle", sizeof (struct auth_cache), 0, NULL, NULL, exi_cache_reclaim, NULL, NULL, 0); } --- 197,206 ----
*** 206,218 **** nfsauth_fini(void) { kmem_cache_destroy(exi_cache_handle); } ! /*ARGSUSED*/ ! static void * ! nfsauth_zone_init(zoneid_t zoneid) { nfsauth_globals_t *nag; nag = kmem_zalloc(sizeof (*nag), KM_SLEEP); --- 208,219 ---- nfsauth_fini(void) { kmem_cache_destroy(exi_cache_handle); } ! void ! nfsauth_zone_init(nfs_globals_t *ng) { nfsauth_globals_t *nag; nag = kmem_zalloc(sizeof (*nag), KM_SLEEP);
*** 225,243 **** list_create(&nag->refreshq_queue, sizeof (refreshq_exi_node_t), offsetof(refreshq_exi_node_t, ren_node)); cv_init(&nag->refreshq_cv, NULL, CV_DEFAULT, NULL); nag->refreshq_thread_state = REFRESHQ_THREAD_NEED_CREATE; ! return (nag); } ! /*ARGSUSED*/ ! static void ! nfsauth_zone_shutdown(zoneid_t zoneid, void *data) { refreshq_exi_node_t *ren; ! nfsauth_globals_t *nag = data; /* Prevent the nfsauth_refresh_thread from getting new work */ mutex_enter(&nag->refreshq_lock); if (nag->refreshq_thread_state == REFRESHQ_THREAD_RUNNING) { nag->refreshq_thread_state = REFRESHQ_THREAD_FINI_REQ; --- 226,243 ---- list_create(&nag->refreshq_queue, sizeof (refreshq_exi_node_t), offsetof(refreshq_exi_node_t, ren_node)); cv_init(&nag->refreshq_cv, NULL, CV_DEFAULT, NULL); nag->refreshq_thread_state = REFRESHQ_THREAD_NEED_CREATE; ! ng->nfs_auth = nag; } ! void ! nfsauth_zone_shutdown(nfs_globals_t *ng) { refreshq_exi_node_t *ren; ! nfsauth_globals_t *nag = ng->nfs_auth; /* Prevent the nfsauth_refresh_thread from getting new work */ mutex_enter(&nag->refreshq_lock); if (nag->refreshq_thread_state == REFRESHQ_THREAD_RUNNING) { nag->refreshq_thread_state = REFRESHQ_THREAD_FINI_REQ;
*** 268,283 **** exi_rele(ren->ren_exi); kmem_free(ren, sizeof (*ren)); } } ! /*ARGSUSED*/ ! static void ! nfsauth_zone_fini(zoneid_t zoneid, void *data) { ! nfsauth_globals_t *nag = data; list_destroy(&nag->refreshq_queue); cv_destroy(&nag->refreshq_cv); mutex_destroy(&nag->refreshq_lock); mutex_destroy(&nag->mountd_lock); /* Extra cleanup. */ --- 268,284 ---- exi_rele(ren->ren_exi); kmem_free(ren, sizeof (*ren)); } } ! void ! nfsauth_zone_fini(nfs_globals_t *ng) { ! nfsauth_globals_t *nag = ng->nfs_auth; + ng->nfs_auth = NULL; + list_destroy(&nag->refreshq_queue); cv_destroy(&nag->refreshq_cv); mutex_destroy(&nag->refreshq_lock); mutex_destroy(&nag->mountd_lock); /* Extra cleanup. */
*** 876,886 **** avl_index_t where; /* used for avl_find()/avl_insert() */ ASSERT(cr != NULL); ASSERT3P(curzone, ==, exi->exi_zone); ! nag = zone_getspecific(nfsauth_zone_key, curzone); /* * Now check whether this client already * has an entry for this flavor in the cache * for this export. --- 877,887 ---- avl_index_t where; /* used for avl_find()/avl_insert() */ ASSERT(cr != NULL); ASSERT3P(curzone, ==, exi->exi_zone); ! nag = nfsauth_get_zg(); /* * Now check whether this client already * has an entry for this flavor in the cache * for this export.
*** 1453,1474 **** nfsauth_free_clnt_node(node); } } /* ! * Called by the kernel memory allocator when ! * memory is low. Free unused cache entries. ! * If that's not enough, the VM system will ! * call again for some more. */ /*ARGSUSED*/ void exi_cache_reclaim(void *cdrarg) { int i; struct exportinfo *exi; ! nfs_export_t *ne = nfs_get_export(); rw_enter(&ne->exported_lock, RW_READER); for (i = 0; i < EXPTABLESIZE; i++) { for (exi = ne->exptable[i]; exi; exi = exi->fid_hash.next) --- 1454,1498 ---- nfsauth_free_clnt_node(node); } } /* ! * Called by the kernel memory allocator when memory is low. ! * Free unused cache entries. If that's not enough, the VM system ! * will call again for some more. ! * ! * This needs to operate on all zones, so we take a reader lock ! * on the list of zones and walk the list. This is OK here ! * becuase exi_cache_trim doesn't block or cause new objects ! * to be allocated (basically just frees lots of stuff). ! * Use care if nfssrv_globals_rwl is taken as reader in any ! * other cases because it will block nfs_server_zone_init ! * and nfs_server_zone_fini, which enter as writer. */ /*ARGSUSED*/ void exi_cache_reclaim(void *cdrarg) { + nfs_globals_t *ng; + + rw_enter(&nfssrv_globals_rwl, RW_READER); + + ng = list_head(&nfssrv_globals_list); + while (ng != NULL) { + exi_cache_reclaim_zone(ng); + ng = list_next(&nfssrv_globals_list, ng); + } + + rw_exit(&nfssrv_globals_rwl); + } + + static void + exi_cache_reclaim_zone(nfs_globals_t *ng) + { int i; struct exportinfo *exi; ! nfs_export_t *ne = ng->nfs_export; rw_enter(&ne->exported_lock, RW_READER); for (i = 0; i < EXPTABLESIZE; i++) { for (exi = ne->exptable[i]; exi; exi = exi->fid_hash.next)
*** 1478,1488 **** rw_exit(&ne->exported_lock); atomic_inc_uint(&nfsauth_cache_reclaim); } ! void exi_cache_trim(struct exportinfo *exi) { struct auth_cache_clnt *c; struct auth_cache_clnt *nextc; struct auth_cache *p; --- 1502,1512 ---- rw_exit(&ne->exported_lock); atomic_inc_uint(&nfsauth_cache_reclaim); } ! static void exi_cache_trim(struct exportinfo *exi) { struct auth_cache_clnt *c; struct auth_cache_clnt *nextc; struct auth_cache *p;