diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-01-20 17:27:17 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2016-01-20 17:27:17 +0000 |
commit | 4708dca3e069f4fb1d8551f053e9e60520795354 (patch) | |
tree | 1f17aaced3c3ea1c6ead51c57790fa14b000d152 /sys | |
parent | 2dc681ae314bdc4af14b5e261b9389d193d1318a (diff) |
dlg@ took a pity on me and let me stay sane a bit longer by giving
me a chance to kill these glowing red trailing whitespace characters.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/ifq.h | 150 |
1 files changed, 75 insertions, 75 deletions
diff --git a/sys/net/ifq.h b/sys/net/ifq.h index f56f668e478..082c91864d0 100644 --- a/sys/net/ifq.h +++ b/sys/net/ifq.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ifq.h,v 1.4 2015/12/29 12:35:43 dlg Exp $ */ +/* $OpenBSD: ifq.h,v 1.5 2016/01/20 17:27:16 mikeb Exp $ */ /* * Copyright (c) 2015 David Gwynne <dlg@openbsd.org> @@ -51,63 +51,63 @@ struct ifqueue { #define IFQ_MAXLEN 256 /* - * + * * Interface Send Queues - * + * * struct ifqueue sits between the network stack and a drivers * transmission of packets. The high level view is that when the stack * has finished generating a packet it hands it to a driver for * transmission. It does this by queueing the packet on an ifqueue and * notifying the driver to start transmission of the queued packets. - * + * * struct ifqueue also provides the point where conditioning of * traffic (ie, priq and hfsc) is implemented, and provides some * infrastructure to assist in the implementation of network drivers. - * + * * = ifq API - * + * * The ifq API provides functions for three distinct consumers: - * + * * 1. The network stack * 2. Traffic QoS/conditioning implementations * 3. Network drivers - * + * * == Network Stack API - * + * * The network stack is responsible for initialising and destroying * the ifqueue structure, changing the traffic conditioner on an * interface queue, enqueuing packets for transmission, and notifying * the driver to start transmission. - * + * * === ifq_init() - * + * * During if_attach(), the network stack calls ifq_init to initialise * the ifqueue structure. By default it configures the priq traffic * conditioner. - * + * * === ifq_destroy() - * + * * The network stack calls ifq_destroy() during if_detach to tear down * the ifqueue structure. It frees the traffic conditioner state, and * frees any mbufs that were left queued. - * + * * === ifq_attach() - * + * * ifq_attach() is used to replace the current traffic conditioner on * the ifqueue. All the pending mbufs are removed from the previous * conditioner and requeued on the new. - * + * * === ifq_enqueue() and ifq_enqueue_try() - * + * * ifq_enqueue() and ifq_enqueue_try() attempt to fit an mbuf onto the * ifqueue. If the current traffic conditioner rejects the packet it * wont be queued and will be counted as a drop. ifq_enqueue() will * free the mbuf on the callers behalf if the packet is rejected. * ifq_enqueue_try() does not free the mbuf, allowing the caller to * reuse it. - * + * * === ifq_start() - * + * * Once a packet has been successfully queued with ifq_enqueue() or * ifq_enqueue_try(), the network card is notified with a call to * if_start(). If an interface is marked with IFXF_MPSAFE in its @@ -115,190 +115,190 @@ struct ifqueue { * interfaces start routine. Calls to ifq_start() run in the ifqueue * serialisation context, guaranteeing that only one instance of * ifp->if_start() will be running in the system at any point in time. - * - * + * + * * == Traffic conditioners API - * + * * The majority of interaction between struct ifqueue and a traffic * conditioner occurs via the callbacks a traffic conditioner provides * in an instance of struct ifq_ops. - * + * * XXX document ifqop_* - * + * * The ifqueue API implements the locking on behalf of the conditioning * implementations so conditioners only have to reject or keep mbufs. * If something needs to inspect a conditioners internals, the queue lock * needs to be taken to allow for a consistent or safe view. The queue * lock may be taken and released with ifq_q_enter() and ifq_q_leave(). - * + * * === ifq_q_enter() - * + * * Code wishing to access a conditioners internals may take the queue * lock with ifq_q_enter(). The caller must pass a reference to the * conditioners ifq_ops structure so the infrastructure can ensure the * caller is able to understand the internals. ifq_q_enter() returns * a pointer to the conditions internal structures, or NULL if the * ifq_ops did not match the current conditioner. - * + * * === ifq_q_leave() - * + * * The queue lock acquired with ifq_q_enter() is released with * ifq_q_leave(). - * - * + * + * * == Network Driver API - * + * * The API used by network drivers is mostly documented in the * ifq_dequeue(9) manpage except for ifq_serialize(), * ifq_is_serialized(), and IFQ_ASSERT_SERIALIZED(). - * + * * === ifq_serialize() - * + * * A driver may run arbitrary work in the ifqueue serialiser context * via ifq_serialize(). The work to be done is represented by a task * that has been prepared with task_set. - * + * * The work will be run in series with any other work dispatched by * ifq_start(), ifq_restart(), or other ifq_serialize() calls. - * + * * Because the work may be run on another CPU, the lifetime of the * task and the work it represents can extend beyond the end of the * call to ifq_serialize() that dispatched it. - * + * * === ifq_is_serialized() - * + * * This function returns whether the caller is currently within the * ifqueue serializer context. - * + * * === IFQ_ASSERT_SERIALIZED() - * + * * This macro will assert that the caller is currently within the * specified ifqueue serialiser context. - * - * + * + * * = ifqueue work serialisation - * + * * ifqueues provide a mechanism to dispatch work to be run in a single * context. Work in this mechanism is represtented by task structures. - * + * * The tasks are run in a context similar to a taskq serviced by a * single kernel thread, except the work is run immediately by the * first CPU that dispatches work. If a second CPU attempts to dispatch * additional tasks while the first is still running, it will be queued * to be run by the first CPU. The second CPU will return immediately. - * + * * = MP Safe Network Drivers - * + * * An MP safe network driver is one in which its start routine can be * called by the network stack without holding the big kernel lock. - * + * * == Attach - * + * * A driver advertises it's ability to run its start routine by setting * the IFXF_MPSAFE flag in ifp->if_xflags before calling if_attach(): - * + * * ifp->if_xflags = IFXF_MPSAFE; * ifp->if_start = drv_start; * if_attach(ifp); - * + * * The network stack will then wrap its calls to ifp->if_start with * ifq_start() to guarantee there is only one instance of that function * running in the system and to serialise it with other work the driver * may provide. - * + * * == Initialise - * + * * When the stack requests an interface be brought up (ie, drv_ioctl() * is called to handle SIOCSIFFLAGS with IFF_UP set in ifp->if_flags) * drivers should set IFF_RUNNING in ifp->if_flags and call * ifq_clr_oactive(). - * + * * == if_start - * + * * ifq_start() checks that IFF_RUNNING is set in ifp->if_flags, that * ifq_is_oactive() does not return true, and that there are pending * packets to transmit via a call to ifq_len(). Therefore, drivers are * no longer responsible for doing this themselves. - * + * * If a driver should not transmit packets while its link is down, use * ifq_purge() to flush pending packets from the transmit queue. - * + * * Drivers for hardware should use the following pattern to transmit * packets: - * + * * void * drv_start(struct ifnet *ifp) * { * struct drv_softc *sc = ifp->if_softc; * struct mbuf *m; * int kick = 0; - * + * * if (NO_LINK) { * ifq_purge(&ifp->if_snd); * return; * } - * + * * for (;;) { * if (NO_SPACE) { * ifq_set_oactive(&ifp->if_snd); * break; * } - * + * * m = ifq_dequeue(&ifp->if_snd); * if (m == NULL) * break; - * + * * if (drv_encap(sc, m) != 0) { // map and fill ring * m_freem(m); * continue; * } - * + * * bpf_mtap(); * } - * + * * drv_kick(sc); // notify hw of new descriptors on the ring * } - * + * * == Transmission completion - * + * * The following pattern should be used for transmit queue interrupt * processing: - * + * * void * drv_txeof(struct drv_softc *sc) * { * struct ifnet *ifp = &sc->sc_if; - * + * * while (COMPLETED_PKTS) { * // unmap packets, m_freem() the mbufs. * } - * + * * if (ifq_is_oactive(&ifp->if_snd)) * ifq_restart(&ifp->if_snd); * } - * + * * == Stop - * + * * Bringing an interface down (ie, IFF_UP was cleared in ifp->if_flags) * should clear IFF_RUNNING in ifp->if_flags, and guarantee the start * routine is not running before freeing any resources it uses: - * + * * void * drv_down(struct drv_softc *sc) * { * struct ifnet *ifp = &sc->sc_if; - * + * * CLR(ifp->if_flags, IFF_RUNNING); * DISABLE_INTERRUPTS(); - * + * * ifq_barrier(&ifp->if_snd); * intr_barrier(sc->sc_ih); - * + * * FREE_RESOURCES(); - * + * * ifq_clr_oactive(); * } - * + * */ struct ifq_ops { |