Make DDP stats per-cpu. While here, bump the counters to 64-bit and

make them available by sysctl.
This commit is contained in:
thorpej 2008-04-23 15:17:42 +00:00
parent 9fc1984c89
commit d2d995427e
6 changed files with 170 additions and 80 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ddp_input.c,v 1.17 2007/12/21 02:46:37 dyoung Exp $ */
/* $NetBSD: ddp_input.c,v 1.18 2008/04/23 15:17:42 thorpej Exp $ */
/*
* Copyright (c) 1990,1994 Regents of The University of Michigan.
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.17 2007/12/21 02:46:37 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.18 2008/04/23 15:17:42 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.17 2007/12/21 02:46:37 dyoung Exp $"
#include <netatalk/at_var.h>
#include <netatalk/ddp.h>
#include <netatalk/ddp_var.h>
#include <netatalk/ddp_private.h>
#include <netatalk/at_extern.h>
int ddp_forward = 1;
@ -113,7 +114,7 @@ atintr()
}
if (m->m_len < SZ_ELAPHDR &&
((m = m_pullup(m, SZ_ELAPHDR)) == 0)) {
ddpstat.ddps_tooshort++;
DDP_STATINC(DDP_STAT_TOOSHORT);
continue;
}
elhp = mtod(m, struct elaphdr *);
@ -152,11 +153,11 @@ ddp_input(m, ifp, elh, phase)
bzero((void *) & from, sizeof(struct sockaddr_at));
if (elh) {
ddpstat.ddps_short++;
DDP_STATINC(DDP_STAT_SHORT);
if (m->m_len < sizeof(struct ddpshdr) &&
((m = m_pullup(m, sizeof(struct ddpshdr))) == 0)) {
ddpstat.ddps_tooshort++;
DDP_STATINC(DDP_STAT_TOOSHORT);
return;
}
dsh = mtod(m, struct ddpshdr *);
@ -184,11 +185,11 @@ ddp_input(m, ifp, elh, phase)
return;
}
} else {
ddpstat.ddps_long++;
DDP_STATINC(DDP_STAT_LONG);
if (m->m_len < sizeof(struct ddpehdr) &&
((m = m_pullup(m, sizeof(struct ddpehdr))) == 0)) {
ddpstat.ddps_tooshort++;
DDP_STATINC(DDP_STAT_TOOSHORT);
return;
}
deh = mtod(m, struct ddpehdr *);
@ -197,7 +198,7 @@ ddp_input(m, ifp, elh, phase)
dlen = ddpe.deh_len;
if ((cksum = ddpe.deh_sum) == 0) {
ddpstat.ddps_nosum++;
DDP_STATINC(DDP_STAT_NOSUM);
}
from.sat_addr.s_net = ddpe.deh_snet;
from.sat_addr.s_node = ddpe.deh_snode;
@ -255,7 +256,7 @@ ddp_input(m, ifp, elh, phase)
*/
mlen = m->m_pkthdr.len;
if (mlen < dlen) {
ddpstat.ddps_toosmall++;
DDP_STATINC(DDP_STAT_TOOSMALL);
m_freem(m);
return;
}
@ -292,9 +293,9 @@ ddp_input(m, ifp, elh, phase)
ddpe.deh_bytes = htonl(ddpe.deh_bytes);
bcopy((void *) & ddpe, (void *) deh, sizeof(u_short));/*XXX*/
if (ddp_route(m, &forwro)) {
ddpstat.ddps_cantforward++;
DDP_STATINC(DDP_STAT_CANTFORWARD);
} else {
ddpstat.ddps_forward++;
DDP_STATINC(DDP_STAT_FORWARD);
}
return;
}
@ -305,7 +306,7 @@ ddp_input(m, ifp, elh, phase)
m_adj(m, sizeof(struct ddpshdr));
} else {
if (ddp_cksum && cksum && cksum != at_cksum(m, sizeof(int))) {
ddpstat.ddps_badsum++;
DDP_STATINC(DDP_STAT_BADSUM);
m_freem(m);
return;
}
@ -318,7 +319,7 @@ ddp_input(m, ifp, elh, phase)
}
if (sbappendaddr(&ddp->ddp_socket->so_rcv, (struct sockaddr *) & from,
m, (struct mbuf *) 0) == 0) {
ddpstat.ddps_nosockspace++;
DDP_STATINC(DDP_STAT_NOSOCKSPACE);
m_freem(m);
return;
}

