diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2015-12-03 12:22:52 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2015-12-03 12:22:52 +0000 |
commit | bf1238a62fc939582179123c95fc26d7d76dc5f2 (patch) | |
tree | 1ac0c5adde30dc35ad8f81291dd2b946387e8c54 /sys/net/if_var.h | |
parent | 5d1cc1f2e49619d168b935c6595ad7107ec10136 (diff) |
rework if_start to allow nics to provide an mpsafe start routine.
existing start routines will still be called under the kernel lock
and at IPL_NET.
mpsafe start routines will be serialised so only one instance of
each interfaces function will be running in the kernel at any point
in time. this guarantees packets will be dequeued in order, and the
start routines dont have to lock against themselves because if_start
does it for them.
the code to do that is based on the scsi runqueue code.
this also provides an if_start_barrier() function that should wait
until any currently running instances of if_start have finished.
a driver can opt in to the mpsafe if_start call by doing the following:
1. setting ifp->if_xflags = IFXF_MPSAFE
2. only calling if_start() instead of its own start routine
3. clearing IFF_RUNNING before calling if_start_barrier() on its way down
4. only using IFQ_DEQUEUE (not ifq_deq_begin/commit/rollback)
to simplify the implementation the tx mitigation code has been removed.
tested by several
ok mpi@ jmatthew@
Diffstat (limited to 'sys/net/if_var.h')
-rw-r--r-- | sys/net/if_var.h | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 85dde1fc6f8..d411fec1ef1 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_var.h,v 1.60 2015/12/02 08:03:00 mpi Exp $ */ +/* $OpenBSD: if_var.h,v 1.61 2015/12/03 12:22:51 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -129,7 +129,6 @@ struct ifnet { /* and the entries */ void *if_softc; /* lower-level data for this if */ struct refcnt if_refcnt; TAILQ_ENTRY(ifnet) if_list; /* all struct ifnets are chained */ - TAILQ_ENTRY(ifnet) if_txlist; /* list of ifnets ready to tx */ TAILQ_HEAD(, ifaddr) if_addrlist; /* linked list of addresses per if */ TAILQ_HEAD(, ifmaddr) if_maddrlist; /* list of multicast records */ TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */ @@ -364,6 +363,7 @@ extern struct ifnet_head ifnet; extern unsigned int lo0ifidx; void if_start(struct ifnet *); +void if_start_barrier(struct ifnet *); int if_enqueue_try(struct ifnet *, struct mbuf *); int if_enqueue(struct ifnet *, struct mbuf *); void if_input(struct ifnet *, struct mbuf_list *); |