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;