dn_sched.h revision 204591
1/* 2 * Copyright (c) 2010 Riccardo Panicucci, Luigi Rizzo, Universita` di Pisa 3 * All rights reserved 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27/* 28 * The API to write a packet scheduling algorithm for dummynet. 29 * 30 * $FreeBSD: head/sys/netinet/ipfw/dn_sched.h 204591 2010-03-02 17:40:48Z luigi $ 31 */ 32 33#ifndef _DN_SCHED_H 34#define _DN_SCHED_H 35 36#define DN_MULTIQUEUE 0x01 37/* 38 * Descriptor for a scheduling algorithm. 39 * Contains all function pointers for a given scheduler 40 * This is typically created when a module is loaded, and stored 41 * in a global list of schedulers. 42 */ 43struct dn_alg { 44 uint32_t type; /* the scheduler type */ 45 const char *name; /* scheduler name */ 46 uint32_t flags; /* DN_MULTIQUEUE if supports multiple queues */ 47 48 /* 49 * The following define the size of 3 optional data structures 50 * that may need to be allocated at runtime, and are appended 51 * to each of the base data structures: scheduler, sched.inst, 52 * and queue. We don't have a per-flowset structure. 53 */ 54 /* + parameters attached to the template, e.g. 55 * default queue sizes, weights, quantum size, and so on; 56 */ 57 size_t schk_datalen; 58 59 /* + per-instance parameters, such as timestamps, 60 * containers for queues, etc; 61 */ 62 size_t si_datalen; 63 64 size_t q_datalen; /* per-queue parameters (e.g. S,F) */ 65 66 /* 67 * Methods implemented by the scheduler: 68 * enqueue enqueue packet 'm' on scheduler 's', queue 'q'. 69 * q is NULL for !MULTIQUEUE. 70 * Return 0 on success, 1 on drop (packet consumed anyways). 71 * 72 * dequeue Called when scheduler instance 's' can 73 * dequeue a packet. Return NULL if none are available. 74 * XXX what about non work-conserving ? 75 * 76 * config called on 'sched X config ...', normally writes 77 * in the area of size sch_arg 78 * 79 * destroy called on 'sched delete', frees everything 80 * in sch_arg (other parts are handled by more specific 81 * functions) 82 * 83 * new_sched called when a new instance is created, e.g. 84 * to create the local queue for !MULTIQUEUE, set V or 85 * copy parameters for WFQ, and so on. 86 * 87 * free_sched called when deleting an instance, cleans 88 * extra data in the per-instance area. 89 * 90 * new_fsk called when a flowset is linked to a scheduler, 91 * e.g. to validate parameters such as weights etc. 92 * free_fsk when a flowset is unlinked from a scheduler. 93 * (probably unnecessary) 94 * 95 * new_queue called to set the per-queue parameters, 96 * e.g. S and F, adjust sum of weights in the parent, etc. 97 * If the queue has packets in it, add them to the scheduler 98 * as well. 99 * 100 * free_queue actions related to a queue removal, e.g. undo 101 * all the above. If the queue has data in it, also remove 102 * from the scheduler. This can e.g. happen during a reconfigure. 103 */ 104 int (*enqueue)(struct dn_sch_inst *, struct dn_queue *, 105 struct mbuf *); 106 struct mbuf * (*dequeue)(struct dn_sch_inst *); 107 108 int (*config)(struct dn_schk *); 109 int (*destroy)(struct dn_schk*); 110 int (*new_sched)(struct dn_sch_inst *); 111 int (*free_sched)(struct dn_sch_inst *); 112 int (*new_fsk)(struct dn_fsk *f); 113 int (*free_fsk)(struct dn_fsk *f); 114 int (*new_queue)(struct dn_queue *q); 115 int (*free_queue)(struct dn_queue *q); 116 117 /* run-time fields */ 118 int ref_count; /* XXX number of instances in the system */ 119 SLIST_ENTRY(dn_alg) next; /* Next scheduler in the list */ 120}; 121 122/* MSVC does not support initializers so we need this ugly macro */ 123#ifdef _WIN32 124#define _SI(fld) 125#else 126#define _SI(fld) fld 127#endif 128 129/* 130 * Additionally, dummynet exports some functions and macros 131 * to be used by schedulers: 132 */ 133 134void dn_free_pkts(struct mbuf *mnext); 135int dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop); 136/* bound a variable between min and max */ 137int ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg); 138 139/* 140 * Extract the head of a queue, update stats. Must be the very last 141 * thing done on a dequeue as the queue itself may go away. 142 */ 143static __inline struct mbuf* 144dn_dequeue(struct dn_queue *q) 145{ 146 struct mbuf *m = q->mq.head; 147 if (m == NULL) 148 return NULL; 149 q->mq.head = m->m_nextpkt; 150 q->ni.length--; 151 q->ni.len_bytes -= m->m_pkthdr.len; 152 if (q->_si) { 153 q->_si->ni.length--; 154 q->_si->ni.len_bytes -= m->m_pkthdr.len; 155 } 156 if (q->ni.length == 0) /* queue is now idle */ 157 q->q_time = dn_cfg.curr_time; 158 return m; 159} 160 161int dn_sched_modevent(module_t mod, int cmd, void *arg); 162 163#define DECLARE_DNSCHED_MODULE(name, dnsched) \ 164 static moduledata_t name##_mod = { \ 165 #name, dn_sched_modevent, dnsched \ 166 }; \ 167 DECLARE_MODULE(name, name##_mod, \ 168 SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); \ 169 MODULE_DEPEND(name, dummynet, 3, 3, 3); 170#endif /* _DN_SCHED_H */ 171