6662959 sockfs need kstats to report usage info
diff --git a/usr/src/uts/common/fs/sockfs/sockparams.c b/usr/src/uts/common/fs/sockfs/sockparams.c
index c72c328..50df715 100644
--- a/usr/src/uts/common/fs/sockfs/sockparams.c
+++ b/usr/src/uts/common/fs/sockfs/sockparams.c
@@ -76,6 +76,16 @@
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 @@
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 @@
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 @@
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 @@
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 @@
if (sp != NULL) {
SOCKPARAMS_INC_REF(sp);
rw_exit(&sp_ephem_lock);
+ sp_g_stats.spgs_ephem_nreuse.value.ui64++;
return (sp);
} else {