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