? pcpu_ipstats.diff Index: ip_input.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_input.c,v retrieving revision 1.23 diff -u -p -u -r1.23 ip_input.c --- ip_input.c 24 Apr 2004 07:05:56 -0000 1.23 +++ ip_input.c 29 Apr 2004 10:21:15 -0000 @@ -181,9 +181,30 @@ SYSCTL_INT(_net_inet_ip, IPCTL_INTRQMAXL SYSCTL_INT(_net_inet_ip, IPCTL_INTRQDROPS, intr_queue_drops, CTLFLAG_RD, &ipintrq.ifq_drops, 0, "Number of packets dropped from the IP input queue"); -struct ipstat ipstat; +struct ip_stats ipstats_ary[MAXCPU]; +#ifdef SMP +static int +sysctl_ipstats(SYSCTL_HANDLER_ARGS) +{ + int cpu, error = 0; + + for (cpu = 0; cpu < ncpus; ++cpu) { + if ((error = SYSCTL_OUT(req, (void *)&ipstats_ary[cpu], + sizeof(struct ip_stats)))) + break; + if ((error = SYSCTL_IN(req, (void *)&ipstats_ary[cpu], + sizeof(struct ip_stats)))) + break; + } + + return (error); +} +SYSCTL_PROC(_net_inet_ip, IPCTL_STATS, stats, (CTLTYPE_OPAQUE | CTLFLAG_RW), + 0, 0, sysctl_ipstats, "S,ip_stats", "IP statistics"); +#else SYSCTL_STRUCT(_net_inet_ip, IPCTL_STATS, stats, CTLFLAG_RW, - &ipstat, ipstat, "IP statistics (struct ipstat, netinet/ip_var.h)"); + &ipstat, ip_stats, "IP statistics"); +#endif /* Packet reassembly stuff */ #define IPREASS_NHASH_LOG2 6 @@ -293,6 +314,21 @@ ip_init() ip_id = time_second & 0xffff; #endif ipintrq.ifq_maxlen = ipqmaxlen; + + /* + * Initialize IP statistics. + * + * It is layed out as an array which is has one element for UP, + * and SMP_MAXCPU elements for SMP. This allows us to retain + * the access mechanism from userland for both UP and SMP. + */ +#ifdef SMP + for (cpu = 0; cpu < ncpus; ++cpu) { + bzero(&ipstats_ary[cpu], sizeof(struct ip_stats)); + } +#else + bzero(&ipstat, sizeof(struct ip_stats)); +#endif netisr_register(NETISR_IP, ip_mport, ip_input_handler); } Index: ip_var.h =================================================================== RCS file: /cvs/src/sys/netinet/ip_var.h,v retrieving revision 1.6 diff -u -p -u -r1.6 ip_var.h --- ip_var.h 6 Mar 2004 07:30:43 -0000 1.6 +++ ip_var.h 29 Apr 2004 10:21:15 -0000 @@ -98,7 +98,23 @@ struct ip_moptions { u_long imo_multicast_vif; /* vif num outgoing multicasts */ }; -struct ipstat { +#ifdef _KERNEL + +#if defined(SMP) +#define _GD mycpu +#define ipstat ipstats_ary[_GD->gd_cpuid] +#else /* !SMP */ +#define ipstat ipstats_ary[0] +#endif + +struct ip_stats; +extern struct ip_stats ipstats_ary[MAXCPU]; +#endif + +/* + * IP Statistics. + */ +struct ip_stats { u_long ips_total; /* total packets received */ u_long ips_badsum; /* checksum bad */ u_long ips_tooshort; /* packet too short */ @@ -144,7 +160,6 @@ struct route; struct sockopt; struct lwkt_port; -extern struct ipstat ipstat; #ifndef RANDOM_IP_ID extern u_short ip_id; /* ip packet ctr, for ids */ #endif