Module Name:    src
Committed By:   thorpej
Date:           Fri Sep  2 05:50:36 UTC 2022

Modified Files:
        src/sys/net: if.c pktqueue.c pktqueue.h

Log Message:
Re-factor how pktq_barrier() is issued by if_detach().

Rather than excplicitly referencing ip_pktq and ip6_pktq in if_detach(),
instead add all pktqueues to a global list.  This list is then used in
the new pktq_ifdetach() function to issue a barrier on all pktqueues.

Note that the performance of this list is not critical; it will seldom
be accessed (then pktqueues are created/destroyed and when network
interfaces are detached), and so a simple synchronization strategy using
a rwlock is sufficient.


To generate a diff of this commit:
cvs rdiff -u -r1.522 -r1.523 src/sys/net/if.c
cvs rdiff -u -r1.19 -r1.20 src/sys/net/pktqueue.c
cvs rdiff -u -r1.7 -r1.8 src/sys/net/pktqueue.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/if.c
diff -u src/sys/net/if.c:1.522 src/sys/net/if.c:1.523
--- src/sys/net/if.c:1.522	Fri Sep  2 04:34:58 2022
+++ src/sys/net/if.c	Fri Sep  2 05:50:36 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: if.c,v 1.522 2022/09/02 04:34:58 thorpej Exp $	*/
+/*	$NetBSD: if.c,v 1.523 2022/09/02 05:50:36 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@@ -90,7 +90,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.522 2022/09/02 04:34:58 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.523 2022/09/02 05:50:36 thorpej Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_inet.h"
@@ -1412,17 +1412,13 @@ if_detach(struct ifnet *ifp)
 	}
 
 	/*
-	 * IP queues have to be processed separately: net-queue barrier
-	 * ensures that the packets are dequeued while a cross-call will
-	 * ensure that the interrupts have completed. FIXME: not quite..
+	 * Ensure that all packets on protocol input pktqueues have been
+	 * processed, or, at least, removed from the queues.
+	 *
+	 * A cross-call will ensure that the interrupts have completed.
+	 * FIXME: not quite..
 	 */
-#ifdef INET
-	pktq_barrier(ip_pktq);
-#endif
-#ifdef INET6
-	if (in6_present)
-		pktq_barrier(ip6_pktq);
-#endif
+	pktq_ifdetach();
 	xc_barrier(0);
 
 	/*

Index: src/sys/net/pktqueue.c
diff -u src/sys/net/pktqueue.c:1.19 src/sys/net/pktqueue.c:1.20
--- src/sys/net/pktqueue.c:1.19	Fri Sep  2 03:50:00 2022
+++ src/sys/net/pktqueue.c	Fri Sep  2 05:50:36 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: pktqueue.c,v 1.19 2022/09/02 03:50:00 thorpej Exp $	*/
+/*	$NetBSD: pktqueue.c,v 1.20 2022/09/02 05:50:36 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pktqueue.c,v 1.19 2022/09/02 03:50:00 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pktqueue.c,v 1.20 2022/09/02 05:50:36 thorpej Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_net_mpsafe.h"
@@ -53,6 +53,9 @@ __KERNEL_RCSID(0, "$NetBSD: pktqueue.c,v
 #include <sys/proc.h>
 #include <sys/percpu.h>
 #include <sys/xcall.h>
+#include <sys/once.h>
+#include <sys/queue.h>
+#include <sys/rwlock.h>
 
 #include <net/pktqueue.h>
 #include <net/rss_config.h>
@@ -80,8 +83,11 @@ struct pktqueue {
 	percpu_t *	pq_counters;
 	void *		pq_sih;
 
-	/* Finally, per-CPU queues. */
+	/* The per-CPU queues. */
 	struct percpu *	pq_pcq;	/* struct pcq * */
+
+	/* The linkage on the list of all pktqueues. */
+	LIST_ENTRY(pktqueue) pq_list;
 };
 
 /* The counters of the packet queue. */
