Do pppoe_timeout() in thread context
OKed by knakahara@n.o fix port-amd64/55661
This commit is contained in:
parent
4acbb1f5ae
commit
66fdad6aa8
|
@ -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 @@ __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.150 2020/09/18 09:48:56 yamaguchi Exp
|
|||
#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 @@ __KERNEL_RCSID(0, "$NetBSD: if_pppoe.c,v 1.150 2020/09/18 09:48:56 yamaguchi Exp
|
|||
#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>
|
||||
|
@ -174,6 +176,9 @@ struct pppoe_softc {
|
|||
size_t sc_hunique_len; /* length of host unique */
|
||||
#endif
|
||||
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 int pppoe_transmit(struct ifnet *, struct mbuf *);
|
|||
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 @@ pppoe_clone_create(struct if_clone *ifc, int unit)
|
|||
/* 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 @@ pppoe_clone_create(struct if_clone *ifc, int unit)
|
|||
|
||||
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 @@ pppoe_clone_destroy(struct ifnet *ifp)
|
|||
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 @@ pppoe_clone_destroy(struct ifnet *ifp)
|
|||
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 @@ pppoe_send_padi(struct pppoe_softc *sc)
|
|||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue