Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/altq altq, cbq: treat time in nanoseconds



details:   https://anonhg.NetBSD.org/src/rev/aa8179353825
branches:  trunk
changeset: 1022476:aa8179353825
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Wed Jul 21 06:41:22 2021 +0000

description:
altq, cbq: treat time in nanoseconds

Time granularity in microseconds is sometimes not enough to provide
accurate bandwidth control; actual bandwidth on a capped class
can exceed its limit considerably in some cases.

Treating time in nanoseconds requires the following changes:
- Use timespec instead of timeval
- Use nanotime(9) instead of microtime(9)
- Change the type of some variables, especially *idle, to long

diffstat:

 sys/altq/altq_cbq.h     |   10 ++--
 sys/altq/altq_rmclass.c |  109 ++++++++++++++++++++++++-----------------------
 sys/altq/altq_rmclass.h |   66 +++++++++++------------------
 3 files changed, 85 insertions(+), 100 deletions(-)

diffs (truncated from 518 to 300 lines):

diff -r 4f1762014690 -r aa8179353825 sys/altq/altq_cbq.h
--- a/sys/altq/altq_cbq.h       Wed Jul 21 06:38:57 2021 +0000
+++ b/sys/altq/altq_cbq.h       Wed Jul 21 06:41:22 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: altq_cbq.h,v 1.9 2021/07/21 06:33:30 ozaki-r Exp $     */
+/*     $NetBSD: altq_cbq.h,v 1.10 2021/07/21 06:41:22 ozaki-r Exp $    */
 /*     $KAME: altq_cbq.h,v 1.12 2003/10/03 05:05:15 kjc Exp $  */
 
 /*
@@ -81,15 +81,15 @@
 
        /* other static class parameters useful for debugging */
        int             priority;
-       int             maxidle;
-       int             minidle;
-       int             offtime;
+       long            maxidle;
+       long            minidle;
+       long            offtime;
        int             qmax;
        u_long          ps_per_byte;
        int             wrr_allot;
 
        int             qcnt;           /* # packets in queue */
-       int             avgidle;
+       long            avgidle;
 
        /* red and rio related info */
        int             qtype;
diff -r 4f1762014690 -r aa8179353825 sys/altq/altq_rmclass.c
--- a/sys/altq/altq_rmclass.c   Wed Jul 21 06:38:57 2021 +0000
+++ b/sys/altq/altq_rmclass.c   Wed Jul 21 06:41:22 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: altq_rmclass.c,v 1.25 2021/07/21 06:33:30 ozaki-r Exp $        */
+/*     $NetBSD: altq_rmclass.c,v 1.26 2021/07/21 06:41:22 ozaki-r Exp $        */
 /*     $KAME: altq_rmclass.c,v 1.19 2005/04/13 03:44:25 suz Exp $      */
 
 /*
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: altq_rmclass.c,v 1.25 2021/07/21 06:33:30 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: altq_rmclass.c,v 1.26 2021/07/21 06:41:22 ozaki-r Exp $");
 
 /* #ident "@(#)rm_class.c  1.48     97/12/05 SMI" */
 
@@ -86,7 +86,7 @@
  * Local routines.
  */
 
-static int     rmc_satisfied(struct rm_class *, struct timeval *);
+static int     rmc_satisfied(struct rm_class *, struct timespec *);
 static void    rmc_wrr_set_weights(struct rm_ifdat *);
 static void    rmc_depth_compute(struct rm_class *);
 static void    rmc_depth_recompute(rm_class_t *);
@@ -99,8 +99,8 @@
 static mbuf_t  *_rmc_getq(rm_class_t *);
 static mbuf_t  *_rmc_pollq(rm_class_t *);
 
-static int     rmc_under_limit(struct rm_class *, struct timeval *);
-static void    rmc_tl_satisfied(struct rm_ifdat *, struct timeval *);
+static int     rmc_under_limit(struct rm_class *, struct timespec *);
+static void    rmc_tl_satisfied(struct rm_ifdat *, struct timespec *);
 static void    rmc_drop_action(struct rm_class *);
 static void    rmc_restart(struct rm_class *);
 static void    rmc_root_overlimit(struct rm_class *, struct rm_class *);
@@ -253,18 +253,18 @@
        cl->flags_ = flags;
 
 #if 1 /* minidle is also scaled in ALTQ */
-       cl->minidle_ = (minidle * (int)PSEC_TO_NSEC(psecPerByte)) / 8;
+       cl->minidle_ = ((long)minidle * (long)psecPerByte) / 8;
        if (cl->minidle_ > 0)
                cl->minidle_ = 0;
 #else
        cl->minidle_ = minidle;
 #endif
-       cl->maxidle_ = (maxidle * PSEC_TO_NSEC(psecPerByte)) / 8;
+       cl->maxidle_ = ((long)maxidle * (long)psecPerByte) / 8;
        if (cl->maxidle_ == 0)
                cl->maxidle_ = 1;
 #if 1 /* offtime is also scaled in ALTQ */
        cl->avgidle_ = cl->maxidle_;
