summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/net/altq/altq_subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/net/altq/altq_subr.c')
-rw-r--r--freebsd/sys/net/altq/altq_subr.c58
1 files changed, 24 insertions, 34 deletions
diff --git a/freebsd/sys/net/altq/altq_subr.c b/freebsd/sys/net/altq/altq_subr.c
index 47a353fc..6da36129 100644
--- a/freebsd/sys/net/altq/altq_subr.c
+++ b/freebsd/sys/net/altq/altq_subr.c
@@ -294,12 +294,12 @@ altq_assert(file, line, failedexpr)
/*
* internal representation of token bucket parameters
- * rate: byte_per_unittime << 32
- * (((bits_per_sec) / 8) << 32) / machclk_freq
- * depth: byte << 32
+ * rate: (byte_per_unittime << TBR_SHIFT) / machclk_freq
+ * (((bits_per_sec) / 8) << TBR_SHIFT) / machclk_freq
+ * depth: byte << TBR_SHIFT
*
*/
-#define TBR_SHIFT 32
+#define TBR_SHIFT 29
#define TBR_SCALE(x) ((int64_t)(x) << TBR_SHIFT)
#define TBR_UNSCALE(x) ((x) >> TBR_SHIFT)
@@ -396,7 +396,20 @@ tbr_set(ifq, profile)
if (tbr->tbr_rate > 0)
tbr->tbr_filluptime = tbr->tbr_depth / tbr->tbr_rate;
else
- tbr->tbr_filluptime = 0xffffffffffffffffLL;
+ tbr->tbr_filluptime = LLONG_MAX;
+ /*
+ * The longest time between tbr_dequeue() calls will be about 1
+ * system tick, as the callout that drives it is scheduled once per
+ * tick. The refill-time detection logic in tbr_dequeue() can only
+ * properly detect the passage of up to LLONG_MAX machclk ticks.
+ * Therefore, in order for this logic to function properly in the
+ * extreme case, the maximum value of tbr_filluptime should be
+ * LLONG_MAX less one system tick's worth of machclk ticks less
+ * some additional slop factor (here one more system tick's worth
+ * of machclk ticks).
+ */
+ if (tbr->tbr_filluptime > (LLONG_MAX - 2 * machclk_per_tick))
+ tbr->tbr_filluptime = LLONG_MAX - 2 * machclk_per_tick;
tbr->tbr_token = tbr->tbr_depth;
tbr->tbr_last = read_machclk();
tbr->tbr_lastop = ALTDQ_REMOVE;
@@ -458,29 +471,6 @@ tbr_timeout(arg)
}
/*
- * get token bucket regulator profile
- */
-int
-tbr_get(ifq, profile)
- struct ifaltq *ifq;
- struct tb_profile *profile;
-{
- struct tb_regulator *tbr;
-
- IFQ_LOCK(ifq);
- if ((tbr = ifq->altq_tbr) == NULL) {
- profile->rate = 0;
- profile->depth = 0;
- } else {
- profile->rate =
- (u_int)TBR_UNSCALE(tbr->tbr_rate * 8 * machclk_freq);
- profile->depth = (u_int)TBR_UNSCALE(tbr->tbr_depth);
- }
- IFQ_UNLOCK(ifq);
- return (0);
-}
-
-/*
* attach a discipline to the interface. if one already exists, it is
* overridden.
* Locking is done in the discipline specific attach functions. Basically
@@ -735,34 +725,34 @@ altq_remove_queue(struct pf_altq *a)
* copyout operations, also it is not yet clear which lock to use.
*/
int
-altq_getqstats(struct pf_altq *a, void *ubuf, int *nbytes)
+altq_getqstats(struct pf_altq *a, void *ubuf, int *nbytes, int version)
{
int error = 0;
switch (a->scheduler) {
#ifdef ALTQ_CBQ
case ALTQT_CBQ:
- error = cbq_getqstats(a, ubuf, nbytes);
+ error = cbq_getqstats(a, ubuf, nbytes, version);
break;
#endif
#ifdef ALTQ_PRIQ
case ALTQT_PRIQ:
- error = priq_getqstats(a, ubuf, nbytes);
+ error = priq_getqstats(a, ubuf, nbytes, version);
break;
#endif
#ifdef ALTQ_HFSC
case ALTQT_HFSC:
- error = hfsc_getqstats(a, ubuf, nbytes);
+ error = hfsc_getqstats(a, ubuf, nbytes, version);
break;
#endif
#ifdef ALTQ_FAIRQ
case ALTQT_FAIRQ:
- error = fairq_getqstats(a, ubuf, nbytes);
+ error = fairq_getqstats(a, ubuf, nbytes, version);
break;
#endif
#ifdef ALTQ_CODEL
case ALTQT_CODEL:
- error = codel_getqstats(a, ubuf, nbytes);
+ error = codel_getqstats(a, ubuf, nbytes, version);
break;
#endif
default: