diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/fs/sockfs/sockcommon.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/sockfs/sockcommon_subr.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/sockfs/sockparams.c | 94 | ||||
-rw-r--r-- | usr/src/uts/common/sys/socketvar.h | 9 |
4 files changed, 106 insertions, 1 deletions
diff --git a/usr/src/uts/common/fs/sockfs/sockcommon.c b/usr/src/uts/common/fs/sockfs/sockcommon.c index 807ccf3021..6aaae3a006 100644 --- a/usr/src/uts/common/fs/sockfs/sockcommon.c +++ b/usr/src/uts/common/fs/sockfs/sockcommon.c @@ -107,6 +107,7 @@ socket_create(int family, int type, int protocol, char *devpath, char *mod, ASSERT(sp->sp_smod_info != NULL); ASSERT(flags == SOCKET_SLEEP || flags == SOCKET_NOSLEEP); + sp->sp_stats.sps_ncreate.value.ui64++; so = sp->sp_smod_info->smod_sock_create_func(sp, family, type, protocol, version, flags, errorp, cr); if (so == NULL) { @@ -140,6 +141,7 @@ socket_newconn(struct sonode *parent, sock_lower_handle_t lh, sp = parent->so_sockparams; ASSERT(sp != NULL); + sp->sp_stats.sps_ncreate.value.ui64++; so = sp->sp_smod_info->smod_sock_create_func(sp, parent->so_family, parent->so_type, parent->so_protocol, parent->so_version, flags, errorp, cr); diff --git a/usr/src/uts/common/fs/sockfs/sockcommon_subr.c b/usr/src/uts/common/fs/sockfs/sockcommon_subr.c index d01447c48a..7a585410b3 100644 --- a/usr/src/uts/common/fs/sockfs/sockcommon_subr.c +++ b/usr/src/uts/common/fs/sockfs/sockcommon_subr.c @@ -2239,6 +2239,8 @@ so_tpi_fallback(struct sonode *so, struct cred *cr) bcopy(so, &origso, sizeof (*so)); #endif + sp->sp_stats.sps_nfallback.value.ui64++; + newsp = sockparams_hold_ephemeral_bydev(so->so_family, so->so_type, so->so_protocol, so->so_sockparams->sp_sdev_info.sd_devpath, KM_SLEEP, &error); diff --git a/usr/src/uts/common/fs/sockfs/sockparams.c b/usr/src/uts/common/fs/sockfs/sockparams.c index c72c32805d..50df715aaf 100644 --- a/usr/src/uts/common/fs/sockfs/sockparams.c +++ b/usr/src/uts/common/fs/sockfs/sockparams.c @@ -76,6 +76,16 @@ static krwlock_t splist_lock; static list_t sp_ephem_list; static krwlock_t sp_ephem_lock; +/* Global kstats for sockparams */ +typedef struct sockparams_g_stats { + kstat_named_t spgs_ephem_nalloc; + kstat_named_t spgs_ephem_nreuse; +} sockparams_g_stats_t; + +static sockparams_g_stats_t sp_g_stats; +static kstat_t *sp_g_kstat; + + void sockparams_init(void) { @@ -86,6 +96,75 @@ sockparams_init(void) rw_init(&splist_lock, NULL, RW_DEFAULT, NULL); rw_init(&sp_ephem_lock, NULL, RW_DEFAULT, NULL); + + kstat_named_init(&sp_g_stats.spgs_ephem_nalloc, "ephemeral_nalloc", + KSTAT_DATA_UINT64); + kstat_named_init(&sp_g_stats.spgs_ephem_nreuse, "ephemeral_nreuse", + KSTAT_DATA_UINT64); + + sp_g_kstat = kstat_create("sockfs", 0, "sockparams", "misc", + KSTAT_TYPE_NAMED, sizeof (sp_g_stats) / sizeof (kstat_named_t), + KSTAT_FLAG_VIRTUAL); + if (sp_g_kstat == NULL) + return; + + sp_g_kstat->ks_data = &sp_g_stats; + + kstat_install(sp_g_kstat); +} + +static int +sockparams_kstat_update(kstat_t *ksp, int rw) +{ + struct sockparams *sp = ksp->ks_private; + sockparams_stats_t *sps = ksp->ks_data; + + if (rw == KSTAT_WRITE) + return (EACCES); + + sps->sps_nactive.value.ui64 = sp->sp_refcnt; + + return (0); +} + +/* + * Setup kstats for the given sockparams entry. + */ +static void +sockparams_kstat_init(struct sockparams *sp) +{ + char name[KSTAT_STRLEN]; + + kstat_named_init(&sp->sp_stats.sps_nfallback, "nfallback", + KSTAT_DATA_UINT64); + kstat_named_init(&sp->sp_stats.sps_nactive, "nactive", + KSTAT_DATA_UINT64); + kstat_named_init(&sp->sp_stats.sps_ncreate, "ncreate", + KSTAT_DATA_UINT64); + + (void) snprintf(name, KSTAT_STRLEN, "socket_%d_%d_%d", sp->sp_family, + sp->sp_type, sp->sp_protocol); + + sp->sp_kstat = kstat_create("sockfs", 0, name, "misc", KSTAT_TYPE_NAMED, + sizeof (sockparams_stats_t) / sizeof (kstat_named_t), + KSTAT_FLAG_VIRTUAL); + + if (sp->sp_kstat == NULL) + return; + + sp->sp_kstat->ks_data = &sp->sp_stats; + sp->sp_kstat->ks_update = sockparams_kstat_update; + sp->sp_kstat->ks_private = sp; + kstat_install(sp->sp_kstat); +} + +static void +sockparams_kstat_fini(struct sockparams *sp) +{ + if (sp->sp_kstat != NULL) { + kstat_delete(sp->sp_kstat); + sp->sp_kstat = NULL; + } } /* @@ -148,6 +227,15 @@ sockparams_create(int family, int type, int protocol, char *modname, sp->sp_refcnt = 0; sp->sp_flags = flags; + /* + * We do not create kstats for ephemeral entries, but we do keep + * track how many we have created. + */ + if (sp->sp_flags & SOCKPARAMS_EPHEMERAL) + sp_g_stats.spgs_ephem_nalloc.value.ui64++; + else + sockparams_kstat_init(sp); + if (modname != NULL) { sp->sp_smod_name = modname; } else { @@ -177,8 +265,10 @@ error: kmem_free(modname, strlen(modname) + 1); if (devpathlen != 0) kmem_free(devpath, devpathlen); - if (sp != NULL) + if (sp != NULL) { + sockparams_kstat_fini(sp); kmem_free(sp, sizeof (*sp)); + } return (NULL); } @@ -236,6 +326,7 @@ sockparams_destroy(struct sockparams *sp) sp->sp_smod_name = NULL; sp->sp_smod_info = NULL; mutex_destroy(&sp->sp_lock); + sockparams_kstat_fini(sp); kmem_free(sp, sizeof (*sp)); } @@ -325,6 +416,7 @@ sockparams_hold_ephemeral(int family, int type, int protocol, if (sp != NULL) { SOCKPARAMS_INC_REF(sp); rw_exit(&sp_ephem_lock); + sp_g_stats.spgs_ephem_nreuse.value.ui64++; return (sp); } else { diff --git a/usr/src/uts/common/sys/socketvar.h b/usr/src/uts/common/sys/socketvar.h index f4f026fd77..928b508f55 100644 --- a/usr/src/uts/common/sys/socketvar.h +++ b/usr/src/uts/common/sys/socketvar.h @@ -54,6 +54,7 @@ #include <sys/socket.h> #include <sys/ksocket.h> #include <sys/sodirect.h> +#include <sys/kstat.h> #ifdef __cplusplus extern "C" { @@ -410,6 +411,12 @@ typedef struct smod_info { list_node_t smod_node; } smod_info_t; +typedef struct sockparams_stats { + kstat_named_t sps_nfallback; /* # of fallbacks to TPI */ + kstat_named_t sps_nactive; /* # of active sockets */ + kstat_named_t sps_ncreate; /* total # of created sockets */ +} sockparams_stats_t; + /* * sockparams * @@ -431,6 +438,8 @@ struct sockparams { kmutex_t sp_lock; /* lock for refcnt */ uint64_t sp_refcnt; /* entry reference count */ + sockparams_stats_t sp_stats; + kstat_t *sp_kstat; /* * The entries below are only modified while holding |