Module Name:    src
Committed By:   ozaki-r
Date:           Wed Feb  1 08:13:45 UTC 2017

Modified Files:
        src/sys/net: bpf.c bpfdesc.h

Log Message:
Use pslist(9) instead of queue(9) for psz/psref

As usual some member variables of struct bpf_d and bpf_if remain to avoid
breaking kvm(3) users (netstat and fstat).


To generate a diff of this commit:
cvs rdiff -u -r1.208 -r1.209 src/sys/net/bpf.c
cvs rdiff -u -r1.41 -r1.42 src/sys/net/bpfdesc.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/bpf.c
diff -u src/sys/net/bpf.c:1.208 src/sys/net/bpf.c:1.209
--- src/sys/net/bpf.c:1.208	Wed Feb  1 08:07:27 2017
+++ src/sys/net/bpf.c	Wed Feb  1 08:13:45 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: bpf.c,v 1.208 2017/02/01 08:07:27 ozaki-r Exp $	*/
+/*	$NetBSD: bpf.c,v 1.209 2017/02/01 08:13:45 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.208 2017/02/01 08:07:27 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.209 2017/02/01 08:13:45 ozaki-r Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_bpf.h"
@@ -132,8 +132,60 @@ static kmutex_t bpf_mtx;
  *  bpf_iflist is the list of interfaces; each corresponds to an ifnet
  *  bpf_dtab holds the descriptors, indexed by minor device #
  */
