summaryrefslogtreecommitdiff
path: root/share/man/man9
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2015-11-20 03:35:24 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2015-11-20 03:35:24 +0000
commit93d7f55b038092ded0514b3f745fd014c1845492 (patch)
treeda8fbd80cf246b5a4ebcdf952d9bb7b92cbe5e19 /share/man/man9
parentd3a33e8102f3bbde40bab36e7fc5067836baf064 (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/Makefile7
-rw-r--r--share/man/man9/ifq_enq.9140
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