186d7f5d3SJohn Marino /* $KAME: altq_hfsc.h,v 1.12 2003/12/05 05:40:46 kjc Exp $ */ 286d7f5d3SJohn Marino /* $DragonFly: src/sys/net/altq/altq_hfsc.h,v 1.1 2005/02/11 22:25:57 joerg Exp $ */ 386d7f5d3SJohn Marino 486d7f5d3SJohn Marino /* 586d7f5d3SJohn Marino * Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved. 686d7f5d3SJohn Marino * 786d7f5d3SJohn Marino * Permission to use, copy, modify, and distribute this software and 886d7f5d3SJohn Marino * its documentation is hereby granted (including for commercial or 986d7f5d3SJohn Marino * for-profit use), provided that both the copyright notice and this 1086d7f5d3SJohn Marino * permission notice appear in all copies of the software, derivative 1186d7f5d3SJohn Marino * works, or modified versions, and any portions thereof. 1286d7f5d3SJohn Marino * 1386d7f5d3SJohn Marino * THIS SOFTWARE IS EXPERIMENTAL AND IS KNOWN TO HAVE BUGS, SOME OF 1486d7f5d3SJohn Marino * WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON PROVIDES THIS 1586d7f5d3SJohn Marino * SOFTWARE IN ITS ``AS IS'' CONDITION, AND ANY EXPRESS OR IMPLIED 1686d7f5d3SJohn Marino * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1786d7f5d3SJohn Marino * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 1886d7f5d3SJohn Marino * DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE 1986d7f5d3SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2086d7f5d3SJohn Marino * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 2186d7f5d3SJohn Marino * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 2286d7f5d3SJohn Marino * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 2386d7f5d3SJohn Marino * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2486d7f5d3SJohn Marino * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 2586d7f5d3SJohn Marino * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 2686d7f5d3SJohn Marino * DAMAGE. 2786d7f5d3SJohn Marino * 2886d7f5d3SJohn Marino * Carnegie Mellon encourages (but does not require) users of this 2986d7f5d3SJohn Marino * software to return any improvements or extensions that they make, 3086d7f5d3SJohn Marino * and to grant Carnegie Mellon the rights to redistribute these 3186d7f5d3SJohn Marino * changes without encumbrance. 3286d7f5d3SJohn Marino */ 3386d7f5d3SJohn Marino #ifndef _ALTQ_ALTQ_HFSC_H_ 3486d7f5d3SJohn Marino #define _ALTQ_ALTQ_HFSC_H_ 3586d7f5d3SJohn Marino 3686d7f5d3SJohn Marino #include <net/altq/altq.h> 3786d7f5d3SJohn Marino #include <net/altq/altq_classq.h> 3886d7f5d3SJohn Marino #include <net/altq/altq_red.h> 3986d7f5d3SJohn Marino #include <net/altq/altq_rio.h> 4086d7f5d3SJohn Marino 4186d7f5d3SJohn Marino struct service_curve { 4286d7f5d3SJohn Marino u_int m1; /* slope of the first segment in bits/sec */ 4386d7f5d3SJohn Marino u_int d; /* the x-projection of the first segment in msec */ 4486d7f5d3SJohn Marino u_int m2; /* slope of the second segment in bits/sec */ 4586d7f5d3SJohn Marino }; 4686d7f5d3SJohn Marino 4786d7f5d3SJohn Marino /* special class handles */ 4886d7f5d3SJohn Marino #define HFSC_NULLCLASS_HANDLE 0 4986d7f5d3SJohn Marino #define HFSC_MAX_CLASSES 64 5086d7f5d3SJohn Marino 5186d7f5d3SJohn Marino /* hfsc class flags */ 5286d7f5d3SJohn Marino #define HFCF_RED 0x0001 /* use RED */ 5386d7f5d3SJohn Marino #define HFCF_ECN 0x0002 /* use RED/ECN */ 5486d7f5d3SJohn Marino #define HFCF_RIO 0x0004 /* use RIO */ 5586d7f5d3SJohn Marino #define HFCF_CLEARDSCP 0x0010 /* clear diffserv codepoint */ 5686d7f5d3SJohn Marino #define HFCF_DEFAULTCLASS 0x1000 /* default class */ 5786d7f5d3SJohn Marino 5886d7f5d3SJohn Marino /* service curve types */ 5986d7f5d3SJohn Marino #define HFSC_REALTIMESC 1 6086d7f5d3SJohn Marino #define HFSC_LINKSHARINGSC 2 6186d7f5d3SJohn Marino #define HFSC_UPPERLIMITSC 4 6286d7f5d3SJohn Marino #define HFSC_DEFAULTSC (HFSC_REALTIMESC|HFSC_LINKSHARINGSC) 6386d7f5d3SJohn Marino 6486d7f5d3SJohn Marino struct hfsc_classstats { 6586d7f5d3SJohn Marino u_int class_id; 6686d7f5d3SJohn Marino uint32_t class_handle; 6786d7f5d3SJohn Marino struct service_curve rsc; 6886d7f5d3SJohn Marino struct service_curve fsc; 6986d7f5d3SJohn Marino struct service_curve usc; /* upper limit service curve */ 7086d7f5d3SJohn Marino 7186d7f5d3SJohn Marino uint64_t total; /* total work in bytes */ 7286d7f5d3SJohn Marino uint64_t cumul; /* cumulative work in bytes 7386d7f5d3SJohn Marino done by real-time criteria */ 7486d7f5d3SJohn Marino uint64_t d; /* deadline */ 7586d7f5d3SJohn Marino uint64_t e; /* eligible time */ 7686d7f5d3SJohn Marino uint64_t vt; /* virtual time */ 7786d7f5d3SJohn Marino uint64_t f; /* fit time for upper-limit */ 7886d7f5d3SJohn Marino 7986d7f5d3SJohn Marino /* info helpful for debugging */ 8086d7f5d3SJohn Marino uint64_t initvt; /* init virtual time */ 8186d7f5d3SJohn Marino uint64_t vtoff; /* cl_vt_ipoff */ 8286d7f5d3SJohn Marino uint64_t cvtmax; /* cl_maxvt */ 8386d7f5d3SJohn Marino uint64_t myf; /* cl_myf */ 8486d7f5d3SJohn Marino uint64_t cfmin; /* cl_mincf */ 8586d7f5d3SJohn Marino uint64_t cvtmin; /* cl_mincvt */ 8686d7f5d3SJohn Marino uint64_t myfadj; /* cl_myfadj */ 8786d7f5d3SJohn Marino uint64_t vtadj; /* cl_vtadj */ 8886d7f5d3SJohn Marino uint64_t cur_time; 8986d7f5d3SJohn Marino uint32_t machclk_freq; 9086d7f5d3SJohn Marino 9186d7f5d3SJohn Marino u_int qlength; 9286d7f5d3SJohn Marino u_int qlimit; 9386d7f5d3SJohn Marino struct pktcntr xmit_cnt; 9486d7f5d3SJohn Marino struct pktcntr drop_cnt; 9586d7f5d3SJohn Marino u_int period; 9686d7f5d3SJohn Marino 9786d7f5d3SJohn Marino u_int vtperiod; /* vt period sequence no */ 9886d7f5d3SJohn Marino u_int parentperiod; /* parent's vt period seqno */ 9986d7f5d3SJohn Marino int nactive; /* number of active children */ 10086d7f5d3SJohn Marino 10186d7f5d3SJohn Marino /* red and rio related info */ 10286d7f5d3SJohn Marino int qtype; 10386d7f5d3SJohn Marino struct redstats red[3]; 10486d7f5d3SJohn Marino }; 10586d7f5d3SJohn Marino 10686d7f5d3SJohn Marino #ifdef _KERNEL 10786d7f5d3SJohn Marino /* 10886d7f5d3SJohn Marino * kernel internal service curve representation 10986d7f5d3SJohn Marino * coordinates are given by 64 bit unsigned integers. 11086d7f5d3SJohn Marino * x-axis: unit is clock count. for the intel x86 architecture, 11186d7f5d3SJohn Marino * the raw Pentium TSC (Timestamp Counter) value is used. 11286d7f5d3SJohn Marino * virtual time is also calculated in this time scale. 11386d7f5d3SJohn Marino * y-axis: unit is byte. 11486d7f5d3SJohn Marino * 11586d7f5d3SJohn Marino * the service curve parameters are converted to the internal 11686d7f5d3SJohn Marino * representation. 11786d7f5d3SJohn Marino * the slope values are scaled to avoid overflow. 11886d7f5d3SJohn Marino * the inverse slope values as well as the y-projection of the 1st 11986d7f5d3SJohn Marino * segment are kept in order to to avoid 64-bit divide operations 12086d7f5d3SJohn Marino * that are expensive on 32-bit architectures. 12186d7f5d3SJohn Marino * 12286d7f5d3SJohn Marino * note: Intel Pentium TSC never wraps around in several thousands of years. 12386d7f5d3SJohn Marino * x-axis doesn't wrap around for 1089 years with 1GHz clock. 12486d7f5d3SJohn Marino * y-axis doesn't wrap around for 4358 years with 1Gbps bandwidth. 12586d7f5d3SJohn Marino */ 12686d7f5d3SJohn Marino 12786d7f5d3SJohn Marino /* kernel internal representation of a service curve */ 12886d7f5d3SJohn Marino struct internal_sc { 12986d7f5d3SJohn Marino uint64_t sm1; /* scaled slope of the 1st segment */ 13086d7f5d3SJohn Marino uint64_t ism1; /* scaled inverse-slope of the 1st segment */ 13186d7f5d3SJohn Marino uint64_t dx; /* the x-projection of the 1st segment */ 13286d7f5d3SJohn Marino uint64_t dy; /* the y-projection of the 1st segment */ 13386d7f5d3SJohn Marino uint64_t sm2; /* scaled slope of the 2nd segment */ 13486d7f5d3SJohn Marino uint64_t ism2; /* scaled inverse-slope of the 2nd segment */ 13586d7f5d3SJohn Marino }; 13686d7f5d3SJohn Marino 13786d7f5d3SJohn Marino /* runtime service curve */ 13886d7f5d3SJohn Marino struct runtime_sc { 13986d7f5d3SJohn Marino uint64_t x; /* current starting position on x-axis */ 14086d7f5d3SJohn Marino uint64_t y; /* current starting position on x-axis */ 14186d7f5d3SJohn Marino uint64_t sm1; /* scaled slope of the 1st segment */ 14286d7f5d3SJohn Marino uint64_t ism1; /* scaled inverse-slope of the 1st segment */ 14386d7f5d3SJohn Marino uint64_t dx; /* the x-projection of the 1st segment */ 14486d7f5d3SJohn Marino uint64_t dy; /* the y-projection of the 1st segment */ 14586d7f5d3SJohn Marino uint64_t sm2; /* scaled slope of the 2nd segment */ 14686d7f5d3SJohn Marino uint64_t ism2; /* scaled inverse-slope of the 2nd segment */ 14786d7f5d3SJohn Marino }; 14886d7f5d3SJohn Marino 14986d7f5d3SJohn Marino /* for TAILQ based ellist and actlist implementation */ 15086d7f5d3SJohn Marino struct hfsc_class; 15186d7f5d3SJohn Marino typedef TAILQ_HEAD(_eligible, hfsc_class) ellist_t; 15286d7f5d3SJohn Marino typedef TAILQ_ENTRY(hfsc_class) elentry_t; 15386d7f5d3SJohn Marino typedef TAILQ_HEAD(_active, hfsc_class) actlist_t; 15486d7f5d3SJohn Marino typedef TAILQ_ENTRY(hfsc_class) actentry_t; 15586d7f5d3SJohn Marino #define ellist_first(s) TAILQ_FIRST(s) 15686d7f5d3SJohn Marino #define actlist_first(s) TAILQ_FIRST(s) 15786d7f5d3SJohn Marino #define actlist_last(s) TAILQ_LAST(s, _active) 15886d7f5d3SJohn Marino 15986d7f5d3SJohn Marino struct hfsc_class { 16086d7f5d3SJohn Marino u_int cl_id; /* class id (just for debug) */ 16186d7f5d3SJohn Marino uint32_t cl_handle; /* class handle */ 16286d7f5d3SJohn Marino struct hfsc_if *cl_hif; /* back pointer to struct hfsc_if */ 16386d7f5d3SJohn Marino int cl_flags; /* misc flags */ 16486d7f5d3SJohn Marino 16586d7f5d3SJohn Marino struct hfsc_class *cl_parent; /* parent class */ 16686d7f5d3SJohn Marino struct hfsc_class *cl_siblings; /* sibling classes */ 16786d7f5d3SJohn Marino struct hfsc_class *cl_children; /* child classes */ 16886d7f5d3SJohn Marino 16986d7f5d3SJohn Marino class_queue_t *cl_q; /* class queue structure */ 17086d7f5d3SJohn Marino struct red *cl_red; /* RED state */ 17186d7f5d3SJohn Marino struct altq_pktattr *cl_pktattr; /* saved header used by ECN */ 17286d7f5d3SJohn Marino 17386d7f5d3SJohn Marino uint64_t cl_total; /* total work in bytes */ 17486d7f5d3SJohn Marino uint64_t cl_cumul; /* cumulative work in bytes 17586d7f5d3SJohn Marino done by real-time criteria */ 17686d7f5d3SJohn Marino uint64_t cl_d; /* deadline */ 17786d7f5d3SJohn Marino uint64_t cl_e; /* eligible time */ 17886d7f5d3SJohn Marino uint64_t cl_vt; /* virtual time */ 17986d7f5d3SJohn Marino uint64_t cl_f; /* time when this class will fit for 18086d7f5d3SJohn Marino link-sharing, max(myf, cfmin) */ 18186d7f5d3SJohn Marino uint64_t cl_myf; /* my fit-time (as calculated from this 18286d7f5d3SJohn Marino class's own upperlimit curve) */ 18386d7f5d3SJohn Marino uint64_t cl_myfadj; /* my fit-time adjustment 18486d7f5d3SJohn Marino (to cancel history dependence) */ 18586d7f5d3SJohn Marino uint64_t cl_cfmin; /* earliest children's fit-time (used 18686d7f5d3SJohn Marino with cl_myf to obtain cl_f) */ 18786d7f5d3SJohn Marino uint64_t cl_cvtmin; /* minimal virtual time among the 18886d7f5d3SJohn Marino children fit for link-sharing 18986d7f5d3SJohn Marino (monotonic within a period) */ 19086d7f5d3SJohn Marino uint64_t cl_vtadj; /* intra-period cumulative vt 19186d7f5d3SJohn Marino adjustment */ 19286d7f5d3SJohn Marino uint64_t cl_vtoff; /* inter-period cumulative vt offset */ 19386d7f5d3SJohn Marino uint64_t cl_cvtmax; /* max child's vt in the last period */ 19486d7f5d3SJohn Marino 19586d7f5d3SJohn Marino uint64_t cl_initvt; /* init virtual time (for debugging) */ 19686d7f5d3SJohn Marino 19786d7f5d3SJohn Marino struct internal_sc *cl_rsc; /* internal real-time service curve */ 19886d7f5d3SJohn Marino struct internal_sc *cl_fsc; /* internal fair service curve */ 19986d7f5d3SJohn Marino struct internal_sc *cl_usc; /* internal upperlimit service curve */ 20086d7f5d3SJohn Marino struct runtime_sc cl_deadline; /* deadline curve */ 20186d7f5d3SJohn Marino struct runtime_sc cl_eligible; /* eligible curve */ 20286d7f5d3SJohn Marino struct runtime_sc cl_virtual; /* virtual curve */ 20386d7f5d3SJohn Marino struct runtime_sc cl_ulimit; /* upperlimit curve */ 20486d7f5d3SJohn Marino 20586d7f5d3SJohn Marino u_int cl_vtperiod; /* vt period sequence no */ 20686d7f5d3SJohn Marino u_int cl_parentperiod; /* parent's vt period seqno */ 20786d7f5d3SJohn Marino int cl_nactive; /* number of active children */ 20886d7f5d3SJohn Marino actlist_t *cl_actc; /* active children list */ 20986d7f5d3SJohn Marino 21086d7f5d3SJohn Marino actentry_t cl_actlist; /* active children list entry */ 21186d7f5d3SJohn Marino elentry_t cl_ellist; /* eligible list entry */ 21286d7f5d3SJohn Marino 21386d7f5d3SJohn Marino struct { 21486d7f5d3SJohn Marino struct pktcntr xmit_cnt; 21586d7f5d3SJohn Marino struct pktcntr drop_cnt; 21686d7f5d3SJohn Marino u_int period; 21786d7f5d3SJohn Marino } cl_stats; 21886d7f5d3SJohn Marino }; 21986d7f5d3SJohn Marino 22086d7f5d3SJohn Marino /* 22186d7f5d3SJohn Marino * hfsc interface state 22286d7f5d3SJohn Marino */ 22386d7f5d3SJohn Marino struct hfsc_if { 22486d7f5d3SJohn Marino struct hfsc_if *hif_next; /* interface state list */ 22586d7f5d3SJohn Marino struct ifaltq *hif_ifq; /* backpointer to ifaltq */ 22686d7f5d3SJohn Marino struct hfsc_class *hif_rootclass; /* root class */ 22786d7f5d3SJohn Marino struct hfsc_class *hif_defaultclass; /* default class */ 22886d7f5d3SJohn Marino struct hfsc_class *hif_class_tbl[HFSC_MAX_CLASSES]; 22986d7f5d3SJohn Marino struct hfsc_class *hif_pollcache; /* cache for poll operation */ 23086d7f5d3SJohn Marino 23186d7f5d3SJohn Marino u_int hif_classes; /* # of classes in the tree */ 23286d7f5d3SJohn Marino u_int hif_packets; /* # of packets in the tree */ 23386d7f5d3SJohn Marino u_int hif_classid; /* class id sequence number */ 23486d7f5d3SJohn Marino 23586d7f5d3SJohn Marino ellist_t *hif_eligible; /* eligible list */ 23686d7f5d3SJohn Marino }; 23786d7f5d3SJohn Marino 23886d7f5d3SJohn Marino #endif /* _KERNEL */ 23986d7f5d3SJohn Marino 24086d7f5d3SJohn Marino #endif /* _ALTQ_ALTQ_HFSC_H_ */ 241