1 /* $OpenBSD: ifq.h,v 1.5 2016/01/20 17:27:16 mikeb Exp $ */ 2 3 /* 4 * Copyright (c) 2015 David Gwynne <dlg@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #ifndef _NET_IFQ_H_ 20 #define _NET_IFQ_H_ 21 22 struct ifnet; 23 24 struct ifq_ops; 25 26 struct ifqueue { 27 struct ifnet *ifq_if; 28 29 /* mbuf handling */ 30 struct mutex ifq_mtx; 31 uint64_t ifq_drops; 32 const struct ifq_ops *ifq_ops; 33 void *ifq_q; 34 unsigned int ifq_len; 35 unsigned int ifq_oactive; 36 37 /* work serialisation */ 38 struct mutex ifq_task_mtx; 39 struct task_list ifq_task_list; 40 void *ifq_serializer; 41 42 /* work to be serialised */ 43 struct task ifq_start; 44 struct task ifq_restart; 45 46 unsigned int ifq_maxlen; 47 }; 48 49 #ifdef _KERNEL 50 51 #define IFQ_MAXLEN 256 52 53 /* 54 * 55 * Interface Send Queues 56 * 57 * struct ifqueue sits between the network stack and a drivers 58 * transmission of packets. The high level view is that when the stack 59 * has finished generating a packet it hands it to a driver for 60 * transmission. It does this by queueing the packet on an ifqueue and 61 * notifying the driver to start transmission of the queued packets. 62 * 63 * struct ifqueue also provides the point where conditioning of 64 * traffic (ie, priq and hfsc) is implemented, and provides some 65 * infrastructure to assist in the implementation of network drivers. 66 * 67 * = ifq API 68 * 69 * The ifq API provides functions for three distinct consumers: 70 * 71 * 1. The network stack 72 * 2. Traffic QoS/conditioning implementations 73 * 3. Network drivers 74 * 75 * == Network Stack API 76 * 77 * The network stack is responsible for initialising and destroying 78 * the ifqueue structure, changing the traffic conditioner on an 79 * interface queue, enqueuing packets for transmission, and notifying 80 * the driver to start transmission. 81 * 82 * === ifq_init() 83 * 84 * During if_attach(), the network stack calls ifq_init to initialise 85 * the ifqueue structure. By default it configures the priq traffic 86 * conditioner. 87 * 88 * === ifq_destroy() 89 * 90 * The network stack calls ifq_destroy() during if_detach to tear down 91 * the ifqueue structure. It frees the traffic conditioner state, and 92 * frees any mbufs that were left queued. 93 * 94 * === ifq_attach() 95 * 96 * ifq_attach() is used to replace the current traffic conditioner on 97 * the ifqueue. All the pending mbufs are removed from the previous 98 * conditioner and requeued on the new. 99 * 100 * === ifq_enqueue() and ifq_enqueue_try() 101 * 102 * ifq_enqueue() and ifq_enqueue_try() attempt to fit an mbuf onto the 103 * ifqueue. If the current traffic conditioner rejects the packet it 104 * wont be queued and will be counted as a drop. ifq_enqueue() will 105 * free the mbuf on the callers behalf if the packet is rejected. 106 * ifq_enqueue_try() does not free the mbuf, allowing the caller to 107 * reuse it. 108 * 109 * === ifq_start() 110 * 111 * Once a packet has been successfully queued with ifq_enqueue() or 112 * ifq_enqueue_try(), the network card is notified with a call to 113 * if_start(). If an interface is marked with IFXF_MPSAFE in its 114 * if_xflags field, if_start() calls ifq_start() to dispatch the 115 * interfaces start routine. Calls to ifq_start() run in the ifqueue 116 * serialisation context, guaranteeing that only one instance of 117 * ifp->if_start() will be running in the system at any point in time. 118 * 119 * 120 * == Traffic conditioners API 121 * 122 * The majority of interaction between struct ifqueue and a traffic 123 * conditioner occurs via the callbacks a traffic conditioner provides 124 * in an instance of struct ifq_ops. 125 * 126 * XXX document ifqop_* 127 * 128 * The ifqueue API implements the locking on behalf of the conditioning 129 * implementations so conditioners only have to reject or keep mbufs. 130 * If something needs to inspect a conditioners internals, the queue lock 131 * needs to be taken to allow for a consistent or safe view. The queue 132 * lock may be taken and released with ifq_q_enter() and ifq_q_leave(). 133 * 134 * === ifq_q_enter() 135 * 136 * Code wishing to access a conditioners internals may take the queue 137 * lock with ifq_q_enter(). The caller must pass a reference to the 138 * conditioners ifq_ops structure so the infrastructure can ensure the 139 * caller is able to understand the internals. ifq_q_enter() returns 140 * a pointer to the conditions internal structures, or NULL if the 141 * ifq_ops did not match the current conditioner. 142 * 143 * === ifq_q_leave() 144 * 145 * The queue lock acquired with ifq_q_enter() is released with 146 * ifq_q_leave(). 147 * 148 * 149 * == Network Driver API 150 * 151 * The API used by network drivers is mostly documented in the 152 * ifq_dequeue(9) manpage except for ifq_serialize(), 153 * ifq_is_serialized(), and IFQ_ASSERT_SERIALIZED(). 154 * 155 * === ifq_serialize() 156 * 157 * A driver may run arbitrary work in the ifqueue serialiser context 158 * via ifq_serialize(). The work to be done is represented by a task 159 * that has been prepared with task_set. 160 * 161 * The work will be run in series with any other work dispatched by 162 * ifq_start(), ifq_restart(), or other ifq_serialize() calls. 163 * 164 * Because the work may be run on another CPU, the lifetime of the 165 * task and the work it represents can extend beyond the end of the 166 * call to ifq_serialize() that dispatched it. 167 * 168 * === ifq_is_serialized() 169 * 170 * This function returns whether the caller is currently within the 171 * ifqueue serializer context. 172 * 173 * === IFQ_ASSERT_SERIALIZED() 174 * 175 * This macro will assert that the caller is currently within the 176 * specified ifqueue serialiser context. 177 * 178 * 179 * = ifqueue work serialisation 180 * 181 * ifqueues provide a mechanism to dispatch work to be run in a single 182 * context. Work in this mechanism is represtented by task structures. 183 * 184 * The tasks are run in a context similar to a taskq serviced by a 185 * single kernel thread, except the work is run immediately by the 186 * first CPU that dispatches work. If a second CPU attempts to dispatch 187 * additional tasks while the first is still running, it will be queued 188 * to be run by the first CPU. The second CPU will return immediately. 189 * 190 * = MP Safe Network Drivers 191 * 192 * An MP safe network driver is one in which its start routine can be 193 * called by the network stack without holding the big kernel lock. 194 * 195 * == Attach 196 * 197 * A driver advertises it's ability to run its start routine by setting 198 * the IFXF_MPSAFE flag in ifp->if_xflags before calling if_attach(): 199 * 200 * ifp->if_xflags = IFXF_MPSAFE; 201 * ifp->if_start = drv_start; 202 * if_attach(ifp); 203 * 204 * The network stack will then wrap its calls to ifp->if_start with 205 * ifq_start() to guarantee there is only one instance of that function 206 * running in the system and to serialise it with other work the driver 207 * may provide. 208 * 209 * == Initialise 210 * 211 * When the stack requests an interface be brought up (ie, drv_ioctl() 212 * is called to handle SIOCSIFFLAGS with IFF_UP set in ifp->if_flags) 213 * drivers should set IFF_RUNNING in ifp->if_flags and call 214 * ifq_clr_oactive(). 215 * 216 * == if_start 217 * 218 * ifq_start() checks that IFF_RUNNING is set in ifp->if_flags, that 219 * ifq_is_oactive() does not return true, and that there are pending 220 * packets to transmit via a call to ifq_len(). Therefore, drivers are 221 * no longer responsible for doing this themselves. 222 * 223 * If a driver should not transmit packets while its link is down, use 224 * ifq_purge() to flush pending packets from the transmit queue. 225 * 226 * Drivers for hardware should use the following pattern to transmit 227 * packets: 228 * 229 * void 230 * drv_start(struct ifnet *ifp) 231 * { 232 * struct drv_softc *sc = ifp->if_softc; 233 * struct mbuf *m; 234 * int kick = 0; 235 * 236 * if (NO_LINK) { 237 * ifq_purge(&ifp->if_snd); 238 * return; 239 * } 240 * 241 * for (;;) { 242 * if (NO_SPACE) { 243 * ifq_set_oactive(&ifp->if_snd); 244 * break; 245 * } 246 * 247 * m = ifq_dequeue(&ifp->if_snd); 248 * if (m == NULL) 249 * break; 250 * 251 * if (drv_encap(sc, m) != 0) { // map and fill ring 252 * m_freem(m); 253 * continue; 254 * } 255 * 256 * bpf_mtap(); 257 * } 258 * 259 * drv_kick(sc); // notify hw of new descriptors on the ring 260 * } 261 * 262 * == Transmission completion 263 * 264 * The following pattern should be used for transmit queue interrupt 265 * processing: 266 * 267 * void 268 * drv_txeof(struct drv_softc *sc) 269 * { 270 * struct ifnet *ifp = &sc->sc_if; 271 * 272 * while (COMPLETED_PKTS) { 273 * // unmap packets, m_freem() the mbufs. 274 * } 275 * 276 * if (ifq_is_oactive(&ifp->if_snd)) 277 * ifq_restart(&ifp->if_snd); 278 * } 279 * 280 * == Stop 281 * 282 * Bringing an interface down (ie, IFF_UP was cleared in ifp->if_flags) 283 * should clear IFF_RUNNING in ifp->if_flags, and guarantee the start 284 * routine is not running before freeing any resources it uses: 285 * 286 * void 287 * drv_down(struct drv_softc *sc) 288 * { 289 * struct ifnet *ifp = &sc->sc_if; 290 * 291 * CLR(ifp->if_flags, IFF_RUNNING); 292 * DISABLE_INTERRUPTS(); 293 * 294 * ifq_barrier(&ifp->if_snd); 295 * intr_barrier(sc->sc_ih); 296 * 297 * FREE_RESOURCES(); 298 * 299 * ifq_clr_oactive(); 300 * } 301 * 302 */ 303 304 struct ifq_ops { 305 void *(*ifqop_alloc)(void *); 306 void (*ifqop_free)(void *); 307 int (*ifqop_enq)(struct ifqueue *, struct mbuf *); 308 struct mbuf *(*ifqop_deq_begin)(struct ifqueue *, void **); 309 void (*ifqop_deq_commit)(struct ifqueue *, 310 struct mbuf *, void *); 311 void (*ifqop_purge)(struct ifqueue *, 312 struct mbuf_list *); 313 }; 314 315 /* 316 * Interface send queues. 317 */ 318 319 void ifq_init(struct ifqueue *, struct ifnet *); 320 void ifq_attach(struct ifqueue *, const struct ifq_ops *, void *); 321 void ifq_destroy(struct ifqueue *); 322 int ifq_enqueue_try(struct ifqueue *, struct mbuf *); 323 int ifq_enqueue(struct ifqueue *, struct mbuf *); 324 struct mbuf *ifq_deq_begin(struct ifqueue *); 325 void ifq_deq_commit(struct ifqueue *, struct mbuf *); 326 void ifq_deq_rollback(struct ifqueue *, struct mbuf *); 327 struct mbuf *ifq_dequeue(struct ifqueue *); 328 unsigned int ifq_purge(struct ifqueue *); 329 void *ifq_q_enter(struct ifqueue *, const struct ifq_ops *); 330 void ifq_q_leave(struct ifqueue *, void *); 331 void ifq_serialize(struct ifqueue *, struct task *); 332 int ifq_is_serialized(struct ifqueue *); 333 void ifq_barrier(struct ifqueue *); 334 335 #define ifq_len(_ifq) ((_ifq)->ifq_len) 336 #define ifq_empty(_ifq) (ifq_len(_ifq) == 0) 337 #define ifq_set_maxlen(_ifq, _l) ((_ifq)->ifq_maxlen = (_l)) 338 339 static inline void 340 ifq_set_oactive(struct ifqueue *ifq) 341 { 342 ifq->ifq_oactive = 1; 343 } 344 345 static inline void 346 ifq_clr_oactive(struct ifqueue *ifq) 347 { 348 ifq->ifq_oactive = 0; 349 } 350 351 static inline unsigned int 352 ifq_is_oactive(struct ifqueue *ifq) 353 { 354 return (ifq->ifq_oactive); 355 } 356 357 static inline void 358 ifq_start(struct ifqueue *ifq) 359 { 360 ifq_serialize(ifq, &ifq->ifq_start); 361 } 362 363 static inline void 364 ifq_restart(struct ifqueue *ifq) 365 { 366 ifq_serialize(ifq, &ifq->ifq_restart); 367 } 368 369 #define IFQ_ASSERT_SERIALIZED(_ifq) KASSERT(ifq_is_serialized(_ifq)) 370 371 extern const struct ifq_ops * const ifq_priq_ops; 372 373 #endif /* _KERNEL */ 374 375 #endif /* _NET_IFQ_H_ */ 376