View File

@ -0,0 +1,50 @@
/* $NetBSD: ddp_private.h,v 1.1 2008/04/23 15:24:14 thorpej Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jason R. Thorpe.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _NETATALK_DDP_PRIVATE_H_
#define _NETATALK_DDP_PRIVATE_H_
#ifdef _KERNEL
#include <net/net_stats.h>
extern percpu_t *ddpstat_percpu;
#define DDP_STATINC(x) _NET_STATINC(ddpstat_percpu, x)
#endif /* _KERNEL */
#endif /* !_NETATALK_DDP_PRIVATE_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ddp_usrreq.c,v 1.30 2008/01/28 18:28:31 dyoung Exp $ */
/* $NetBSD: ddp_usrreq.c,v 1.31 2008/04/23 15:17:42 thorpej Exp $ */
/*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.30 2008/01/28 18:28:31 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.31 2008/04/23 15:17:42 thorpej Exp $");
#include "opt_mbuftrace.h"
@ -42,14 +42,17 @@ __KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.30 2008/01/28 18:28:31 dyoung Exp $
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/kauth.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/route.h>
#include <net/if_ether.h>
#include <net/net_stats.h>
#include <netinet/in.h>
#include <netatalk/at.h>
#include <netatalk/at_var.h>
#include <netatalk/ddp_var.h>
#include <netatalk/ddp_private.h>
#include <netatalk/aarp.h>
#include <netatalk/at_extern.h>
@ -63,7 +66,7 @@ static int at_pcballoc __P((struct socket *));
struct ifqueue atintrq1, atintrq2;
struct ddpcb *ddp_ports[ATPORT_LAST];
struct ddpcb *ddpcb = NULL;
struct ddpstat ddpstat;
percpu_t *ddpstat_percpu;
struct at_ifaddrhead at_ifaddr; /* Here as inited in this file */
u_long ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */
u_long ddp_recvspace = 25 * (587 + sizeof(struct sockaddr_at));
@ -550,8 +553,11 @@ ddp_search(
* Initialize all the ddp & appletalk stuff
*/
void
ddp_init()
ddp_init(void)
{
ddpstat_percpu = percpu_alloc(sizeof(uint64_t) * DDP_NSTATS);
TAILQ_INIT(&at_ifaddr);
atintrq1.ifq_maxlen = IFQ_MAXLEN;
atintrq2.ifq_maxlen = IFQ_MAXLEN;
@ -570,3 +576,47 @@ ddp_clean()
at_pcbdetach(ddp->ddp_socket, ddp);
}
#endif
static int
sysctl_net_atalk_ddp_stats(SYSCTLFN_ARGS)
{
netstat_sysctl_context ctx;
uint64_t ddps[DDP_NSTATS];
ctx.ctx_stat = ddpstat_percpu;
ctx.ctx_counters = ddps;
ctx.ctx_ncounters = DDP_NSTATS;
return (NETSTAT_SYSCTL(&ctx));
}
/*
* Sysctl for DDP variables.
*/
SYSCTL_SETUP(sysctl_net_atalk_ddp_setup, "sysctl net.atalk.ddp subtree setup")
{
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "net", NULL,
NULL, 0, NULL, 0,
CTL_NET, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "atalk", NULL,
NULL, 0, NULL, 0,
CTL_NET, PF_APPLETALK, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "ddp",
SYSCTL_DESCR("DDP related settings"),
NULL, 0, NULL, 0,
CTL_NET, PF_APPLETALK, ATPROTO_DDP, CTL_EOL);
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,
CTLTYPE_STRUCT, "stats",
SYSCTL_DESCR("DDP statistics"),
sysctl_net_atalk_ddp_stats, 0, NULL, 0,
CTL_NET, PF_APPLETALK, ATPROTO_DDP, CTL_CREATE,
CTL_EOL);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ddp_var.h,v 1.3 2005/12/10 23:29:05 elad Exp $ */
/* $NetBSD: ddp_var.h,v 1.4 2008/04/23 15:17:42 thorpej Exp $ */
/*
* Copyright (c) 1990,1994 Regents of The University of Michigan.
@ -39,23 +39,22 @@ struct ddpcb {
#define sotoddpcb(so) ((struct ddpcb *)(so)->so_pcb)
struct ddpstat {
long ddps_short; /* short header packets received */
long ddps_long; /* long header packets received */
long ddps_nosum; /* no checksum */
long ddps_badsum; /* bad checksum */
long ddps_tooshort; /* packet too short */
long ddps_toosmall; /* not enough data */
long ddps_forward; /* packets forwarded */
long ddps_encap; /* packets encapsulated */
long ddps_cantforward; /* packets rcvd for unreachable dest */
long ddps_nosockspace; /* no space in sockbuf for packet */
};
#define DDP_STAT_SHORT 0 /* short header packets received */
#define DDP_STAT_LONG 1 /* long header packets received */
#define DDP_STAT_NOSUM 2 /* no checksum */
#define DDP_STAT_BADSUM 3 /* bad checksum */
#define DDP_STAT_TOOSHORT 4 /* packet too short */
#define DDP_STAT_TOOSMALL 5 /* not enough data */
#define DDP_STAT_FORWARD 6 /* packets forwarded */
#define DDP_STAT_ENCAP 7 /* packets encapsulated */
#define DDP_STAT_CANTFORWARD 8 /* packets rcvd for unreachable net */
#define DDP_STAT_NOSOCKSPACE 9 /* no space in sockbuf for packet */
#define DDP_NSTATS 10
#ifdef _KERNEL
extern struct ddpcb *ddp_ports[];
extern struct ddpcb *ddpcb;
extern struct ddpstat ddpstat;
#endif
#endif /* !_NETATALK_DDP_VAR_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: atalk.c,v 1.10 2006/04/06 18:30:31 rpaulo Exp $ */
/* $NetBSD: atalk.c,v 1.11 2008/04/23 15:17:42 thorpej Exp $ */
/*
* Copyright (c) 1983, 1988, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "from @(#)atalk.c 1.1 (Whistle) 6/6/96";
#else
__RCSID("$NetBSD: atalk.c,v 1.10 2006/04/06 18:30:31 rpaulo Exp $");
__RCSID("$NetBSD: atalk.c,v 1.11 2008/04/23 15:17:42 thorpej Exp $");
#endif
#endif /* not lint */
@ -44,6 +44,7 @@ __RCSID("$NetBSD: atalk.c,v 1.10 2006/04/06 18:30:31 rpaulo Exp $");
#include <sys/socketvar.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/sysctl.h>
#include <net/route.h>
#include <net/if.h>
@ -65,11 +66,6 @@ struct socket sockb;
static int first = 1;
static char *at_pr_net __P((struct sockaddr_at *, int));
static char *at_pr_host __P((struct sockaddr_at *, int));
static char *at_pr_range __P((struct sockaddr_at *));
static char *at_pr_port __P((struct sockaddr_at *));
/*
* Print a summary of connections related to a Network Systems
* protocol. For XXX, also give state of connection.
@ -78,9 +74,7 @@ static char *at_pr_port __P((struct sockaddr_at *));
*/
static char *
at_pr_net(sat, numeric)
struct sockaddr_at *sat;
int numeric;
at_pr_net(struct sockaddr_at *sat, int numeric)
{
static char mybuf[50];
@ -97,9 +91,7 @@ at_pr_net(sat, numeric)
}
static char *
at_pr_host(sat, numeric)
struct sockaddr_at *sat;
int numeric;
at_pr_host(struct sockaddr_at *sat, int numeric)
{
static char mybuf[50];
@ -117,8 +109,7 @@ at_pr_host(sat, numeric)
}
static char *
at_pr_port(sat)
struct sockaddr_at *sat;
at_pr_port(struct sockaddr_at *sat)
{
static char mybuf[50];
@ -135,8 +126,7 @@ at_pr_port(sat)
}
static char *
at_pr_range(sat)
struct sockaddr_at *sat;
at_pr_range(struct sockaddr_at *sat)
{
static char mybuf[50];
@ -160,9 +150,7 @@ at_pr_range(sat)
* 8 for numeric only
*/
char *
atalk_print(sa, what)
const struct sockaddr *sa;
int what;
atalk_print(const struct sockaddr *sa, int what)
{
struct sockaddr_at *sat = (struct sockaddr_at *) sa;
static char mybuf[50];
@ -197,10 +185,7 @@ atalk_print(sa, what)
}
char *
atalk_print2(sa, mask, what)
const struct sockaddr *sa;
const struct sockaddr *mask;
int what;
atalk_print2(const struct sockaddr *sa, const struct sockaddr *mask, int what)
{
int n, l;
static char buf[100];
@ -241,9 +226,7 @@ atalk_print2(sa, mask, what)
}
void
atalkprotopr(off, name)
u_long off;
char *name;
atalkprotopr(u_long off, char *name)
{
struct ddpcb cb;
struct ddpcb *prev, *next;
@ -296,32 +279,40 @@ atalkprotopr(off, name)
}
}
#define ANY(x,y,z) \
((sflag==1 || (x)) ? printf("\t%ld %s%s%s\n",x,y,plural(x),z) : 0)
((sflag==1 || (x)) ? printf("\t%llu %s%s%s\n",(unsigned long long)x,y,plural(x),z) : 0)
/*
* Dump DDP statistics structure.
*/
void
ddp_stats(off, name)
u_long off;
char *name;
ddp_stats(u_long off, char *name)
{
struct ddpstat ddpstat;
uint64_t ddpstat[DDP_NSTATS];
if (use_sysctl) {
size_t size = sizeof(ddpstat);
if (sysctlbyname("net.at.ddp.stats", ddpstat, &size,
NULL, 0) == -1)
return;
} else {
if (off == 0)
return;
if (kread(off, (char *)&ddpstat, sizeof(ddpstat)) < 0)
return;
}
if (off == 0)
return;
if (kread(off, (char *)&ddpstat, sizeof(ddpstat)) < 0)
return;
printf("%s:\n", name);
ANY(ddpstat.ddps_short, "packet", " with short headers ");
ANY(ddpstat.ddps_long, "packet", " with long headers ");
ANY(ddpstat.ddps_nosum, "packet", " with no checksum ");
ANY(ddpstat.ddps_tooshort, "packet", " too short ");
ANY(ddpstat.ddps_badsum, "packet", " with bad checksum ");
ANY(ddpstat.ddps_toosmall, "packet", " with not enough data ");
ANY(ddpstat.ddps_forward, "packet", " forwarded ");
ANY(ddpstat.ddps_encap, "packet", " encapsulated ");
ANY(ddpstat.ddps_cantforward, "packet", " rcvd for unreachable dest ");
ANY(ddpstat.ddps_nosockspace, "packet", " dropped due to no socket space ");
ANY(ddpstat[DDP_STAT_SHORT], "packet", " with short headers ");
ANY(ddpstat[DDP_STAT_LONG], "packet", " with long headers ");
ANY(ddpstat[DDP_STAT_NOSUM], "packet", " with no checksum ");
ANY(ddpstat[DDP_STAT_TOOSHORT], "packet", " too short ");
ANY(ddpstat[DDP_STAT_BADSUM], "packet", " with bad checksum ");
ANY(ddpstat[DDP_STAT_TOOSMALL], "packet", " with not enough data ");
ANY(ddpstat[DDP_STAT_FORWARD], "packet", " forwarded ");
ANY(ddpstat[DDP_STAT_ENCAP], "packet", " encapsulated ");
ANY(ddpstat[DDP_STAT_CANTFORWARD], "packet", " rcvd for unreachable dest ");
ANY(ddpstat[DDP_STAT_NOSOCKSPACE], "packet", " dropped due to no socket space ");
}
#undef ANY

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.66 2008/04/23 07:29:47 thorpej Exp $ */
/* $NetBSD: main.c,v 1.67 2008/04/23 15:17:42 thorpej Exp $ */
/*
* Copyright (c) 1983, 1988, 1993
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1988, 1993\n\
#if 0
static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 3/1/94";
#else
__RCSID("$NetBSD: main.c,v 1.66 2008/04/23 07:29:47 thorpej Exp $");
__RCSID("$NetBSD: main.c,v 1.67 2008/04/23 15:17:42 thorpej Exp $");
#endif
#endif /* not lint */
@ -390,7 +390,6 @@ prepare(char *nlistf, char *memf, struct protox *tp)
iflag ||
#ifndef SMALL
gflag ||
(pflag && tp->pr_sindex == N_DDPSTAT) ||
#ifdef NS
(pflag && tp->pr_sindex == N_IDPSTAT) ||
(pflag && tp->pr_sindex == N_SPPSTAT) ||