@@ -97,6 +103,28 @@ typedef struct {
 /* Special marker value used by pktq_barrier() mechanism. */
 #define	PKTQ_MARKER	((void *)(~0ULL))
 
+/*
+ * This is a list of all pktqueues.  This list is used by
+ * pktq_ifdetach() to issue a barrier on every pktqueue.
+ *
+ * The r/w lock is acquired for writing in pktq_create() and
+ * pktq_destroy(), and for reading in pktq_ifdetach().
+ *
+ * This list is not performance critical, and will seldom be
+ * accessed.
+ */
+static LIST_HEAD(, pktqueue) pktqueue_list	__read_mostly;
+static krwlock_t pktqueue_list_lock		__read_mostly;
+static once_t pktqueue_list_init_once		__read_mostly;
+
+static int
+pktqueue_list_init(void)
+{
+	LIST_INIT(&pktqueue_list);
+	rw_init(&pktqueue_list_lock);
+	return 0;
+}
+
 static void
 pktq_init_cpu(void *vqp, void *vpq, struct cpu_info *ci)
 {
@@ -141,6 +169,8 @@ pktq_create(size_t maxlen, void (*intrh)
 	percpu_t *pc;
 	void *sih;
 
+	RUN_ONCE(&pktqueue_list_init_once, pktqueue_list_init);
+
 	pc = percpu_alloc(sizeof(pktq_counters_t));
 	if ((sih = softint_establish(sflags, intrh, sc)) == NULL) {
 		percpu_free(pc, sizeof(pktq_counters_t));
@@ -155,6 +185,10 @@ pktq_create(size_t maxlen, void (*intrh)
 	pq->pq_pcq = percpu_create(sizeof(struct pcq *),
 	    pktq_init_cpu, pktq_fini_cpu, pq);
 
+	rw_enter(&pktqueue_list_lock, RW_WRITER);
+	LIST_INSERT_HEAD(&pktqueue_list, pq, pq_list);
+	rw_exit(&pktqueue_list_lock);
+
 	return pq;
 }
 
@@ -162,6 +196,12 @@ void
 pktq_destroy(pktqueue_t *pq)
 {
 
+	KASSERT(pktqueue_list_init_once.o_status == ONCE_DONE);
+
+	rw_enter(&pktqueue_list_lock, RW_WRITER);
+	LIST_REMOVE(pq, pq_list);
+	rw_exit(&pktqueue_list_lock);
+
 	percpu_free(pq->pq_pcq, sizeof(struct pcq *));
 	percpu_free(pq->pq_counters, sizeof(pktq_counters_t));
 	softint_disestablish(pq->pq_sih);
@@ -472,6 +512,25 @@ pktq_barrier(pktqueue_t *pq)
 }
 
 /*
+ * pktq_ifdetach: issue a barrier on all pktqueues when a network
+ * interface is detached.
+ */
+void
+pktq_ifdetach(void)
+{
+	pktqueue_t *pq;
+
+	/* Just in case no pktqueues have been created yet... */
+	RUN_ONCE(&pktqueue_list_init_once, pktqueue_list_init);
+
+	rw_enter(&pktqueue_list_lock, RW_READER);
+	LIST_FOREACH(pq, &pktqueue_list, pq_list) {
+		pktq_barrier(pq);
+	}
+	rw_exit(&pktqueue_list_lock);
+}
+
+/*
  * pktq_flush: free mbufs in all queues.
  *
  * => The caller must ensure there are no concurrent writers or flush calls.

Index: src/sys/net/pktqueue.h
diff -u src/sys/net/pktqueue.h:1.7 src/sys/net/pktqueue.h:1.8
--- src/sys/net/pktqueue.h:1.7	Fri Sep  2 03:50:00 2022
+++ src/sys/net/pktqueue.h	Fri Sep  2 05:50:36 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: pktqueue.h,v 1.7 2022/09/02 03:50:00 thorpej Exp $	*/
+/*	$NetBSD: pktqueue.h,v 1.8 2022/09/02 05:50:36 thorpej Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -53,6 +53,7 @@ void		pktq_destroy(pktqueue_t *);
 bool		pktq_enqueue(pktqueue_t *, struct mbuf *, const u_int);
 struct mbuf *	pktq_dequeue(pktqueue_t *);
 void		pktq_barrier(pktqueue_t *);
+void		pktq_ifdetach(void);
 void		pktq_flush(pktqueue_t *);
 int		pktq_set_maxlen(pktqueue_t *, size_t);
 

Reply via email to