Switch agr(4) to use a workqueue. This is necessary because during

a callout, it allocates memory with M_WAITOK, which triggers a
DEBUG assert.

XXX we should drain the workqueue.

ok riastradh
This commit is contained in:
maya 2017-01-28 22:56:09 +00:00
parent 45f67fc24b
commit 491605d47f
4 changed files with 35 additions and 16 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_agr.c,v 1.40 2016/12/15 09:28:06 ozaki-r Exp $ */
/* $NetBSD: if_agr.c,v 1.41 2017/01/28 22:56:09 maya Exp $ */
/*-
* Copyright (c)2005 YAMAMOTO Takashi,
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_agr.c,v 1.40 2016/12/15 09:28:06 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_agr.c,v 1.41 2017/01/28 22:56:09 maya Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -343,14 +343,19 @@ agr_clone_create(struct if_clone *ifc, int unit)
{
struct agr_softc *sc;
struct ifnet *ifp;
int error;
sc = agr_alloc_softc();
error = agrtimer_init(sc);
if (error) {
agr_free_softc(sc);
return error;
}
TAILQ_INIT(&sc->sc_ports);
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NET);
mutex_init(&sc->sc_entry_mtx, MUTEX_DEFAULT, IPL_NONE);
cv_init(&sc->sc_insc_cv, "agrsoftc");
cv_init(&sc->sc_ports_cv, "agrports");
agrtimer_init(sc);
ifp = &sc->sc_if;
snprintf(ifp->if_xname, sizeof(ifp->if_xname), "%s%d",
ifc->ifc_name, unit);

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_agrmonitor.c,v 1.4 2008/03/24 09:14:52 yamt Exp $ */
/* $NetBSD: if_agrmonitor.c,v 1.5 2017/01/28 22:56:09 maya Exp $ */
/*-
* Copyright (c)2005 YAMAMOTO Takashi,
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_agrmonitor.c,v 1.4 2008/03/24 09:14:52 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_agrmonitor.c,v 1.5 2017/01/28 22:56:09 maya Exp $");
#include <sys/param.h>
#include <sys/callout.h>
@ -46,12 +46,6 @@ agrport_monitor(struct agr_port *port)
u_int media;
u_int status;
/*
* XXX XXX
* assuming that it's safe to use SIOCGIFMEDIA from callout handler.
* maybe it's better to have a worker thread.
*/
media = IFM_ETHER | IFM_NONE;
status = IFM_AVALID;
if ((~port->port_ifp->if_flags & (IFF_RUNNING | IFF_UP))

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_agrtimer.c,v 1.6 2010/02/08 17:59:06 dyoung Exp $ */
/* $NetBSD: if_agrtimer.c,v 1.7 2017/01/28 22:56:09 maya Exp $ */
/*-
* Copyright (c)2005 YAMAMOTO Takashi,
@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_agrtimer.c,v 1.6 2010/02/08 17:59:06 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_agrtimer.c,v 1.7 2017/01/28 22:56:09 maya Exp $");
#include <sys/param.h>
#include <sys/callout.h>
@ -40,14 +40,22 @@ __KERNEL_RCSID(0, "$NetBSD: if_agrtimer.c,v 1.6 2010/02/08 17:59:06 dyoung Exp $
#include <net/agr/if_agrsubr.h>
static void agrtimer_tick(void *);
static void agrtimer_work(struct work *, void *);
static int agrtimer_port_tick(struct agr_port *, void *);
void
int
agrtimer_init(struct agr_softc *sc)
{
int error;
error = workqueue_create(&sc->sc_wq, "agrmon",
agrtimer_work, sc, PRI_SOFTNET, IPL_SOFTNET, 0);
if (error)
return error;
callout_init(&sc->sc_callout, 0);
callout_setfunc(&sc->sc_callout, agrtimer_tick, sc);
return 0;
}
void
@ -55,6 +63,7 @@ agrtimer_destroy(struct agr_softc *sc)
{
callout_destroy(&sc->sc_callout);
workqueue_destroy(sc->sc_wq);
}
void
@ -73,6 +82,14 @@ agrtimer_stop(struct agr_softc *sc)
static void
agrtimer_tick(void *arg)
{
struct agr_softc *sc = arg;
workqueue_enqueue(sc->sc_wq, &sc->sc_wk, NULL);
}
static void
agrtimer_work(struct work *wk, void *arg)
{
struct agr_softc *sc = arg;
const struct agr_iftype_ops *iftop = sc->sc_iftop;

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_agrvar_impl.h,v 1.10 2010/05/26 23:46:44 dyoung Exp $ */
/* $NetBSD: if_agrvar_impl.h,v 1.11 2017/01/28 22:56:09 maya Exp $ */
/*-
* Copyright (c)2005 YAMAMOTO Takashi,
@ -35,6 +35,7 @@
#include <sys/mutex.h>
#include <sys/queue.h>
#include <sys/workqueue.h>
struct agr_port;
struct agr_softc;
@ -112,6 +113,8 @@ struct agr_softc {
volatile bool sc_wrports;
volatile int sc_rdports;
volatile int sc_paused;
struct workqueue *sc_wq;
struct work sc_wk;
struct callout sc_callout;
int sc_nports;
TAILQ_HEAD(, agr_port) sc_ports;
@ -142,7 +145,7 @@ int agr_xmit_frame(struct ifnet *, struct mbuf *); /* XXX */
#define AGR_ROUNDROBIN(sc) (((sc)->sc_if.if_flags & IFF_LINK0) != 0)
#define AGR_STATIC(sc) (((sc)->sc_if.if_flags & IFF_LINK1) != 0)
void agrtimer_init(struct agr_softc *);
int agrtimer_init(struct agr_softc *);
void agrtimer_destroy(struct agr_softc *);
void agrtimer_start(struct agr_softc *);
void agrtimer_stop(struct agr_softc *);