Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net Do pppoe_timeout() in thread context
details: https://anonhg.NetBSD.org/src/rev/a8b25c077068
branches: trunk
changeset: 955088:a8b25c077068
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Fri Sep 18 09:53:50 2020 +0000
description:
Do pppoe_timeout() in thread context
OKed by knakahara@n.o
fix port-amd64/55661
diffstat:
sys/net/if_pppoe.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 53 insertions(+), 7 deletions(-)
diffs (140 lines):
diff -r 721f33e95459 -r a8b25c077068 sys/net/if_pppoe.c
--- a/sys/net/if_pppoe.c Fri Sep 18 09:48:56 2020 +0000
+++ b/sys/net/if_pppoe.c Fri Sep 18 09:53:50 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_pppoe.c,v 1.150 2020/09/18 09:48:56 yamaguchi Exp $ */
+/* $NetBSD: if_pppoe.c,v 1.151 2020/09/18 09:53:50 yamaguchi Exp $ */
/*
* Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.150 2020/09/18 09:48:56 yamaguchi Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.151 2020/09/18 09:53:50 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "pppoe.h"
@@ -41,6 +41,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/atomic.h>
#include <sys/callout.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
@@ -57,6 +58,7 @@
#include <sys/mutex.h>
#include <sys/psref.h>
#include <sys/cprng.h>
+#include <sys/workqueue.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -173,7 +175,10 @@
uint8_t *sc_hunique; /* content of host unique we must echo back */
size_t sc_hunique_len; /* length of host unique */
#endif
- callout_t sc_timeout; /* timeout while not in session state */
+ callout_t sc_timeout; /* timeout while not in session state */
+ struct workqueue *sc_timeout_wq; /* workqueue for timeout */
+ struct work sc_timeout_wk;
+ u_int sc_timeout_scheduled;
int sc_padi_retried; /* number of PADI retries already done */
int sc_padr_retried; /* number of PADR retries already done */
krwlock_t sc_lock; /* lock of sc_state, sc_session, and sc_eth_if */
@@ -209,7 +214,10 @@
static void pppoe_clear_softc(struct pppoe_softc *, const char *);
/* internal timeout handling */
-static void pppoe_timeout(void *);
+static void pppoe_timeout_co(void *);
+static void pppoe_timeout_co_halt(void *);
+static void pppoe_timeout_wk(struct work *, void *);
+static void pppoe_timeout(struct pppoe_softc *);
/* sending actual protocol controll packets */
static int pppoe_send_padi(struct pppoe_softc *);
@@ -349,8 +357,16 @@
/* changed to real address later */
memcpy(&sc->sc_dest, etherbroadcastaddr, sizeof(sc->sc_dest));
+ rv = workqueue_create(&sc->sc_timeout_wq,
+ sc->sc_sppp.pp_if.if_xname, pppoe_timeout_wk, sc,
+ PRI_SOFTNET, IPL_SOFTNET, 0);
+ if (rv != 0) {
+ free(sc, M_DEVBUF);
+ return rv;
+ }
+
callout_init(&sc->sc_timeout, CALLOUT_MPSAFE);
- callout_setfunc(&sc->sc_timeout, pppoe_timeout, sc);
+ callout_setfunc(&sc->sc_timeout, pppoe_timeout_co, sc);
sc->sc_sppp.pp_if.if_start = pppoe_start;
#ifdef PPPOE_MPSAFE
@@ -362,6 +378,7 @@
rv = if_initialize(&sc->sc_sppp.pp_if);
if (rv != 0) {
+ workqueue_destroy(sc->sc_timeout_wq);
callout_halt(&sc->sc_timeout, NULL);
callout_destroy(&sc->sc_timeout);
free(sc, M_DEVBUF);
@@ -395,6 +412,8 @@
rw_enter(&pppoe_softc_list_lock, RW_WRITER);
PPPOE_LOCK(sc, RW_WRITER);
+ callout_setfunc(&sc->sc_timeout, pppoe_timeout_co_halt, sc);
+ workqueue_wait(sc->sc_timeout_wq, &sc->sc_timeout_wk);
callout_halt(&sc->sc_timeout, NULL);
LIST_REMOVE(sc, sc_list);
@@ -416,6 +435,7 @@
if (sc->sc_relay_sid)
free(sc->sc_relay_sid, M_DEVBUF);
callout_destroy(&sc->sc_timeout);
+ workqueue_destroy(sc->sc_timeout_wq);
PPPOE_UNLOCK(sc);
rw_destroy(&sc->sc_lock);
@@ -1411,10 +1431,36 @@
}
static void
-pppoe_timeout(void *arg)
+pppoe_timeout_co(void *arg)
+{
+ struct pppoe_softc *sc = (struct pppoe_softc *)arg;
+
+ if (atomic_swap_uint(&sc->sc_timeout_scheduled, 1) != 0)
+ return;
+
+ workqueue_enqueue(sc->sc_timeout_wq, &sc->sc_timeout_wk, NULL);
+}
+
+static void
+pppoe_timeout_co_halt(void *unused __unused)
+{
+
+ /* do nothing to halt callout safely */
+}
+
+static void
+pppoe_timeout_wk(struct work *wk __unused, void *arg)
+{
+ struct pppoe_softc *sc = (struct pppoe_softc *)arg;
+
+ atomic_swap_uint(&sc->sc_timeout_scheduled, 0);
+ pppoe_timeout(sc);
+}
+
+static void
+pppoe_timeout(struct pppoe_softc *sc)
{
int retry_wait, err;
- struct pppoe_softc *sc = (struct pppoe_softc*)arg;
DECLARE_SPLNET_VARIABLE;
#ifdef PPPOE_DEBUG
Home |
Main Index |
Thread Index |
Old Index