summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/sockfs/sockcommon.c2
-rw-r--r--usr/src/uts/common/fs/sockfs/sockcommon_subr.c2
-rw-r--r--usr/src/uts/common/fs/sockfs/sockparams.c94
-rw-r--r--usr/src/uts/common/sys/socketvar.h9
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