-       cl->offtime_ = ((offtime * PSEC_TO_NSEC(psecPerByte)) / 8) >> RM_FILTER_GAIN;
+       cl->offtime_ = (((long)offtime * (long)psecPerByte) / 8) >> RM_FILTER_GAIN;
        if (cl->offtime_ == 0)
                cl->offtime_ = 1;
 #else
@@ -365,18 +365,18 @@
        qlimit(cl->q_) = maxq;
 
 #if 1 /* minidle is also scaled in ALTQ */
-       cl->minidle_ = (minidle * PSEC_TO_NSEC(psecPerByte)) / 8;
+       cl->minidle_ = ((long)minidle * (long)psecPerByte) / 8;
        if (cl->minidle_ > 0)
                cl->minidle_ = 0;
 #else
        cl->minidle_ = minidle;
 #endif
-       cl->maxidle_ = (maxidle * PSEC_TO_NSEC(psecPerByte)) / 8;
+       cl->maxidle_ = ((long)maxidle * (long)psecPerByte) / 8;
        if (cl->maxidle_ == 0)
                cl->maxidle_ = 1;
 #if 1 /* offtime is also scaled in ALTQ */
        cl->avgidle_ = cl->maxidle_;
-       cl->offtime_ = ((offtime * PSEC_TO_NSEC(psecPerByte)) / 8) >> RM_FILTER_GAIN;
+       cl->offtime_ = (((long)offtime * (long)psecPerByte) / 8) >> RM_FILTER_GAIN;
        if (cl->offtime_ == 0)
                cl->offtime_ = 1;
 #else
