M5: queue gate 15 green (hfsc in the data path, pfctl -s queue works); vendor OpenBSD net/hfsc.h + net/fq_codel.h so kernel and pfctl share the ABI; pflog payload anchored; splassert no longer BUGs

This commit is contained in:
lgcosta committed 2026-11-12 03:10:46 -03:00
1 parent 4bade69cf9
commit 90c51f43fc
46 files changed
+502 -126

No files matched your search

+51
View File
@@ -0,0 +1,51 @@
/* $OpenBSD: fq_codel.h,v 1.4 2020/06/18 23:29:59 dlg Exp $ */
/*
* Copyright (c) 2017 Mike Belopuhov
*
* 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.
*/
#ifndef _NET_FQ_CODEL_H_
#define _NET_FQ_CODEL_H_
/* compatible with hfsc_pktcntr */
struct fqcodel_pktcntr {
uint64_t packets;
uint64_t bytes;
};
struct fqcodel_stats {
struct fqcodel_pktcntr xmit_cnt;
struct fqcodel_pktcntr drop_cnt;
uint32_t qlength;
uint32_t qlimit;
uint32_t flows;
uint32_t _unused; /* padding */
uint32_t target;
uint32_t interval;
/* the values below are used to calculate standard deviation */
uint64_t delaysum; /* sum of delays, us */
uint64_t delaysumsq;/* sum of squared delays, us */
};
#ifdef _KERNEL
extern const struct ifq_ops * const ifq_fqcodel_ops;
extern const struct pfq_ops * const pfq_fqcodel_ops;
#endif /* _KERNEL */
#endif /* _NET_FQ_CODEL_H_ */
+122
View File
@@ -0,0 +1,122 @@
/* $OpenBSD: hfsc.h,v 1.15 2026/03/19 14:59:05 sthen Exp $ */
/*
* Copyright (c) 2012-2013 Henning Brauer <henning@openbsd.org>
* Copyright (c) 1997-1999 Carnegie Mellon University. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation is hereby granted (including for commercial or
* for-profit use), provided that both the copyright notice and this
* permission notice appear in all copies of the software, derivative
* works, or modified versions, and any portions thereof.
*
* THIS SOFTWARE IS EXPERIMENTAL AND IS KNOWN TO HAVE BUGS, SOME OF
* WHICH MAY HAVE SERIOUS CONSEQUENCES. CARNEGIE MELLON PROVIDES THIS
* SOFTWARE IN ITS ``AS IS'' CONDITION, AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* Carnegie Mellon encourages (but does not require) users of this
* software to return any improvements or extensions that they make,
* and to grant Carnegie Mellon the rights to redistribute these
* changes without encumbrance.
*/
#ifndef _HFSC_H_
#define _HFSC_H_
/* hfsc class flags */
#define HFSC_DEFAULTCLASS 0x1000 /* default class */
struct hfsc_pktcntr {
u_int64_t packets;
u_int64_t bytes;
};
#define PKTCNTR_INC(cntr, len) \
do { (cntr)->packets++; (cntr)->bytes += len; } while (0)
struct hfsc_sc {
u_int64_t m1; /* slope of the first segment in bits/sec */
u_int64_t m2; /* slope of the second segment in bits/sec */
u_int d; /* the x-projection of the first segment in msec */
};
/* special class handles */
#define HFSC_ROOT_CLASS 0x10000
#define HFSC_DEFAULT_CLASSES 64
#define HFSC_MAX_CLASSES 65535
/* service curve types */
#define HFSC_REALTIMESC 1
#define HFSC_LINKSHARINGSC 2
#define HFSC_UPPERLIMITSC 4
#define HFSC_DEFAULTSC (HFSC_REALTIMESC|HFSC_LINKSHARINGSC)
struct hfsc_class_stats {
struct hfsc_pktcntr xmit_cnt;
struct hfsc_pktcntr drop_cnt;
u_int qlength;
u_int qlimit;
u_int period;
u_int class_id;
u_int32_t class_handle;
struct hfsc_sc rsc;
struct hfsc_sc fsc;
struct hfsc_sc usc; /* upper limit service curve */
u_int64_t total; /* total work in bytes */
u_int64_t cumul; /* cumulative work in bytes
done by real-time criteria */
u_int64_t d; /* deadline */
u_int64_t e; /* eligible time */
u_int64_t vt; /* virtual time */
u_int64_t f; /* fit time for upper-limit */
/* info helpful for debugging */
u_int64_t initvt; /* init virtual time */
u_int64_t vtoff; /* cl_vt_ipoff */
u_int64_t cvtmax; /* cl_maxvt */
u_int64_t myf; /* cl_myf */
u_int64_t cfmin; /* cl_mincf */
u_int64_t cvtmin; /* cl_mincvt */
u_int64_t myfadj; /* cl_myfadj */
u_int64_t vtadj; /* cl_vtadj */
u_int64_t cur_time;
u_int32_t machclk_freq;
u_int vtperiod; /* vt period sequence no */
u_int parentperiod; /* parent's vt period seqno */
int nactive; /* number of active children */
/* red and rio related info */
int qtype;
/* struct redstats red[3]; */
};
#ifdef _KERNEL
struct ifnet;
struct ifqueue;
struct pf_queuespec;
struct hfsc_if;
extern const struct ifq_ops * const ifq_hfsc_ops;
extern const struct pfq_ops * const pfq_hfsc_ops;
#define HFSC_ENABLED(ifq) ((ifq)->ifq_ops == ifq_hfsc_ops)
#define HFSC_DEFAULT_QLIMIT 50
void hfsc_initialize(void);
#endif /* _KERNEL */
#endif /* _HFSC_H_ */
+17 -69
View File
@@ -1214,62 +1214,18 @@ struct pfk_pflog_stat {
/*
* Pieces the staged scheduler back ends (fq_codel(4)/hfsc(4) ports) need from
* OpenBSD <net/if_var.h>, <net/if_fq_codel.h> and <net/if_hfsc.h>.
* Scheduler back-end ABI: the very headers OpenBSD ships (net/hfsc.h,
* net/fq_codel.h), vendored into the port so that pfctl and pf.ko agree on the
* stats layouts and on the class-handle/service-curve constants. (Hand-rolled
* approximations of these structs made DIOCGETQSTATS fail with EINVAL, because
* pfctl's sizeof(struct hfsc_class_stats) did not match the kernel's.)
*/
#ifndef nsecuptime
#define nsecuptime() getnsecuptime()
#endif
struct fqcodel_pktcntr { uint64_t packets; uint64_t bytes; };
struct hfsc_pktcntr { uint64_t packets; uint64_t bytes; };
struct fqcodel_stats {
struct fqcodel_pktcntr xmit_cnt;
struct fqcodel_pktcntr drop_cnt;
uint32_t target, interval, tc_interval_drop;
uint32_t rcvtime, mtu, qlimit, qlength;
uint64_t delaysum, delaysumsq;
uint8_t ecn, limit, flows, lscroll, flags;
};
/* ifq scheduler hand-off (see pfsrc/ifq.c): enter returns the scheduler's
* queue when it owns the interface queue, NULL otherwise. */
void *ifq_q_enter(struct ifqueue *, const struct ifq_ops *);
void ifq_q_leave(struct ifqueue *, void *);
int pfk_ifq_transmit(struct ifqueue *, struct mbuf *);
int pf_kifq_input(struct pfk_ifnet *, struct mbuf *);
/*
* OpenBSD <net/if_hfsc.h> pieces the staged hfsc(4) back end needs.
* PFLINUX: the port keeps the BSD scheduler sources verbatim, so the
* user-visible service curve, the class-stats record and the class-table
* limits live here instead of in a separate kernel header.
*/
struct hfsc_sc { /* user-supplied service curve */
u_int64_t m1; /* slope1 (bytes/sec) */
u_int64_t d; /* ordinate of the knee (us) */
u_int64_t m2; /* slope2 (bytes/sec) */
};
struct hfsc_class_stats {
u_int class_id;
u_int32_t class_handle;
struct hfsc_sc rsc, fsc, usc;
u_int64_t total, cumul;
u_int64_t d, e, vt, f;
u_int64_t initvt, vtperiod, parentperiod;
int nactive;
u_int64_t vtoff, cvtmax, myf, cfmin, cvtmin, myfadj, vtadj;
u_int period;
struct hfsc_pktcntr xmit_cnt, drop_cnt;
u_int64_t cur_time;
u_int64_t machclk_freq;
int qlength;
int qlimit;
int qtype;
};
#include <net/hfsc.h>
#include <net/fq_codel.h>
/* OpenBSD's global nanoseconds-per-clocktick (HFSC_CLK_PER_TICK). The port
* has no clock_rate machinery, so derive it from the kernel's HZ. */
@@ -1277,18 +1233,13 @@ struct hfsc_class_stats {
#define tick_nsec (1000000000LL / HZ)
#endif
/*
* Class-handle namespace. pf queue ids are u_int16_t, so the root class gets
* a high bit that can never collide with a queue handle (a collision made
* hfsc_pf_addqueue() see the root class as a duplicate and refuse the queue
* with EBUSY). HFSC_DEFAULTCLASS must equal PFQS_DEFAULT because hfsc.c
* receives the pf queue flags verbatim.
*/
#define HFSC_ROOT_CLASS 0x80000000u
#define HFSC_DEFAULTCLASS 0x1000
#define HFSC_MAX_CLASSES 64
#define HFSC_DEFAULT_CLASSES 8
#define HFSC_DEFAULT_QLIMIT 1000
/* ifq scheduler hand-off (see pfsrc/ifq.c): enter returns the scheduler's
* queue state when it owns the interface queue, NULL otherwise. */
void *ifq_q_enter(struct ifqueue *, const struct ifq_ops *);
void ifq_q_leave(struct ifqueue *, void *);
int pfk_ifq_transmit(struct ifqueue *, struct mbuf *);
int pf_kifq_input(struct pfk_ifnet *, struct mbuf *);
/*
* PFLINUX notes on the scheduler back ends:
@@ -1299,16 +1250,13 @@ struct hfsc_class_stats {
* are kept as markers of the critical regions.
* - KERNEL_ASSERT_LOCKED(): the schedulers are only reached from ifq/pf paths
* that already hold the queue mutex; asserted structurally, not by spl.
* - HFSC_ENABLED(): the scheduler owns the interface queue once it attached
* its private state through ifq_q_enter().
* - HFSC_ENABLED(), PKTCNTR_INC(), the class-handle constants and the stats
* layouts all come from the vendored net/hfsc.h / net/fq_codel.h above, so
* kernel and pfctl cannot drift apart.
*/
#define splnet() 0
#define splx(s) ((void)(s))
#define KERNEL_ASSERT_LOCKED() do { } while (0)
#define HFSC_ENABLED(_ifq) ((_ifq)->ifq_q != NULL)
#define PKTCNTR_INC(_c, _len) do { (_c)->packets++; (_c)->bytes += (_len); } \
while (0)
#endif /* _PFK_H */