summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2012-10-28 18:07:34 +0000
committerandre <andre@FreeBSD.org>2012-10-28 18:07:34 +0000
commit2d426461500a5758cfe3fe0a86fcaa42422cfcf6 (patch)
tree7a722d9abcf590658ab9cd9799745d79073658f3
parentdf63a1d6ea0988b75d838ad5677672cddd312063 (diff)
downloadFreeBSD-src-2d426461500a5758cfe3fe0a86fcaa42422cfcf6.zip
FreeBSD-src-2d426461500a5758cfe3fe0a86fcaa42422cfcf6.tar.gz
Change the syncache count reporting the current number of entries
from an unprotected u_int that reports garbage on SMP to a function based sysctl obtaining the current value from UMA. Also read back the actual cache_limit after page size rounding by UMA. PR: kern/165879 MFC after: 2 weeks
-rw-r--r--sys/netinet/tcp_syncache.c23
-rw-r--r--sys/netinet/tcp_syncache.h1
2 files changed, 15 insertions, 9 deletions
diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c
index adb175b..778e762 100644
--- a/sys/netinet/tcp_syncache.c
+++ b/sys/netinet/tcp_syncache.c
@@ -123,6 +123,7 @@ struct syncache *syncache_lookup(struct in_conninfo *, struct syncache_head **);
static int syncache_respond(struct syncache *);
static struct socket *syncache_socket(struct syncache *, struct socket *,
struct mbuf *m);
+static int syncache_sysctl_count(SYSCTL_HANDLER_ARGS);
static void syncache_timeout(struct syncache *sc, struct syncache_head *sch,
int docallout);
static void syncache_timer(void *);
@@ -158,8 +159,8 @@ SYSCTL_VNET_UINT(_net_inet_tcp_syncache, OID_AUTO, cachelimit, CTLFLAG_RDTUN,
&VNET_NAME(tcp_syncache.cache_limit), 0,
"Overall entry limit for syncache");
-SYSCTL_VNET_UINT(_net_inet_tcp_syncache, OID_AUTO, count, CTLFLAG_RD,
- &VNET_NAME(tcp_syncache.cache_count), 0,
+SYSCTL_VNET_PROC(_net_inet_tcp_syncache, OID_AUTO, count, (CTLTYPE_UINT|CTLFLAG_RD),
+ NULL, 0, &syncache_sysctl_count, "IU",
"Current number of entries in syncache");
SYSCTL_VNET_UINT(_net_inet_tcp_syncache, OID_AUTO, hashsize, CTLFLAG_RDTUN,
@@ -225,7 +226,6 @@ syncache_init(void)
{
int i;
- V_tcp_syncache.cache_count = 0;
V_tcp_syncache.hashsize = TCP_SYNCACHE_HASHSIZE;
V_tcp_syncache.bucket_limit = TCP_SYNCACHE_BUCKETLIMIT;
V_tcp_syncache.rexmt_limit = SYNCACHE_MAXREXMTS;
@@ -269,6 +269,7 @@ syncache_init(void)
V_tcp_syncache.zone = uma_zcreate("syncache", sizeof(struct syncache),
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, 0);
uma_zone_set_max(V_tcp_syncache.zone, V_tcp_syncache.cache_limit);
+ V_tcp_syncache.cache_limit = uma_zone_get_max(V_tcp_syncache.zone);
}
#ifdef VIMAGE
@@ -296,8 +297,8 @@ syncache_destroy(void)
mtx_destroy(&sch->sch_mtx);
}
- KASSERT(V_tcp_syncache.cache_count == 0, ("%s: cache_count %d not 0",
- __func__, V_tcp_syncache.cache_count));
+ KASSERT(uma_zone_get_cur(V_tcp_syncache.zone) == 0,
+ ("%s: cache_count not 0", __func__));
/* Free the allocated global resources. */
uma_zdestroy(V_tcp_syncache.zone);
@@ -305,6 +306,15 @@ syncache_destroy(void)
}
#endif
+static int
+syncache_sysctl_count(SYSCTL_HANDLER_ARGS)
+{
+ int count;
+
+ count = uma_zone_get_cur(V_tcp_syncache.zone);
+ return (sysctl_handle_int(oidp, &count, sizeof(count), req));
+}
+
/*
* Inserts a syncache entry into the specified bucket row.
* Locks and unlocks the syncache_head autonomously.
@@ -347,7 +357,6 @@ syncache_insert(struct syncache *sc, struct syncache_head *sch)
SCH_UNLOCK(sch);
- V_tcp_syncache.cache_count++;
TCPSTAT_INC(tcps_sc_added);
}
@@ -373,7 +382,6 @@ syncache_drop(struct syncache *sc, struct syncache_head *sch)
#endif
syncache_free(sc);
- V_tcp_syncache.cache_count--;
}
/*
@@ -958,7 +966,6 @@ syncache_expand(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th,
tod->tod_syncache_removed(tod, sc->sc_todctx);
}
#endif
- V_tcp_syncache.cache_count--;
SCH_UNLOCK(sch);
}
diff --git a/sys/netinet/tcp_syncache.h b/sys/netinet/tcp_syncache.h
index d18ee07..1ff8a46 100644
--- a/sys/netinet/tcp_syncache.h
+++ b/sys/netinet/tcp_syncache.h
@@ -112,7 +112,6 @@ struct tcp_syncache {
u_int hashsize;
u_int hashmask;
u_int bucket_limit;
- u_int cache_count; /* XXX: unprotected */
u_int cache_limit;
u_int rexmt_limit;
u_int hash_secret;
OpenPOWER on IntegriCloud