@@ -748,14 +748,14 @@
 int
 rmc_queue_packet(struct rm_class *cl, mbuf_t *m)
 {
-       struct timeval   now;
+       struct timespec  now;
        struct rm_ifdat *ifd = cl->ifdat_;
        int              cpri = cl->pri_;
        int              is_empty = qempty(cl->q_);
 
        RM_GETTIME(now);
        if (ifd->cutoff_ > 0) {
-               if (TV_LT(&cl->undertime_, &now)) {
+               if (TS_LT(&cl->undertime_, &now)) {
                        if (ifd->cutoff_ > cl->depth_)
                                ifd->cutoff_ = cl->depth_;
                        CBQTRACE(rmc_queue_packet, 'ffoc', cl->depth_);
@@ -771,7 +771,7 @@
 
                        while (borrow != NULL &&
                               borrow->depth_ < ifd->cutoff_) {
-                               if (TV_LT(&borrow->undertime_, &now)) {
+                               if (TS_LT(&borrow->undertime_, &now)) {
                                        ifd->cutoff_ = borrow->depth_;
                                        CBQTRACE(rmc_queue_packet, 'ffob', ifd->cutoff_);
                                        break;
@@ -781,7 +781,7 @@
                }
 #else /* !ALTQ */
                else if ((ifd->cutoff_ > 1) && cl->borrow_) {
-                       if (TV_LT(&cl->borrow_->undertime_, &now)) {
+                       if (TS_LT(&cl->borrow_->undertime_, &now)) {
                                ifd->cutoff_ = cl->borrow_->depth_;
                                CBQTRACE(rmc_queue_packet, 'ffob',
                                         cl->borrow_->depth_);
@@ -809,12 +809,12 @@
 
 /*
  * void
- * rmc_tl_satisfied(struct rm_ifdat *ifd, struct timeval *now) - Check all
+ * rmc_tl_satisfied(struct rm_ifdat *ifd, struct timespec *now) - Check all
  *     classes to see if there are satified.
  */
 
 static void
-rmc_tl_satisfied(struct rm_ifdat *ifd, struct timeval *now)
+rmc_tl_satisfied(struct rm_ifdat *ifd, struct timespec *now)
 {
        int              i;
        rm_class_t      *p, *bp;
@@ -840,13 +840,13 @@
  */
 
 static int
-rmc_satisfied(struct rm_class *cl, struct timeval *now)
+rmc_satisfied(struct rm_class *cl, struct timespec *now)
 {
        rm_class_t      *p;
 
        if (cl == NULL)
                return (1);
-       if (TV_LT(now, &cl->undertime_))
+       if (TS_LT(now, &cl->undertime_))
                return (1);
        if (cl->depth_ == 0) {
                if (!cl->sleeping_ && (qlen(cl->q_) > cl->qthresh_))
@@ -873,7 +873,7 @@
  */
 
 static int
-rmc_under_limit(struct rm_class *cl, struct timeval *now)
+rmc_under_limit(struct rm_class *cl, struct timespec *now)
 {
        rm_class_t      *p = cl;
        rm_class_t      *top;
@@ -888,7 +888,7 @@
                return (1);
 
        if (cl->sleeping_) {
-               if (TV_LT(now, &cl->undertime_))
+               if (TS_LT(now, &cl->undertime_))
                        return (0);
 
                CALLOUT_STOP(&cl->callout_);
@@ -898,7 +898,7 @@
        }
 
        top = NULL;
-       while (cl->undertime_.tv_sec && TV_LT(now, &cl->undertime_)) {
+       while (cl->undertime_.tv_sec && TS_LT(now, &cl->undertime_)) {
                if (((cl = cl->borrow_) == NULL) ||
                    (cl->depth_ > ifd->cutoff_)) {
 #ifdef ADJUST_CUTOFF
@@ -961,7 +961,7 @@
        u_int            deficit;
        int              cpri;
        mbuf_t          *m;
-       struct timeval   now;
+       struct timespec  now;
 
        RM_GETTIME(now);
 
@@ -1116,7 +1116,7 @@
        mbuf_t          *m;
        int              cpri;
        struct rm_class *cl, *first = NULL;
-       struct timeval   now;
+       struct timespec  now;
 
        RM_GETTIME(now);
 
@@ -1212,7 +1212,7 @@
 
 /*
  * mbuf_t *
- * rmc_dequeue_next(struct rm_ifdat *ifd, struct timeval *now) - this function
+ * rmc_dequeue_next(struct rm_ifdat *ifd, struct timespec *now) - this function
  *     is invoked by the packet driver to get the next packet to be
  *     dequeued and output on the link.  If WRR is enabled, then the
  *     WRR dequeue next routine will determine the next packet to sent.
@@ -1253,12 +1253,12 @@
 void
 rmc_update_class_util(struct rm_ifdat *ifd)
 {
-       int              idle, avgidle, pktlen;
-       u_long           pkt_time;
-       int              tidle;
+       long             idle, avgidle, pktlen;
+       long             pkt_time;
+       long             tidle;
        rm_class_t      *cl, *cl0, *borrowed;
        rm_class_t      *borrows;
-       struct timeval  *nowp;
+       struct timespec *nowp;
 
        /*
         * Get the most recent completed class.
@@ -1267,7 +1267,7 @@
                return;
 
        cl0 = cl;
-       pktlen = ifd->curlen_[ifd->qo_];
+       pktlen = (long)ifd->curlen_[ifd->qo_];
        borrowed = ifd->borrowed_[ifd->qo_];
        borrows = borrowed;
 
@@ -1286,13 +1286,13 @@
        nowp = &ifd->now_[ifd->qo_];
        /* get pkt_time (for link) in usec */
 #if 1  /* use approximation */
-       pkt_time = (u_long)ifd->curlen_[ifd->qo_] * ifd->ps_per_byte_;
-       pkt_time = PSEC_TO_USEC(pkt_time);
+       pkt_time = (long)ifd->curlen_[ifd->qo_] * (long)ifd->ps_per_byte_;
+       pkt_time = PSEC_TO_NSEC(pkt_time);
 #else
        pkt_time = ifd->curlen_[ifd->qo_] * ifd->ns_per_byte_ / 1000;
 #endif
 #if 1 /* ALTQ4PPP */
-       if (TV_LT(nowp, &ifd->ifnow_)) {
+       if (TS_LT(nowp, &ifd->ifnow_)) {
                int iftime;
 
                /*
@@ -1301,36 +1301,36 @@
                 * data compression or the interface speed is set to
                 * a much lower value.
                 */
-               TV_DELTA(&ifd->ifnow_, nowp, iftime);
+               TS_DELTA(&ifd->ifnow_, nowp, iftime);
                if (iftime+pkt_time < ifd->maxiftime_) {
-                       TV_ADD_DELTA(&ifd->ifnow_, pkt_time, &ifd->ifnow_);
+                       TS_ADD_DELTA(&ifd->ifnow_, pkt_time, &ifd->ifnow_);
                } else {
-                       TV_ADD_DELTA(nowp, ifd->maxiftime_, &ifd->ifnow_);
+                       TS_ADD_DELTA(nowp, ifd->maxiftime_, &ifd->ifnow_);
                }
        } else {
-               TV_ADD_DELTA(nowp, pkt_time, &ifd->ifnow_);
+               TS_ADD_DELTA(nowp, pkt_time, &ifd->ifnow_);
        }
 #else
-       if (TV_LT(nowp, &ifd->ifnow_)) {
-               TV_ADD_DELTA(&ifd->ifnow_, pkt_time, &ifd->ifnow_);
+       if (TS_LT(nowp, &ifd->ifnow_)) {
+               TS_ADD_DELTA(&ifd->ifnow_, pkt_time, &ifd->ifnow_);
        } else {
-               TV_ADD_DELTA(nowp, pkt_time, &ifd->ifnow_);
+               TS_ADD_DELTA(nowp, pkt_time, &ifd->ifnow_);
        }



Home | Main Index | Thread Index | Old Index