diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2015-11-20 03:35:24 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2015-11-20 03:35:24 +0000 |
commit | 93d7f55b038092ded0514b3f745fd014c1845492 (patch) | |
tree | da8fbd80cf246b5a4ebcdf952d9bb7b92cbe5e19 /share/man/man9 | |
parent | d3a33e8102f3bbde40bab36e7fc5067836baf064 (diff) |
shuffle struct ifqueue so in flight mbufs are protected by a mutex.
the code is refactored so the IFQ macros call newly implemented ifq
functions. the ifq code is split so each discipline (priq and hfsc
in our case) is an opaque set of operations that the common ifq
code can call. the common code does the locking, accounting (ifq_len
manipulation), and freeing of the mbuf if the disciplines enqueue
function rejects it. theyre kind of like bufqs in the block layer
with their fifo and nscan disciplines.
the new api also supports atomic switching of disciplines at runtime.
the hfsc setup in pf_ioctl.c has been tweaked to build a complete
hfsc_if structure which it attaches to the send queue in a single
operation, rather than attaching to the interface up front and
building up a list of queues.
the send queue is now mutexed, which raises the expectation that
packets can be enqueued or purged on one cpu while another cpu is
dequeueing them in a driver for transmission. a lot of drivers use
IFQ_POLL to peek at an mbuf and attempt to fit it on the ring before
committing to it with a later IFQ_DEQUEUE operation. if the mbuf
gets freed in between the POLL and DEQUEUE operations, fireworks
will ensue.
to avoid this, the ifq api introduces ifq_deq_begin, ifq_deq_rollback,
and ifq_deq_commit. ifq_deq_begin allows a driver to take the ifq
mutex and get a reference to the mbuf they wish to try and tx. if
there's space, they can ifq_deq_commit it to remove the mbuf and
release the mutex. if there's no space, ifq_deq_rollback simply
releases the mutex. this api was developed to make updating the
drivers using IFQ_POLL easy, instead of having to do significant
semantic changes to avoid POLL that we cannot test on all the
hardware.
the common code has been tested pretty hard, and all the driver
modifications are straightforward except for de(4). if that breaks
it can be dealt with later.
ok mpi@ jmatthew@
Diffstat (limited to 'share/man/man9')
-rw-r--r-- | share/man/man9/Makefile | 7 | ||||
-rw-r--r-- | share/man/man9/ifq_enq.9 | 140 |
2 files changed, 145 insertions, 2 deletions
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index 386f4bc65ce..ddffd6be35c 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.253 2015/11/15 19:35:05 jmc Exp $ +# $OpenBSD: Makefile,v 1.254 2015/11/20 03:35:22 dlg Exp $ # $NetBSD: Makefile,v 1.4 1996/01/09 03:23:01 thorpej Exp $ # Makefile for section 9 (kernel function and variable) manual pages. @@ -18,7 +18,7 @@ MAN= aml_evalnode.9 atomic_add_int.9 atomic_cas_uint.9 \ ieee80211.9 ieee80211_crypto.9 ieee80211_input.9 ieee80211_ioctl.9 \ ieee80211_node.9 ieee80211_output.9 ieee80211_proto.9 \ ieee80211_radiotap.9 \ - if_rxr_init.9 iic.9 intro.9 inittodr.9 intr_barrier.9 \ + if_rxr_init.9 ifq_enq.9 iic.9 intro.9 inittodr.9 intr_barrier.9 \ kern.9 km_alloc.9 knote.9 kthread.9 ktrace.9 \ loadfirmware.9 lock.9 log.9 \ malloc.9 membar_sync.9 mbuf.9 mbuf_tags.9 md5.9 mi_switch.9 \ @@ -216,6 +216,9 @@ MLINKS+=ieee80211_proto.9 ieee80211_proto_attach.9 \ MLINKS+=if_rxr_init.9 if_rxr_get.9 if_rxr_init.9 if_rxr_put.9 \ if_rxr_init.9 if_rxr_inuse.9 if_rxr_init.9 if_rxr_ioctl.9 \ if_rxr_init.9 if_rxr_info_ioctl.9 +MLINKS+=ifq_enq.9 ifq_deq.9 ifq_enq.9 ifq_deq_begin.9 \ + ifq_enq.9 ifq_deq_commit.9 ifq_enq.9 ifq_deq_rollback.9 \ + ifq_enq.9 ifq_purge.9 ifq_enq.9 ifq_len.9 ifq_enq.9 ifq_empty.9 MLINKS+=iic.9 iic_acquire_bus.9 iic.9 iic_release_bus.9 iic.9 iic_exec.9 \ iic.9 iic_smbus_write_byte.9 iic.9 iic_smbus_read_byte.9 \ iic.9 iic_smbus_receive_byte.9 diff --git a/share/man/man9/ifq_enq.9 b/share/man/man9/ifq_enq.9 new file mode 100644 index 00000000000..a4be8a0aceb --- /dev/null +++ b/share/man/man9/ifq_enq.9 @@ -0,0 +1,140 @@ +.\" $OpenBSD: ifq_enq.9,v 1.1 2015/11/20 03:35:22 dlg Exp $ +.\" +.\" Copyright (c) 2015 David Gwynne <dlg@openbsd.org> +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: November 20 2015 $ +.Dt IFQ_ENQ 9 +.Os +.Sh NAME +.Nm ifq_enq , +.Nm ifq_deq , +.Nm ifq_deq_begin , +.Nm ifq_deq_commit , +.Nm ifq_deq_rollback , +.Nm ifq_purge , +.Nm ifq_len , +.Nm ifq_empty +.Nd Interface send queue API +.Sh SYNOPSIS +.In net/if_var.h +.Ft int +.Fn ifq_enq "struct ifqueue *ifq" "struct mbuf *m" +.Ft struft mbuf * +.Fn ifq_deq "struct ifqueue *ifq" +.Ft struft mbuf * +.Fn ifq_deq_begin "struct ifqueue *ifq" +.Ft void +.Fn ifq_deq_commit "struct ifqueue *ifq" "struct mbuf *m" +.Ft void +.Fn ifq_deq_rollback "struct ifqueue *ifq" "struct mbuf *m" +.Ft unsigned int +.Fn ifq_purge "struct ifqueue *ifq" +.Ft unsigned int +.Fn ifq_len "struct ifqueue *ifq" +.Ft unsigned int +.Fn ifq_empty "struct ifqueue *ifq" +.Sh DESCRIPTION +The ifqueue API provides implementions of data structures and +operations for the network stack to queue mbufs for a network driver +to dequeue from its start routine for transmission. +.Bl -tag -width Ds +.It Fn ifq_enq "struct ifqueue *ifq" "struct mbuf *m" +Enqueue mbuf +.Fa m +on the +.Fa ifq +interface send queue. +If the queue rejects the packet it will be freed with +.Xr m_freem 9 +and counted as a drop. +.It Fn ifq_deq "struct ifqueue *ifq" +Dequeue the next mbuf to be transmitted from the +.Fa ifq +interface send queue. +.It Fn ifq_deq_begin "struct ifqueue *ifq" +Get a reference to the next mbuf to be transmitted from the +.Fa ifq +interface send queue. +If an mbuf is to be transmitted, also acquire a lock on the send queue +to exclude modification or freeing of the referenced mbuf. +The mbuf must not be freed, or have its length (m_pkthdr.len) or +cookie (m_pkthdr.ph_cookie) modified until it has been dequeued +completely with +.Fn ifq_deq_commit . +.It Fn ifq_deq_commit "struct ifqueue *ifq" "struct mbuf *m" +Dequeue the mbuf +.Fa m +that was referenced by a previous call to +.Fn ifq_deq_begin +and release the lock on +.Fa ifq . +.It Fn ifq_deq_rollback "struct ifqueue *ifq" "struct mbuf *m" +Release the lock on the interface send queue +.Fa ifq +that was acquired while a reference to +.Fa m +was being held. +.It Fn ifq_purge "struct ifqueue *ifq" +Free all the mbufs on the interface send queue +.Fa ifq . +Freed mbufs will be accounted as drops. +.It Fn ifq_len "struct ifqueue *ifq" +Return the number of mbufs on the interface send queue +.Fa ifq . +Note that while +.Fn ifq_len +may report that mbufs are on the queue, the current queue +discipline may not make them available for dequeueing with +.Fn ifq_deq +or +.Fn ifq_deq_begin . +.It Fn ifq_empty "struct ifqueue *ifq" +Return if the interface send queue +.Fa ifq +is empty. +.El +.Sh CONTEXT +.Fn ifq_enq , +.Fn ifq_deq , +.Fn ifq_deq_begin , +.Fn ifq_deq_commit , +.Fn ifq_deq_rollback , +.Fn ifq_purge , +.Fn ifq_len , +and +.Fn ifq_empty +can be called during autoconf, from process context, or from interrupt context. +.Sh RETURN VALUES +.Fn ifq_enq +returns 0 if the mbuf was successfully queued, or non-zero if mbuf was freed. +.Pp +.Fn ifq_deq +and +.Fn ifq_deq_begin +return the next mbuf to be transmitted by the interface. +If no packet is available for transmission, +.Dv NULL +is returned. +.Pp +.Fn ifq_purge +returns the number of mbufs that were removed from the queue and freed. +.Pp +.Fn ifq_len +returns the number of mbufs on the queue. +.Pp +.Fn ifq_empty +returns a non-zero value if the queue is empty, otherwise 0. +.Sh SEE ALSO +.Xr m_freem 9 |