-static struct bpf_if	*bpf_iflist;
-static LIST_HEAD(, bpf_d) bpf_list;
+static struct pslist_head bpf_iflist;
+static struct pslist_head bpf_dlist;
+
+/* Macros for bpf_d on bpf_dlist */
+#define BPF_DLIST_WRITER_INSEART_HEAD(__d)				\
+	PSLIST_WRITER_INSERT_HEAD(&bpf_dlist, (__d), bd_bpf_dlist_entry)
+#define BPF_DLIST_READER_FOREACH(__d)					\
+	PSLIST_READER_FOREACH((__d), &bpf_dlist, struct bpf_d,		\
+	                      bd_bpf_dlist_entry)
+#define BPF_DLIST_WRITER_FOREACH(__d)					\
+	PSLIST_WRITER_FOREACH((__d), &bpf_dlist, struct bpf_d,		\
+	                      bd_bpf_dlist_entry)
+#define BPF_DLIST_ENTRY_INIT(__d)					\
+	PSLIST_ENTRY_INIT((__d), bd_bpf_dlist_entry)
+#define BPF_DLIST_WRITER_REMOVE(__d)					\
+	PSLIST_WRITER_REMOVE((__d), bd_bpf_dlist_entry)
+#define BPF_DLIST_ENTRY_DESTROY(__d)					\
+	PSLIST_ENTRY_DESTROY((__d), bd_bpf_dlist_entry)
+
+/* Macros for bpf_if on bpf_iflist */
+#define BPF_IFLIST_WRITER_INSERT_HEAD(__bp)				\
+	PSLIST_WRITER_INSERT_HEAD(&bpf_iflist, (__bp), bif_iflist_entry)
+#define BPF_IFLIST_READER_FOREACH(__bp)					\
+	PSLIST_READER_FOREACH((__bp), &bpf_iflist, struct bpf_if,	\
+	                      bif_iflist_entry)
+#define BPF_IFLIST_WRITER_FOREACH(__bp)					\
+	PSLIST_WRITER_FOREACH((__bp), &bpf_iflist, struct bpf_if,	\
+	                      bif_iflist_entry)
+#define BPF_IFLIST_WRITER_REMOVE(__bp)					\
+	PSLIST_WRITER_REMOVE((__bp), bif_iflist_entry)
+#define BPF_IFLIST_ENTRY_INIT(__bp)					\
+	PSLIST_ENTRY_INIT((__bp), bif_iflist_entry)
+#define BPF_IFLIST_ENTRY_DESTROY(__bp)					\
+	PSLIST_ENTRY_DESTROY((__bp), bif_iflist_entry)
+
+/* Macros for bpf_d on bpf_if#bif_dlist_pslist */
+#define BPFIF_DLIST_READER_FOREACH(__d, __bp)				\
+	PSLIST_READER_FOREACH((__d), &(__bp)->bif_dlist_head, struct bpf_d, \
+	                      bd_bif_dlist_entry)
+#define BPFIF_DLIST_WRITER_INSERT_HEAD(__bp, __d)			\
+	PSLIST_WRITER_INSERT_HEAD(&(__bp)->bif_dlist_head, (__d),	\
+	                          bd_bif_dlist_entry)
+#define BPFIF_DLIST_WRITER_REMOVE(__d)					\
+	PSLIST_WRITER_REMOVE((__d), bd_bif_dlist_entry)
+#define BPFIF_DLIST_ENTRY_INIT(__d)					\
+	PSLIST_ENTRY_INIT((__d), bd_bif_dlist_entry)
+#define	BPFIF_DLIST_READER_EMPTY(__bp)					\
+	(PSLIST_READER_FIRST(&(__bp)->bif_dlist_head, struct bpf_d,	\
+	                     bd_bif_dlist_entry) == NULL)
+#define	BPFIF_DLIST_WRITER_EMPTY(__bp)					\
+	(PSLIST_WRITER_FIRST(&(__bp)->bif_dlist_head, struct bpf_d,	\
+	                     bd_bif_dlist_entry) == NULL)
+#define BPFIF_DLIST_ENTRY_DESTROY(__d)					\
+	PSLIST_ENTRY_DESTROY((__d), bd_bif_dlist_entry)
 
 static int	bpf_allocbufs(struct bpf_d *);
 static void	bpf_deliver(struct bpf_if *,
@@ -350,8 +402,7 @@ bpf_attachd(struct bpf_d *d, struct bpf_
 	 * it will divert packets to bpf.
 	 */
 	d->bd_bif = bp;
-	d->bd_next = bp->bif_dlist;
-	bp->bif_dlist = d;
+	BPFIF_DLIST_WRITER_INSERT_HEAD(bp, d);
 
 	*bp->bif_driverp = bp;
 }
@@ -362,7 +413,6 @@ bpf_attachd(struct bpf_d *d, struct bpf_
 static void
 bpf_detachd(struct bpf_d *d)
 {
-	struct bpf_d **p;
 	struct bpf_if *bp;
 
 	KASSERT(mutex_owned(&bpf_mtx));
@@ -389,19 +439,21 @@ bpf_detachd(struct bpf_d *d)
 			printf("%s: ifpromisc failed: %d", __func__, error);
 #endif
 	}
+
 	/* Remove d from the interface's descriptor list. */
-	p = &bp->bif_dlist;
-	while (*p != d) {
-		p = &(*p)->bd_next;
-		if (*p == NULL)
-			panic("%s: descriptor not in list", __func__);
-	}
-	*p = (*p)->bd_next;
-	if (bp->bif_dlist == NULL)
+	BPFIF_DLIST_WRITER_REMOVE(d);
+
+	/* TODO pserialize_perform(); */
+	/* TODO psref_target_destroy(); */
+	BPFIF_DLIST_ENTRY_DESTROY(d);
+
+	/* XXX NOMPSAFE? */
+	if (BPFIF_DLIST_WRITER_EMPTY(bp)) {
 		/*
 		 * Let the driver know that there are no more listeners.
 		 */
 		*d->bd_bif->bif_driverp = NULL;
+	}
 	d->bd_bif = NULL;
 }
 
@@ -411,7 +463,8 @@ bpf_init(void)
 
 	mutex_init(&bpf_mtx, MUTEX_DEFAULT, IPL_NONE);
 
-	LIST_INIT(&bpf_list);
+	PSLIST_INIT(&bpf_iflist);
+	PSLIST_INIT(&bpf_dlist);
 
 	bpf_gstats.bs_recv = 0;
 	bpf_gstats.bs_drop = 0;
@@ -461,9 +514,11 @@ bpfopen(dev_t dev, int flag, int mode, s
 	selinit(&d->bd_sel);
 	d->bd_sih = softint_establish(SOFTINT_CLOCK, bpf_softintr, d);
 	d->bd_jitcode = NULL;
+	BPF_DLIST_ENTRY_INIT(d);
+	BPFIF_DLIST_ENTRY_INIT(d);
 
 	mutex_enter(&bpf_mtx);
-	LIST_INSERT_HEAD(&bpf_list, d, bd_list);
+	BPF_DLIST_WRITER_INSEART_HEAD(d);
 	mutex_exit(&bpf_mtx);
 
 	return fd_clone(fp, fd, flag, &bpf_fileops, d);
@@ -502,12 +557,16 @@ bpf_close(struct file *fp)
 		bpf_detachd(d);
 	splx(s);
 	bpf_freed(d);
-	LIST_REMOVE(d, bd_list);
+	BPF_DLIST_WRITER_REMOVE(d);
 	fp->f_bpf = NULL;
 
 	mutex_exit(&bpf_mtx);
 	KERNEL_UNLOCK_ONE(NULL);
 
+	/* TODO pserialize_perform(); */
+	/* TODO psref_target_destroy(); */
+	BPF_DLIST_ENTRY_DESTROY(d);
+
 	callout_destroy(&d->bd_callout);
 	seldestroy(&d->bd_sel);
 	softint_disestablish(d->bd_sih);
@@ -1203,7 +1262,7 @@ bpf_setif(struct bpf_d *d, struct ifreq 
 	/*
 	 * Look through attached interfaces for the named one.
 	 */
-	for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
+	BPF_IFLIST_WRITER_FOREACH(bp) {
 		struct ifnet *ifp = bp->bif_ifp;
 
 		if (ifp == NULL ||
@@ -1423,13 +1482,14 @@ bpf_deliver(struct bpf_if *bp, void *(*c
 	};
 	bool gottime = false;
 	struct timespec ts;
+	struct bpf_d *d;
 
 	/*
 	 * Note that the IPL does not have to be raised at this point.
 	 * The only problem that could arise here is that if two different
 	 * interfaces shared any data.  This is not the case.
 	 */
-	for (struct bpf_d *d = bp->bif_dlist; d != NULL; d = d->bd_next) {
+	BPFIF_DLIST_READER_FOREACH(d, bp) {
 		u_int slen;
 
 		if (!d->bd_seesent && !rcv) {
@@ -1682,7 +1742,7 @@ _bpf_mtap_softint(struct ifnet *ifp, str
 	KASSERT(cpu_intr_p());
 
 	/* To avoid extra invocations of the softint */
-	if (bp->bif_dlist == NULL)
+	if (BPFIF_DLIST_READER_EMPTY(bp))
 		return;
 	KASSERT(bp->bif_si != NULL);
 
@@ -1883,14 +1943,14 @@ _bpfattach(struct ifnet *ifp, u_int dlt,
 		panic("bpfattach");
 
 	mutex_enter(&bpf_mtx);
-	bp->bif_dlist = NULL;
 	bp->bif_driverp = driverp;
 	bp->bif_ifp = ifp;
 	bp->bif_dlt = dlt;
 	bp->bif_si = NULL;
+	BPF_IFLIST_ENTRY_INIT(bp);
+	PSLIST_INIT(&bp->bif_dlist_head);
 
-	bp->bif_next = bpf_iflist;
-	bpf_iflist = bp;
+	BPF_IFLIST_WRITER_INSERT_HEAD(bp);
 
 	*bp->bif_driverp = NULL;
 
@@ -1907,7 +1967,7 @@ _bpf_mtap_softint_init(struct ifnet *ifp
 	struct bpf_if *bp;
 
 	mutex_enter(&bpf_mtx);
-	for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
+	BPF_IFLIST_WRITER_FOREACH(bp) {
 		if (bp->bif_ifp != ifp)
 			continue;
 
@@ -1930,13 +1990,14 @@ _bpf_mtap_softint_init(struct ifnet *ifp
 static void
 _bpfdetach(struct ifnet *ifp)
 {
-	struct bpf_if *bp, **pbp;
+	struct bpf_if *bp;
 	struct bpf_d *d;
 	int s;
 
 	mutex_enter(&bpf_mtx);
 	/* Nuke the vnodes for any open instances */
-	LIST_FOREACH(d, &bpf_list, bd_list) {
+  again_d:
+	BPF_DLIST_WRITER_FOREACH(d) {
 		if (d->bd_bif != NULL && d->bd_bif->bif_ifp == ifp) {
 			/*
 			 * Detach the descriptor from an interface now.
@@ -1946,14 +2007,17 @@ _bpfdetach(struct ifnet *ifp)
 			d->bd_promisc = 0;	/* we can't touch device. */
 			bpf_detachd(d);
 			splx(s);
+			goto again_d;
 		}
 	}
 
   again:
-	for (bp = bpf_iflist, pbp = &bpf_iflist;
-	     bp != NULL; pbp = &bp->bif_next, bp = bp->bif_next) {
+	BPF_IFLIST_WRITER_FOREACH(bp) {
 		if (bp->bif_ifp == ifp) {
-			*pbp = bp->bif_next;
+			BPF_IFLIST_WRITER_REMOVE(bp);
+			/* TODO pserialize_perform(); */
+			/* TODO psref_target_destroy(); */
+			BPF_IFLIST_ENTRY_DESTROY(bp);
 			if (bp->bif_si != NULL) {
 				s = splnet();
 				while (bp->bif_mbuf_head != NULL) {
@@ -1979,7 +2043,7 @@ _bpf_change_type(struct ifnet *ifp, u_in
 {
 	struct bpf_if *bp;
 
-	for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
+	BPF_IFLIST_READER_FOREACH(bp) {
 		if (bp->bif_driverp == &ifp->if_bpf)
 			break;
 	}
@@ -2004,7 +2068,7 @@ bpf_getdltlist(struct bpf_d *d, struct b
 	ifp = d->bd_bif->bif_ifp;
 	n = 0;
 	error = 0;
-	for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
+	BPF_IFLIST_READER_FOREACH(bp) {
 		if (bp->bif_ifp != ifp)
 			continue;
 		if (bfl->bfl_list != NULL) {
@@ -2034,7 +2098,7 @@ bpf_setdlt(struct bpf_d *d, u_int dlt)
 	if (d->bd_bif->bif_dlt == dlt)
 		return 0;
 	ifp = d->bd_bif->bif_ifp;
-	for (bp = bpf_iflist; bp != NULL; bp = bp->bif_next) {
+	BPF_IFLIST_WRITER_FOREACH(bp) {
 		if (bp->bif_ifp == ifp && bp->bif_dlt == dlt)
 			break;
 	}
@@ -2142,7 +2206,7 @@ sysctl_net_bpf_peers(SYSCTLFN_ARGS)
 		return (EINVAL);
 
 	mutex_enter(&bpf_mtx);
-	LIST_FOREACH(dp, &bpf_list, bd_list) {
+	BPF_DLIST_WRITER_FOREACH(dp) {
 		if (len >= elem_size && elem_count > 0) {
 #define BPF_EXT(field)	dpe.bde_ ## field = dp->bd_ ## field
 			BPF_EXT(bufsize);

Index: src/sys/net/bpfdesc.h
diff -u src/sys/net/bpfdesc.h:1.41 src/sys/net/bpfdesc.h:1.42
--- src/sys/net/bpfdesc.h:1.41	Wed Feb  1 08:07:27 2017
+++ src/sys/net/bpfdesc.h	Wed Feb  1 08:13:45 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: bpfdesc.h,v 1.41 2017/02/01 08:07:27 ozaki-r Exp $	*/
+/*	$NetBSD: bpfdesc.h,v 1.42 2017/02/01 08:13:45 ozaki-r Exp $	*/
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -45,12 +45,16 @@
 #include <sys/selinfo.h>		/* for struct selinfo */
 #include <net/if.h>			/* for IFNAMSIZ */
 #include <net/bpfjit.h>			/* for bpfjit_function_t */
+#ifdef _KERNEL
+#include <sys/pslist.h>
+#endif
 
 /*
  * Descriptor associated with each open bpf file.
  */
 struct bpf_d {
-	struct bpf_d	*bd_next;	/* Linked list of descriptors */
+	/* DEPRECATED. Keep it to avoid breaking kvm(3) users */
+	struct bpf_d	*_bd_next;	/* Linked list of descriptors */
 	/*
 	 * Buffer slots: two mbuf clusters buffer the incoming packets.
 	 *   The model has three slots.  Sbuf is always occupied.
@@ -93,7 +97,8 @@ struct bpf_d {
 #endif
 	callout_t	bd_callout;	/* for BPF timeouts with select */
 	pid_t		bd_pid;		/* corresponding PID */
-	LIST_ENTRY(bpf_d) bd_list;	/* list of all BPF's */
+	/* DEPRECATED. Keep it to avoid breaking kvm(3) users */
+	LIST_ENTRY(bpf_d) _bd_list;	/* list of all BPF's */
 	void		*bd_sih;	/* soft interrupt handle */
 	struct timespec bd_atime;	/* access time */
 	struct timespec bd_mtime;	/* modification time */
@@ -103,6 +108,10 @@ struct bpf_d {
 #endif
 	bpfjit_func_t	bd_jitcode;	/* compiled filter program */
 	size_t		bd_filter_size;
+#ifdef _KERNEL
+	struct pslist_entry	bd_bif_dlist_entry; /* For bpf_if */
+	struct pslist_entry	bd_bpf_dlist_entry; /* For the global list */
+#endif
 };
 
 
@@ -134,8 +143,9 @@ struct bpf_d_ext {
  * Descriptor associated with each attached hardware interface.
  */
 struct bpf_if {
-	struct bpf_if *bif_next;	/* list of all interfaces */
-	struct bpf_d *bif_dlist;	/* descriptor list */
+	/* DEPRECATED. Keep it to avoid breaking kvm(3) users */
+	struct bpf_if *_bif_next;	/* list of all interfaces */
+	struct bpf_d *_bif_dlist;	/* descriptor list */
 	struct bpf_if **bif_driverp;	/* pointer into softc */
 	u_int bif_dlt;			/* link layer type */
 	u_int bif_hdrlen;		/* length of header (with padding) */
@@ -143,6 +153,10 @@ struct bpf_if {
 	void *bif_si;
 	struct mbuf *bif_mbuf_head;
 	struct mbuf *bif_mbuf_tail;
+#ifdef _KERNEL
+	struct pslist_entry bif_iflist_entry;
+	struct pslist_head bif_dlist_head;
+#endif
 };
 
 #endif /* !_NET_BPFDESC_H_ */

Reply via email to