1adc56f5aSEdward Tomasz Napierala /*- 2adc56f5aSEdward Tomasz Napierala * Copyright (c) 2016-2018 Netflix, Inc. 3adc56f5aSEdward Tomasz Napierala * All rights reserved. 4adc56f5aSEdward Tomasz Napierala * 5adc56f5aSEdward Tomasz Napierala * Redistribution and use in source and binary forms, with or without 6adc56f5aSEdward Tomasz Napierala * modification, are permitted provided that the following conditions 7adc56f5aSEdward Tomasz Napierala * are met: 8adc56f5aSEdward Tomasz Napierala * 1. Redistributions of source code must retain the above copyright 9adc56f5aSEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer. 10adc56f5aSEdward Tomasz Napierala * 2. Redistributions in binary form must reproduce the above copyright 11adc56f5aSEdward Tomasz Napierala * notice, this list of conditions and the following disclaimer in the 12adc56f5aSEdward Tomasz Napierala * documentation and/or other materials provided with the distribution. 13adc56f5aSEdward Tomasz Napierala * 14adc56f5aSEdward Tomasz Napierala * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15adc56f5aSEdward Tomasz Napierala * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16adc56f5aSEdward Tomasz Napierala * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17adc56f5aSEdward Tomasz Napierala * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18adc56f5aSEdward Tomasz Napierala * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19adc56f5aSEdward Tomasz Napierala * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20adc56f5aSEdward Tomasz Napierala * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21adc56f5aSEdward Tomasz Napierala * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22adc56f5aSEdward Tomasz Napierala * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23adc56f5aSEdward Tomasz Napierala * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24adc56f5aSEdward Tomasz Napierala * SUCH DAMAGE. 25adc56f5aSEdward Tomasz Napierala */ 26adc56f5aSEdward Tomasz Napierala 27adc56f5aSEdward Tomasz Napierala /* 28adc56f5aSEdward Tomasz Napierala * Author: Lawrence Stewart <lstewart@netflix.com> 29adc56f5aSEdward Tomasz Napierala */ 30adc56f5aSEdward Tomasz Napierala 31adc56f5aSEdward Tomasz Napierala #include <sys/cdefs.h> 32adc56f5aSEdward Tomasz Napierala __FBSDID("$FreeBSD$"); 33adc56f5aSEdward Tomasz Napierala 34adc56f5aSEdward Tomasz Napierala #include <sys/param.h> 35adc56f5aSEdward Tomasz Napierala #include <sys/arb.h> 36adc56f5aSEdward Tomasz Napierala #include <sys/errno.h> 37adc56f5aSEdward Tomasz Napierala #include <sys/malloc.h> 38adc56f5aSEdward Tomasz Napierala #include <sys/qmath.h> 39adc56f5aSEdward Tomasz Napierala #include <sys/queue.h> 40adc56f5aSEdward Tomasz Napierala #include <sys/socket.h> 41adc56f5aSEdward Tomasz Napierala #include <sys/socketvar.h> 42adc56f5aSEdward Tomasz Napierala #include <sys/sysctl.h> 43adc56f5aSEdward Tomasz Napierala #ifdef _KERNEL 44adc56f5aSEdward Tomasz Napierala #include <sys/kernel.h> 45adc56f5aSEdward Tomasz Napierala #include <sys/lock.h> 46adc56f5aSEdward Tomasz Napierala #include <sys/rmlock.h> 47adc56f5aSEdward Tomasz Napierala #include <sys/systm.h> 48adc56f5aSEdward Tomasz Napierala #endif 49adc56f5aSEdward Tomasz Napierala #include <sys/stats.h> 50adc56f5aSEdward Tomasz Napierala 51adc56f5aSEdward Tomasz Napierala #include <net/vnet.h> 52adc56f5aSEdward Tomasz Napierala 53adc56f5aSEdward Tomasz Napierala #include <netinet/in.h> 54adc56f5aSEdward Tomasz Napierala #include <netinet/in_pcb.h> 55adc56f5aSEdward Tomasz Napierala #include <netinet/tcp.h> 56adc56f5aSEdward Tomasz Napierala #include <netinet/tcp_var.h> 57adc56f5aSEdward Tomasz Napierala 58adc56f5aSEdward Tomasz Napierala #include <netinet/cc/cc.h> 59adc56f5aSEdward Tomasz Napierala 60adc56f5aSEdward Tomasz Napierala VNET_DEFINE(int, tcp_perconn_stats_dflt_tpl) = -1; 61adc56f5aSEdward Tomasz Napierala 62adc56f5aSEdward Tomasz Napierala #ifndef _KERNEL 63adc56f5aSEdward Tomasz Napierala #define V_tcp_perconn_stats_enable VNET(tcp_perconn_stats_enable) 64adc56f5aSEdward Tomasz Napierala #define V_tcp_perconn_stats_dflt_tpl VNET(tcp_perconn_stats_dflt_tpl) 65adc56f5aSEdward Tomasz Napierala #else /* _KERNEL */ 66adc56f5aSEdward Tomasz Napierala 67adc56f5aSEdward Tomasz Napierala VNET_DEFINE(int, tcp_perconn_stats_enable) = 2; 68adc56f5aSEdward Tomasz Napierala VNET_DEFINE_STATIC(struct stats_tpl_sample_rate *, tcp_perconn_stats_sample_rates); 69adc56f5aSEdward Tomasz Napierala VNET_DEFINE_STATIC(int, tcp_stats_nrates) = 0; 70adc56f5aSEdward Tomasz Napierala #define V_tcp_perconn_stats_sample_rates VNET(tcp_perconn_stats_sample_rates) 71adc56f5aSEdward Tomasz Napierala #define V_tcp_stats_nrates VNET(tcp_stats_nrates) 72adc56f5aSEdward Tomasz Napierala 73adc56f5aSEdward Tomasz Napierala static struct rmlock tcp_stats_tpl_sampling_lock; 74adc56f5aSEdward Tomasz Napierala static int tcp_stats_tpl_sr_cb(enum stats_tpl_sr_cb_action action, 75adc56f5aSEdward Tomasz Napierala struct stats_tpl_sample_rate **rates, int *nrates, void *ctx); 76adc56f5aSEdward Tomasz Napierala 77adc56f5aSEdward Tomasz Napierala SYSCTL_INT(_net_inet_tcp, OID_AUTO, perconn_stats_enable, 78adc56f5aSEdward Tomasz Napierala CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(tcp_perconn_stats_enable), 0, 79adc56f5aSEdward Tomasz Napierala "Enable per-connection TCP stats gathering; 1 enables for all connections, " 80adc56f5aSEdward Tomasz Napierala "2 enables random sampling across log id connection groups"); 81adc56f5aSEdward Tomasz Napierala SYSCTL_PROC(_net_inet_tcp, OID_AUTO, perconn_stats_sample_rates, 827029da5cSPawel Biernacki CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_NEEDGIANT, tcp_stats_tpl_sr_cb, 83adc56f5aSEdward Tomasz Napierala sizeof(struct rm_priotracker), stats_tpl_sample_rates, "A", 84adc56f5aSEdward Tomasz Napierala "TCP stats per template random sampling rates, in CSV tpl_spec=percent " 85adc56f5aSEdward Tomasz Napierala "key-value pairs (see stats(9) for template spec details)"); 86adc56f5aSEdward Tomasz Napierala #endif /* _KERNEL */ 87adc56f5aSEdward Tomasz Napierala 88adc56f5aSEdward Tomasz Napierala #ifdef _KERNEL 89adc56f5aSEdward Tomasz Napierala int 90adc56f5aSEdward Tomasz Napierala #else 91adc56f5aSEdward Tomasz Napierala static int 92adc56f5aSEdward Tomasz Napierala /* Ensure all templates are also added to the userland template list. */ 93adc56f5aSEdward Tomasz Napierala __attribute__ ((constructor)) 94adc56f5aSEdward Tomasz Napierala #endif 95*937b00acSMateusz Guzik tcp_stats_init(void) 96adc56f5aSEdward Tomasz Napierala { 97adc56f5aSEdward Tomasz Napierala int err, lasterr; 98adc56f5aSEdward Tomasz Napierala 99adc56f5aSEdward Tomasz Napierala err = lasterr = 0; 100adc56f5aSEdward Tomasz Napierala 101adc56f5aSEdward Tomasz Napierala V_tcp_perconn_stats_dflt_tpl = stats_tpl_alloc("TCP_DEFAULT", 0); 102adc56f5aSEdward Tomasz Napierala if (V_tcp_perconn_stats_dflt_tpl < 0) 103adc56f5aSEdward Tomasz Napierala return (-V_tcp_perconn_stats_dflt_tpl); 104adc56f5aSEdward Tomasz Napierala 105adc56f5aSEdward Tomasz Napierala struct voistatspec vss_sum[] = { 106adc56f5aSEdward Tomasz Napierala STATS_VSS_SUM(), 107adc56f5aSEdward Tomasz Napierala }; 108adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 109adc56f5aSEdward Tomasz Napierala VOI_TCP_TXPB, "TCP_TXPB", VSD_DTYPE_INT_U64, 110adc56f5aSEdward Tomasz Napierala NVSS(vss_sum), vss_sum, 0); 111adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 112adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 113adc56f5aSEdward Tomasz Napierala VOI_TCP_RETXPB, "TCP_RETXPB", VSD_DTYPE_INT_U32, 114adc56f5aSEdward Tomasz Napierala NVSS(vss_sum), vss_sum, 0); 115adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 116adc56f5aSEdward Tomasz Napierala 117adc56f5aSEdward Tomasz Napierala struct voistatspec vss_max[] = { 118adc56f5aSEdward Tomasz Napierala STATS_VSS_MAX(), 119adc56f5aSEdward Tomasz Napierala }; 120adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 121adc56f5aSEdward Tomasz Napierala VOI_TCP_FRWIN, "TCP_FRWIN", VSD_DTYPE_INT_ULONG, 122adc56f5aSEdward Tomasz Napierala NVSS(vss_max), vss_max, 0); 123adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 124adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 125adc56f5aSEdward Tomasz Napierala VOI_TCP_LCWIN, "TCP_LCWIN", VSD_DTYPE_INT_ULONG, 126adc56f5aSEdward Tomasz Napierala NVSS(vss_max), vss_max, 0); 127adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 128adc56f5aSEdward Tomasz Napierala 129adc56f5aSEdward Tomasz Napierala struct voistatspec vss_rtt[] = { 130adc56f5aSEdward Tomasz Napierala STATS_VSS_MAX(), 131adc56f5aSEdward Tomasz Napierala STATS_VSS_MIN(), 132adc56f5aSEdward Tomasz Napierala STATS_VSS_TDGSTCLUST32(20, 4), 133adc56f5aSEdward Tomasz Napierala }; 134adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 135adc56f5aSEdward Tomasz Napierala VOI_TCP_RTT, "TCP_RTT", VSD_DTYPE_INT_U32, 136adc56f5aSEdward Tomasz Napierala NVSS(vss_rtt), vss_rtt, 0); 137adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 138adc56f5aSEdward Tomasz Napierala 139adc56f5aSEdward Tomasz Napierala struct voistatspec vss_congsig[] = { 140adc56f5aSEdward Tomasz Napierala STATS_VSS_DVHIST32_USR(HBKTS(DVBKT(CC_ECN), DVBKT(CC_RTO), 141adc56f5aSEdward Tomasz Napierala DVBKT(CC_RTO_ERR), DVBKT(CC_NDUPACK)), 0) 142adc56f5aSEdward Tomasz Napierala }; 143adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 144adc56f5aSEdward Tomasz Napierala VOI_TCP_CSIG, "TCP_CSIG", VSD_DTYPE_INT_U32, 145adc56f5aSEdward Tomasz Napierala NVSS(vss_congsig), vss_congsig, 0); 146adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 147adc56f5aSEdward Tomasz Napierala 148adc56f5aSEdward Tomasz Napierala struct voistatspec vss_gput[] = { 149adc56f5aSEdward Tomasz Napierala STATS_VSS_MAX(), 150adc56f5aSEdward Tomasz Napierala STATS_VSS_TDGSTCLUST32(20, 4), 151adc56f5aSEdward Tomasz Napierala }; 152adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 153adc56f5aSEdward Tomasz Napierala VOI_TCP_GPUT, "TCP_GPUT", VSD_DTYPE_INT_U32, 154adc56f5aSEdward Tomasz Napierala NVSS(vss_gput), vss_gput, 0); 155adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 156adc56f5aSEdward Tomasz Napierala 157adc56f5aSEdward Tomasz Napierala struct voistatspec vss_gput_nd[] = { 158adc56f5aSEdward Tomasz Napierala STATS_VSS_TDGSTCLUST32(10, 4), 159adc56f5aSEdward Tomasz Napierala }; 160adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 161adc56f5aSEdward Tomasz Napierala VOI_TCP_GPUT_ND, "TCP_GPUT_ND", VSD_DTYPE_INT_S32, 162adc56f5aSEdward Tomasz Napierala NVSS(vss_gput_nd), vss_gput_nd, 0); 163adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 164adc56f5aSEdward Tomasz Napierala 165adc56f5aSEdward Tomasz Napierala struct voistatspec vss_windiff[] = { 166adc56f5aSEdward Tomasz Napierala STATS_VSS_CRHIST32_USR(HBKTS(CRBKT(0)), VSD_HIST_LBOUND_INF) 167adc56f5aSEdward Tomasz Napierala }; 168adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 169adc56f5aSEdward Tomasz Napierala VOI_TCP_CALCFRWINDIFF, "TCP_CALCFRWINDIFF", VSD_DTYPE_INT_S32, 170adc56f5aSEdward Tomasz Napierala NVSS(vss_windiff), vss_windiff, 0); 171adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 172adc56f5aSEdward Tomasz Napierala 173adc56f5aSEdward Tomasz Napierala struct voistatspec vss_acklen[] = { 174adc56f5aSEdward Tomasz Napierala STATS_VSS_MAX(), 175adc56f5aSEdward Tomasz Napierala STATS_VSS_CRHIST32_LIN(0, 9, 1, VSD_HIST_UBOUND_INF) 176adc56f5aSEdward Tomasz Napierala }; 177adc56f5aSEdward Tomasz Napierala err |= stats_tpl_add_voistats(V_tcp_perconn_stats_dflt_tpl, 178adc56f5aSEdward Tomasz Napierala VOI_TCP_ACKLEN, "TCP_ACKLEN", VSD_DTYPE_INT_U32, 179adc56f5aSEdward Tomasz Napierala NVSS(vss_acklen), vss_acklen, 0); 180adc56f5aSEdward Tomasz Napierala lasterr = err ? err : lasterr; 181adc56f5aSEdward Tomasz Napierala 182adc56f5aSEdward Tomasz Napierala return (lasterr); 183adc56f5aSEdward Tomasz Napierala } 184adc56f5aSEdward Tomasz Napierala 185adc56f5aSEdward Tomasz Napierala #ifdef _KERNEL 186adc56f5aSEdward Tomasz Napierala int 187adc56f5aSEdward Tomasz Napierala tcp_stats_sample_rollthedice(struct tcpcb *tp, void *seed_bytes, 188adc56f5aSEdward Tomasz Napierala size_t seed_len) 189adc56f5aSEdward Tomasz Napierala { 190adc56f5aSEdward Tomasz Napierala struct rm_priotracker tracker; 191adc56f5aSEdward Tomasz Napierala int tpl; 192adc56f5aSEdward Tomasz Napierala 193adc56f5aSEdward Tomasz Napierala tpl = -1; 194adc56f5aSEdward Tomasz Napierala 195adc56f5aSEdward Tomasz Napierala if (V_tcp_stats_nrates > 0) { 196adc56f5aSEdward Tomasz Napierala rm_rlock(&tcp_stats_tpl_sampling_lock, &tracker); 197adc56f5aSEdward Tomasz Napierala tpl = stats_tpl_sample_rollthedice(V_tcp_perconn_stats_sample_rates, 198adc56f5aSEdward Tomasz Napierala V_tcp_stats_nrates, seed_bytes, seed_len); 199adc56f5aSEdward Tomasz Napierala rm_runlock(&tcp_stats_tpl_sampling_lock, &tracker); 200adc56f5aSEdward Tomasz Napierala 201adc56f5aSEdward Tomasz Napierala if (tpl >= 0) { 2029eb0e832SGleb Smirnoff INP_WLOCK_ASSERT(tptoinpcb(tp)); 203adc56f5aSEdward Tomasz Napierala if (tp->t_stats != NULL) 204adc56f5aSEdward Tomasz Napierala stats_blob_destroy(tp->t_stats); 205adc56f5aSEdward Tomasz Napierala tp->t_stats = stats_blob_alloc(tpl, 0); 206adc56f5aSEdward Tomasz Napierala if (tp->t_stats == NULL) 207adc56f5aSEdward Tomasz Napierala tpl = -ENOMEM; 208adc56f5aSEdward Tomasz Napierala } 209adc56f5aSEdward Tomasz Napierala } 210adc56f5aSEdward Tomasz Napierala 211adc56f5aSEdward Tomasz Napierala return (tpl); 212adc56f5aSEdward Tomasz Napierala } 213adc56f5aSEdward Tomasz Napierala 214adc56f5aSEdward Tomasz Napierala /* 215adc56f5aSEdward Tomasz Napierala * Callback function for stats_tpl_sample_rates() to interact with the TCP 216adc56f5aSEdward Tomasz Napierala * subsystem's stats template sample rates list. 217adc56f5aSEdward Tomasz Napierala */ 218adc56f5aSEdward Tomasz Napierala int 219adc56f5aSEdward Tomasz Napierala tcp_stats_tpl_sr_cb(enum stats_tpl_sr_cb_action action, 220adc56f5aSEdward Tomasz Napierala struct stats_tpl_sample_rate **rates, int *nrates, void *ctx) 221adc56f5aSEdward Tomasz Napierala { 222adc56f5aSEdward Tomasz Napierala struct stats_tpl_sample_rate *old_rates; 223adc56f5aSEdward Tomasz Napierala int old_nrates; 224adc56f5aSEdward Tomasz Napierala 225adc56f5aSEdward Tomasz Napierala if (ctx == NULL) 226adc56f5aSEdward Tomasz Napierala return (ENOMEM); 227adc56f5aSEdward Tomasz Napierala 228adc56f5aSEdward Tomasz Napierala switch (action) { 229adc56f5aSEdward Tomasz Napierala case TPL_SR_RLOCKED_GET: 230adc56f5aSEdward Tomasz Napierala /* 231adc56f5aSEdward Tomasz Napierala * Return with rlock held i.e. this call must be paired with a 232adc56f5aSEdward Tomasz Napierala * "action == TPL_SR_RUNLOCK" call. 233adc56f5aSEdward Tomasz Napierala */ 234adc56f5aSEdward Tomasz Napierala rm_assert(&tcp_stats_tpl_sampling_lock, RA_UNLOCKED); 235adc56f5aSEdward Tomasz Napierala rm_rlock(&tcp_stats_tpl_sampling_lock, 236adc56f5aSEdward Tomasz Napierala (struct rm_priotracker *)ctx); 237adc56f5aSEdward Tomasz Napierala /* FALLTHROUGH */ 238adc56f5aSEdward Tomasz Napierala case TPL_SR_UNLOCKED_GET: 239adc56f5aSEdward Tomasz Napierala if (rates != NULL) 240adc56f5aSEdward Tomasz Napierala *rates = V_tcp_perconn_stats_sample_rates; 241adc56f5aSEdward Tomasz Napierala if (nrates != NULL) 242adc56f5aSEdward Tomasz Napierala *nrates = V_tcp_stats_nrates; 243adc56f5aSEdward Tomasz Napierala break; 244adc56f5aSEdward Tomasz Napierala case TPL_SR_RUNLOCK: 245adc56f5aSEdward Tomasz Napierala rm_assert(&tcp_stats_tpl_sampling_lock, RA_RLOCKED); 246adc56f5aSEdward Tomasz Napierala rm_runlock(&tcp_stats_tpl_sampling_lock, 247adc56f5aSEdward Tomasz Napierala (struct rm_priotracker *)ctx); 248adc56f5aSEdward Tomasz Napierala break; 249adc56f5aSEdward Tomasz Napierala case TPL_SR_PUT: 250adc56f5aSEdward Tomasz Napierala KASSERT(rates != NULL && nrates != NULL, 251adc56f5aSEdward Tomasz Napierala ("%s: PUT without new rates", __func__)); 252adc56f5aSEdward Tomasz Napierala rm_assert(&tcp_stats_tpl_sampling_lock, RA_UNLOCKED); 253adc56f5aSEdward Tomasz Napierala if (rates == NULL || nrates == NULL) 254adc56f5aSEdward Tomasz Napierala return (EINVAL); 255adc56f5aSEdward Tomasz Napierala rm_wlock(&tcp_stats_tpl_sampling_lock); 256adc56f5aSEdward Tomasz Napierala old_rates = V_tcp_perconn_stats_sample_rates; 257adc56f5aSEdward Tomasz Napierala old_nrates = V_tcp_stats_nrates; 258adc56f5aSEdward Tomasz Napierala V_tcp_perconn_stats_sample_rates = *rates; 259adc56f5aSEdward Tomasz Napierala V_tcp_stats_nrates = *nrates; 260adc56f5aSEdward Tomasz Napierala rm_wunlock(&tcp_stats_tpl_sampling_lock); 261adc56f5aSEdward Tomasz Napierala *rates = old_rates; 262adc56f5aSEdward Tomasz Napierala *nrates = old_nrates; 263adc56f5aSEdward Tomasz Napierala break; 264adc56f5aSEdward Tomasz Napierala default: 265adc56f5aSEdward Tomasz Napierala return (EINVAL); 266adc56f5aSEdward Tomasz Napierala break; 267adc56f5aSEdward Tomasz Napierala } 268adc56f5aSEdward Tomasz Napierala 269adc56f5aSEdward Tomasz Napierala return (0); 270adc56f5aSEdward Tomasz Napierala } 271adc56f5aSEdward Tomasz Napierala 272adc56f5aSEdward Tomasz Napierala RM_SYSINIT(tcp_stats_tpl_sampling_lock, &tcp_stats_tpl_sampling_lock, 273adc56f5aSEdward Tomasz Napierala "tcp_stats_tpl_sampling_lock"); 274adc56f5aSEdward Tomasz Napierala #endif /* _KERNEL */ 275