Home | History | Annotate | Line # | Download | only in pfctl
pfctl_qstats.c revision 1.1.1.3
      1  1.1.1.3  martti /*	$NetBSD: pfctl_qstats.c,v 1.1.1.3 2009/12/01 07:03:09 martti Exp $	*/
      2  1.1.1.2    yamt /*	$OpenBSD: pfctl_qstats.c,v 1.30 2004/04/27 21:47:32 kjc Exp $ */
      3      1.1  itojun 
      4      1.1  itojun /*
      5      1.1  itojun  * Copyright (c) Henning Brauer <henning (at) openbsd.org>
      6      1.1  itojun  *
      7      1.1  itojun  * Permission to use, copy, modify, and distribute this software for any
      8      1.1  itojun  * purpose with or without fee is hereby granted, provided that the above
      9      1.1  itojun  * copyright notice and this permission notice appear in all copies.
     10      1.1  itojun  *
     11      1.1  itojun  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     12      1.1  itojun  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     13      1.1  itojun  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     14      1.1  itojun  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     15      1.1  itojun  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     16      1.1  itojun  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     17      1.1  itojun  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     18      1.1  itojun  */
     19      1.1  itojun 
     20      1.1  itojun #include <sys/types.h>
     21      1.1  itojun #include <sys/ioctl.h>
     22      1.1  itojun #include <sys/socket.h>
     23      1.1  itojun 
     24      1.1  itojun #include <net/if.h>
     25      1.1  itojun #include <netinet/in.h>
     26      1.1  itojun #include <net/pfvar.h>
     27      1.1  itojun #include <arpa/inet.h>
     28      1.1  itojun 
     29      1.1  itojun #include <err.h>
     30      1.1  itojun #include <stdio.h>
     31      1.1  itojun #include <stdlib.h>
     32      1.1  itojun #include <string.h>
     33      1.1  itojun #include <unistd.h>
     34      1.1  itojun 
     35      1.1  itojun #include <altq/altq.h>
     36      1.1  itojun #include <altq/altq_cbq.h>
     37      1.1  itojun #include <altq/altq_priq.h>
     38      1.1  itojun #include <altq/altq_hfsc.h>
     39      1.1  itojun 
     40      1.1  itojun #include "pfctl.h"
     41      1.1  itojun #include "pfctl_parser.h"
     42      1.1  itojun 
     43      1.1  itojun union class_stats {
     44      1.1  itojun 	class_stats_t		cbq_stats;
     45      1.1  itojun 	struct priq_classstats	priq_stats;
     46      1.1  itojun 	struct hfsc_classstats	hfsc_stats;
     47      1.1  itojun };
     48      1.1  itojun 
     49      1.1  itojun #define AVGN_MAX	8
     50      1.1  itojun #define STAT_INTERVAL	5
     51      1.1  itojun 
     52      1.1  itojun struct queue_stats {
     53      1.1  itojun 	union class_stats	 data;
     54      1.1  itojun 	int			 avgn;
     55      1.1  itojun 	double			 avg_bytes;
     56      1.1  itojun 	double			 avg_packets;
     57      1.1  itojun 	u_int64_t		 prev_bytes;
     58      1.1  itojun 	u_int64_t		 prev_packets;
     59      1.1  itojun };
     60      1.1  itojun 
     61      1.1  itojun struct pf_altq_node {
     62      1.1  itojun 	struct pf_altq		 altq;
     63      1.1  itojun 	struct pf_altq_node	*next;
     64      1.1  itojun 	struct pf_altq_node	*children;
     65      1.1  itojun 	struct queue_stats	 qstats;
     66      1.1  itojun };
     67      1.1  itojun 
     68      1.1  itojun int			 pfctl_update_qstats(int, struct pf_altq_node **);
     69      1.1  itojun void			 pfctl_insert_altq_node(struct pf_altq_node **,
     70      1.1  itojun 			    const struct pf_altq, const struct queue_stats);
     71      1.1  itojun struct pf_altq_node	*pfctl_find_altq_node(struct pf_altq_node *,
     72      1.1  itojun 			    const char *, const char *);
     73      1.1  itojun void			 pfctl_print_altq_node(int, const struct pf_altq_node *,
     74      1.1  itojun 			     unsigned, int);
     75      1.1  itojun void			 print_cbqstats(struct queue_stats);
     76      1.1  itojun void			 print_priqstats(struct queue_stats);
     77      1.1  itojun void			 print_hfscstats(struct queue_stats);
     78      1.1  itojun void			 pfctl_free_altq_node(struct pf_altq_node *);
     79      1.1  itojun void			 pfctl_print_altq_nodestat(int,
     80      1.1  itojun 			    const struct pf_altq_node *);
     81      1.1  itojun 
     82      1.1  itojun void			 update_avg(struct pf_altq_node *);
     83      1.1  itojun 
     84      1.1  itojun int
     85      1.1  itojun pfctl_show_altq(int dev, const char *iface, int opts, int verbose2)
     86      1.1  itojun {
     87      1.1  itojun 	struct pf_altq_node	*root = NULL, *node;
     88      1.1  itojun 	int			 nodes, dotitle = (opts & PF_OPT_SHOWALL);
     89      1.1  itojun 
     90      1.1  itojun 
     91      1.1  itojun 	if ((nodes = pfctl_update_qstats(dev, &root)) < 0)
     92      1.1  itojun 		return (-1);
     93      1.1  itojun 
     94  1.1.1.2    yamt 	if (nodes == 0)
     95  1.1.1.2    yamt 		printf("No queue in use\n");
     96      1.1  itojun 	for (node = root; node != NULL; node = node->next) {
     97      1.1  itojun 		if (iface != NULL && strcmp(node->altq.ifname, iface))
     98      1.1  itojun 			continue;
     99      1.1  itojun 		if (dotitle) {
    100      1.1  itojun 			pfctl_print_title("ALTQ:");
    101      1.1  itojun 			dotitle = 0;
    102      1.1  itojun 		}
    103      1.1  itojun 		pfctl_print_altq_node(dev, node, 0, opts);
    104      1.1  itojun 	}
    105      1.1  itojun 
    106  1.1.1.2    yamt 	while (verbose2 && nodes > 0) {
    107      1.1  itojun 		printf("\n");
    108      1.1  itojun 		fflush(stdout);
    109      1.1  itojun 		sleep(STAT_INTERVAL);
    110  1.1.1.2    yamt 		if ((nodes = pfctl_update_qstats(dev, &root)) == -1)
    111      1.1  itojun 			return (-1);
    112      1.1  itojun 		for (node = root; node != NULL; node = node->next) {
    113      1.1  itojun 			if (iface != NULL && strcmp(node->altq.ifname, iface))
    114      1.1  itojun 				continue;
    115      1.1  itojun 			pfctl_print_altq_node(dev, node, 0, opts);
    116      1.1  itojun 		}
    117      1.1  itojun 	}
    118      1.1  itojun 	pfctl_free_altq_node(root);
    119      1.1  itojun 	return (0);
    120      1.1  itojun }
    121      1.1  itojun 
    122      1.1  itojun int
    123      1.1  itojun pfctl_update_qstats(int dev, struct pf_altq_node **root)
    124      1.1  itojun {
    125      1.1  itojun 	struct pf_altq_node	*node;
    126      1.1  itojun 	struct pfioc_altq	 pa;
    127      1.1  itojun 	struct pfioc_qstats	 pq;
    128      1.1  itojun 	u_int32_t		 mnr, nr;
    129      1.1  itojun 	struct queue_stats	 qstats;
    130      1.1  itojun 	static	u_int32_t	 last_ticket;
    131      1.1  itojun 
    132      1.1  itojun 	memset(&pa, 0, sizeof(pa));
    133      1.1  itojun 	memset(&pq, 0, sizeof(pq));
    134      1.1  itojun 	memset(&qstats, 0, sizeof(qstats));
    135      1.1  itojun 	if (ioctl(dev, DIOCGETALTQS, &pa)) {
    136      1.1  itojun 		warn("DIOCGETALTQS");
    137      1.1  itojun 		return (-1);
    138      1.1  itojun 	}
    139      1.1  itojun 
    140      1.1  itojun 	/* if a new set is found, start over */
    141      1.1  itojun 	if (pa.ticket != last_ticket && *root != NULL) {
    142      1.1  itojun 		pfctl_free_altq_node(*root);
    143      1.1  itojun 		*root = NULL;
    144      1.1  itojun 	}
    145      1.1  itojun 	last_ticket = pa.ticket;
    146      1.1  itojun 
    147      1.1  itojun 	mnr = pa.nr;
    148      1.1  itojun 	for (nr = 0; nr < mnr; ++nr) {
    149      1.1  itojun 		pa.nr = nr;
    150      1.1  itojun 		if (ioctl(dev, DIOCGETALTQ, &pa)) {
    151      1.1  itojun 			warn("DIOCGETALTQ");
    152      1.1  itojun 			return (-1);
    153      1.1  itojun 		}
    154      1.1  itojun 		if (pa.altq.qid > 0) {
    155      1.1  itojun 			pq.nr = nr;
    156      1.1  itojun 			pq.ticket = pa.ticket;
    157      1.1  itojun 			pq.buf = &qstats.data;
    158      1.1  itojun 			pq.nbytes = sizeof(qstats.data);
    159      1.1  itojun 			if (ioctl(dev, DIOCGETQSTATS, &pq)) {
    160      1.1  itojun 				warn("DIOCGETQSTATS");
    161      1.1  itojun 				return (-1);
    162      1.1  itojun 			}
    163      1.1  itojun 			if ((node = pfctl_find_altq_node(*root, pa.altq.qname,
    164      1.1  itojun 			    pa.altq.ifname)) != NULL) {
    165      1.1  itojun 				memcpy(&node->qstats.data, &qstats.data,
    166      1.1  itojun 				    sizeof(qstats.data));
    167      1.1  itojun 				update_avg(node);
    168      1.1  itojun 			} else {
    169      1.1  itojun 				pfctl_insert_altq_node(root, pa.altq, qstats);
    170      1.1  itojun 			}
    171      1.1  itojun 		}
    172      1.1  itojun 	}
    173      1.1  itojun 	return (mnr);
    174      1.1  itojun }
    175      1.1  itojun 
    176      1.1  itojun void
    177      1.1  itojun pfctl_insert_altq_node(struct pf_altq_node **root,
    178      1.1  itojun     const struct pf_altq altq, const struct queue_stats qstats)
    179      1.1  itojun {
    180      1.1  itojun 	struct pf_altq_node	*node;
    181      1.1  itojun 
    182      1.1  itojun 	node = calloc(1, sizeof(struct pf_altq_node));
    183      1.1  itojun 	if (node == NULL)
    184      1.1  itojun 		err(1, "pfctl_insert_altq_node: calloc");
    185      1.1  itojun 	memcpy(&node->altq, &altq, sizeof(struct pf_altq));
    186      1.1  itojun 	memcpy(&node->qstats, &qstats, sizeof(qstats));
    187      1.1  itojun 	node->next = node->children = NULL;
    188      1.1  itojun 
    189      1.1  itojun 	if (*root == NULL)
    190      1.1  itojun 		*root = node;
    191      1.1  itojun 	else if (!altq.parent[0]) {
    192      1.1  itojun 		struct pf_altq_node	*prev = *root;
    193      1.1  itojun 
    194      1.1  itojun 		while (prev->next != NULL)
    195      1.1  itojun 			prev = prev->next;
    196      1.1  itojun 		prev->next = node;
    197      1.1  itojun 	} else {
    198      1.1  itojun 		struct pf_altq_node	*parent;
    199      1.1  itojun 
    200      1.1  itojun 		parent = pfctl_find_altq_node(*root, altq.parent, altq.ifname);
    201      1.1  itojun 		if (parent == NULL)
    202      1.1  itojun 			errx(1, "parent %s not found", altq.parent);
    203      1.1  itojun 		if (parent->children == NULL)
    204      1.1  itojun 			parent->children = node;
    205      1.1  itojun 		else {
    206      1.1  itojun 			struct pf_altq_node *prev = parent->children;
    207      1.1  itojun 
    208      1.1  itojun 			while (prev->next != NULL)
    209      1.1  itojun 				prev = prev->next;
    210      1.1  itojun 			prev->next = node;
    211      1.1  itojun 		}
    212      1.1  itojun 	}
    213      1.1  itojun 	update_avg(node);
    214      1.1  itojun }
    215      1.1  itojun 
    216      1.1  itojun struct pf_altq_node *
    217      1.1  itojun pfctl_find_altq_node(struct pf_altq_node *root, const char *qname,
    218      1.1  itojun     const char *ifname)
    219      1.1  itojun {
    220      1.1  itojun 	struct pf_altq_node	*node, *child;
    221      1.1  itojun 
    222      1.1  itojun 	for (node = root; node != NULL; node = node->next) {
    223      1.1  itojun 		if (!strcmp(node->altq.qname, qname)
    224      1.1  itojun 		    && !(strcmp(node->altq.ifname, ifname)))
    225      1.1  itojun 			return (node);
    226      1.1  itojun 		if (node->children != NULL) {
    227      1.1  itojun 			child = pfctl_find_altq_node(node->children, qname,
    228      1.1  itojun 			    ifname);
    229      1.1  itojun 			if (child != NULL)
    230      1.1  itojun 				return (child);
    231      1.1  itojun 		}
    232      1.1  itojun 	}
    233      1.1  itojun 	return (NULL);
    234      1.1  itojun }
    235      1.1  itojun 
    236      1.1  itojun void
    237      1.1  itojun pfctl_print_altq_node(int dev, const struct pf_altq_node *node, unsigned level,
    238      1.1  itojun     int opts)
    239      1.1  itojun {
    240      1.1  itojun 	const struct pf_altq_node	*child;
    241      1.1  itojun 
    242      1.1  itojun 	if (node == NULL)
    243      1.1  itojun 		return;
    244      1.1  itojun 
    245      1.1  itojun 	print_altq(&node->altq, level, NULL, NULL);
    246      1.1  itojun 
    247      1.1  itojun 	if (node->children != NULL) {
    248      1.1  itojun 		printf("{");
    249      1.1  itojun 		for (child = node->children; child != NULL;
    250      1.1  itojun 		    child = child->next) {
    251      1.1  itojun 			printf("%s", child->altq.qname);
    252      1.1  itojun 			if (child->next != NULL)
    253      1.1  itojun 				printf(", ");
    254      1.1  itojun 		}
    255      1.1  itojun 		printf("}");
    256      1.1  itojun 	}
    257      1.1  itojun 	printf("\n");
    258      1.1  itojun 
    259      1.1  itojun 	if (opts & PF_OPT_VERBOSE)
    260      1.1  itojun 		pfctl_print_altq_nodestat(dev, node);
    261      1.1  itojun 
    262      1.1  itojun 	if (opts & PF_OPT_DEBUG)
    263      1.1  itojun 		printf("  [ qid=%u ifname=%s ifbandwidth=%s ]\n",
    264      1.1  itojun 		    node->altq.qid, node->altq.ifname,
    265      1.1  itojun 		    rate2str((double)(node->altq.ifbandwidth)));
    266      1.1  itojun 
    267      1.1  itojun 	for (child = node->children; child != NULL;
    268      1.1  itojun 	    child = child->next)
    269      1.1  itojun 		pfctl_print_altq_node(dev, child, level + 1, opts);
    270      1.1  itojun }
    271      1.1  itojun 
    272      1.1  itojun void
    273      1.1  itojun pfctl_print_altq_nodestat(int dev, const struct pf_altq_node *a)
    274      1.1  itojun {
    275      1.1  itojun 	if (a->altq.qid == 0)
    276      1.1  itojun 		return;
    277      1.1  itojun 
    278      1.1  itojun 	switch (a->altq.scheduler) {
    279      1.1  itojun 	case ALTQT_CBQ:
    280      1.1  itojun 		print_cbqstats(a->qstats);
    281      1.1  itojun 		break;
    282      1.1  itojun 	case ALTQT_PRIQ:
    283      1.1  itojun 		print_priqstats(a->qstats);
    284      1.1  itojun 		break;
    285      1.1  itojun 	case ALTQT_HFSC:
    286      1.1  itojun 		print_hfscstats(a->qstats);
    287      1.1  itojun 		break;
    288      1.1  itojun 	}
    289      1.1  itojun }
    290      1.1  itojun 
    291      1.1  itojun void
    292      1.1  itojun print_cbqstats(struct queue_stats cur)
    293      1.1  itojun {
    294      1.1  itojun 	printf("  [ pkts: %10llu  bytes: %10llu  "
    295      1.1  itojun 	    "dropped pkts: %6llu bytes: %6llu ]\n",
    296      1.1  itojun 	    (unsigned long long)cur.data.cbq_stats.xmit_cnt.packets,
    297      1.1  itojun 	    (unsigned long long)cur.data.cbq_stats.xmit_cnt.bytes,
    298      1.1  itojun 	    (unsigned long long)cur.data.cbq_stats.drop_cnt.packets,
    299      1.1  itojun 	    (unsigned long long)cur.data.cbq_stats.drop_cnt.bytes);
    300      1.1  itojun 	printf("  [ qlength: %3d/%3d  borrows: %6u  suspends: %6u ]\n",
    301      1.1  itojun 	    cur.data.cbq_stats.qcnt, cur.data.cbq_stats.qmax,
    302      1.1  itojun 	    cur.data.cbq_stats.borrows, cur.data.cbq_stats.delays);
    303      1.1  itojun 
    304      1.1  itojun 	if (cur.avgn < 2)
    305      1.1  itojun 		return;
    306      1.1  itojun 
    307      1.1  itojun 	printf("  [ measured: %7.1f packets/s, %s/s ]\n",
    308      1.1  itojun 	    cur.avg_packets / STAT_INTERVAL,
    309      1.1  itojun 	    rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
    310      1.1  itojun }
    311      1.1  itojun 
    312      1.1  itojun void
    313      1.1  itojun print_priqstats(struct queue_stats cur)
    314      1.1  itojun {
    315      1.1  itojun 	printf("  [ pkts: %10llu  bytes: %10llu  "
    316      1.1  itojun 	    "dropped pkts: %6llu bytes: %6llu ]\n",
    317      1.1  itojun 	    (unsigned long long)cur.data.priq_stats.xmitcnt.packets,
    318      1.1  itojun 	    (unsigned long long)cur.data.priq_stats.xmitcnt.bytes,
    319      1.1  itojun 	    (unsigned long long)cur.data.priq_stats.dropcnt.packets,
    320      1.1  itojun 	    (unsigned long long)cur.data.priq_stats.dropcnt.bytes);
    321      1.1  itojun 	printf("  [ qlength: %3d/%3d ]\n",
    322      1.1  itojun 	    cur.data.priq_stats.qlength, cur.data.priq_stats.qlimit);
    323      1.1  itojun 
    324      1.1  itojun 	if (cur.avgn < 2)
    325      1.1  itojun 		return;
    326      1.1  itojun 
    327      1.1  itojun 	printf("  [ measured: %7.1f packets/s, %s/s ]\n",
    328      1.1  itojun 	    cur.avg_packets / STAT_INTERVAL,
    329      1.1  itojun 	    rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
    330      1.1  itojun }
    331      1.1  itojun 
    332      1.1  itojun void
    333      1.1  itojun print_hfscstats(struct queue_stats cur)
    334      1.1  itojun {
    335      1.1  itojun 	printf("  [ pkts: %10llu  bytes: %10llu  "
    336      1.1  itojun 	    "dropped pkts: %6llu bytes: %6llu ]\n",
    337      1.1  itojun 	    (unsigned long long)cur.data.hfsc_stats.xmit_cnt.packets,
    338      1.1  itojun 	    (unsigned long long)cur.data.hfsc_stats.xmit_cnt.bytes,
    339      1.1  itojun 	    (unsigned long long)cur.data.hfsc_stats.drop_cnt.packets,
    340      1.1  itojun 	    (unsigned long long)cur.data.hfsc_stats.drop_cnt.bytes);
    341      1.1  itojun 	printf("  [ qlength: %3d/%3d ]\n",
    342      1.1  itojun 	    cur.data.hfsc_stats.qlength, cur.data.hfsc_stats.qlimit);
    343      1.1  itojun 
    344      1.1  itojun 	if (cur.avgn < 2)
    345      1.1  itojun 		return;
    346      1.1  itojun 
    347      1.1  itojun 	printf("  [ measured: %7.1f packets/s, %s/s ]\n",
    348      1.1  itojun 	    cur.avg_packets / STAT_INTERVAL,
    349      1.1  itojun 	    rate2str((8 * cur.avg_bytes) / STAT_INTERVAL));
    350      1.1  itojun }
    351      1.1  itojun 
    352      1.1  itojun void
    353      1.1  itojun pfctl_free_altq_node(struct pf_altq_node *node)
    354      1.1  itojun {
    355      1.1  itojun 	while (node != NULL) {
    356      1.1  itojun 		struct pf_altq_node	*prev;
    357      1.1  itojun 
    358      1.1  itojun 		if (node->children != NULL)
    359      1.1  itojun 			pfctl_free_altq_node(node->children);
    360      1.1  itojun 		prev = node;
    361      1.1  itojun 		node = node->next;
    362      1.1  itojun 		free(prev);
    363      1.1  itojun 	}
    364      1.1  itojun }
    365      1.1  itojun 
    366      1.1  itojun void
    367      1.1  itojun update_avg(struct pf_altq_node *a)
    368      1.1  itojun {
    369      1.1  itojun 	struct queue_stats	*qs;
    370      1.1  itojun 	u_int64_t		 b, p;
    371      1.1  itojun 	int			 n;
    372      1.1  itojun 
    373      1.1  itojun 	if (a->altq.qid == 0)
    374      1.1  itojun 		return;
    375      1.1  itojun 
    376      1.1  itojun 	qs = &a->qstats;
    377      1.1  itojun 	n = qs->avgn;
    378      1.1  itojun 
    379      1.1  itojun 	switch (a->altq.scheduler) {
    380      1.1  itojun 	case ALTQT_CBQ:
    381      1.1  itojun 		b = qs->data.cbq_stats.xmit_cnt.bytes;
    382      1.1  itojun 		p = qs->data.cbq_stats.xmit_cnt.packets;
    383      1.1  itojun 		break;
    384      1.1  itojun 	case ALTQT_PRIQ:
    385      1.1  itojun 		b = qs->data.priq_stats.xmitcnt.bytes;
    386      1.1  itojun 		p = qs->data.priq_stats.xmitcnt.packets;
    387      1.1  itojun 		break;
    388      1.1  itojun 	case ALTQT_HFSC:
    389      1.1  itojun 		b = qs->data.hfsc_stats.xmit_cnt.bytes;
    390      1.1  itojun 		p = qs->data.hfsc_stats.xmit_cnt.packets;
    391      1.1  itojun 		break;
    392      1.1  itojun 	default:
    393      1.1  itojun 		b = 0;
    394      1.1  itojun 		p = 0;
    395      1.1  itojun 		break;
    396      1.1  itojun 	}
    397      1.1  itojun 
    398      1.1  itojun 	if (n == 0) {
    399      1.1  itojun 		qs->prev_bytes = b;
    400      1.1  itojun 		qs->prev_packets = p;
    401      1.1  itojun 		qs->avgn++;
    402      1.1  itojun 		return;
    403      1.1  itojun 	}
    404      1.1  itojun 
    405      1.1  itojun 	if (b >= qs->prev_bytes)
    406      1.1  itojun 		qs->avg_bytes = ((qs->avg_bytes * (n - 1)) +
    407      1.1  itojun 		    (b - qs->prev_bytes)) / n;
    408      1.1  itojun 
    409      1.1  itojun 	if (p >= qs->prev_packets)
    410      1.1  itojun 		qs->avg_packets = ((qs->avg_packets * (n - 1)) +
    411      1.1  itojun 		    (p - qs->prev_packets)) / n;
    412      1.1  itojun 
    413      1.1  itojun 	qs->prev_bytes = b;
    414      1.1  itojun 	qs->prev_packets = p;
    415      1.1  itojun 	if (n < AVGN_MAX)
    416      1.1  itojun 		qs->avgn++;
    417      1.1  itojun }
    418