Skip to content

Commit

Permalink
route/qdisc: merge branch 'd0u9/htb_64'
Browse files Browse the repository at this point in the history
  • Loading branch information
thom311 committed Sep 1, 2019
2 parents 2154891 + 03ee05d commit 2c862a6
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 62 deletions.
14 changes: 12 additions & 2 deletions include/netlink-private/netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ static inline void rtnl_copy_ratespec(struct rtnl_ratespec *dst,
dst->rs_overhead = src->overhead;
dst->rs_cell_align = src->cell_align;
dst->rs_mpu = src->mpu;
dst->rs_rate = src->rate;
dst->rs_rate64 = src->rate;
}

static inline void rtnl_rcopy_ratespec(struct tc_ratespec *dst,
Expand All @@ -196,7 +196,7 @@ static inline void rtnl_rcopy_ratespec(struct tc_ratespec *dst,
dst->overhead = src->rs_overhead;
dst->cell_align = src->rs_cell_align;
dst->mpu = src->rs_mpu;
dst->rate = src->rs_rate;
dst->rate = src->rs_rate64 > 0xFFFFFFFFull ? 0xFFFFFFFFull : (uint32_t) src->rs_rate64;
}

static inline const char *nl_cache_name(struct nl_cache *cache)
Expand Down Expand Up @@ -276,4 +276,14 @@ static inline void nl_write_unlock(pthread_rwlock_t *lock)
#define nl_write_unlock(LOCK) do { } while(0)
#endif

static inline int rtnl_tc_calc_txtime64(int bufsize, uint64_t rate)
{
return ((double) bufsize / (double) rate) * 1000000.0;
}

static inline int rtnl_tc_calc_bufsize64(int txtime, uint64_t rate)
{
return ((double) txtime * (double) rate) / 1000000.0;
}

#endif
4 changes: 2 additions & 2 deletions include/netlink-private/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -495,11 +495,11 @@ struct rtnl_neightbl

struct rtnl_ratespec
{
uint8_t rs_cell_log;
uint64_t rs_rate64;
uint16_t rs_overhead;
int16_t rs_cell_align;
uint16_t rs_mpu;
uint32_t rs_rate;
uint8_t rs_cell_log;
};

struct rtnl_tstats
Expand Down
15 changes: 11 additions & 4 deletions include/netlink/route/qdisc/htb.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,17 @@ extern int rtnl_htb_set_defcls(struct rtnl_qdisc *, uint32_t);

extern uint32_t rtnl_htb_get_prio(struct rtnl_class *);
extern int rtnl_htb_set_prio(struct rtnl_class *, uint32_t);
extern uint32_t rtnl_htb_get_rate(struct rtnl_class *);
extern int rtnl_htb_set_rate(struct rtnl_class *, uint32_t);
extern uint32_t rtnl_htb_get_ceil(struct rtnl_class *);
extern int rtnl_htb_set_ceil(struct rtnl_class *, uint32_t);

extern uint32_t rtnl_htb_get_rate(struct rtnl_class *);
extern int rtnl_htb_set_rate(struct rtnl_class *, uint32_t);
extern uint32_t rtnl_htb_get_ceil(struct rtnl_class *);
extern int rtnl_htb_set_ceil(struct rtnl_class *, uint32_t);

extern int rtnl_htb_get_rate64(struct rtnl_class *, uint64_t *);
extern int rtnl_htb_set_rate64(struct rtnl_class *, uint64_t);
extern int rtnl_htb_get_ceil64(struct rtnl_class *, uint64_t *);
extern int rtnl_htb_set_ceil64(struct rtnl_class *, uint64_t);

extern uint32_t rtnl_htb_get_rbuffer(struct rtnl_class *);
extern int rtnl_htb_set_rbuffer(struct rtnl_class *, uint32_t);
extern uint32_t rtnl_htb_get_cbuffer(struct rtnl_class *);
Expand Down
135 changes: 113 additions & 22 deletions lib/route/qdisc/htb.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
static struct nla_policy htb_policy[TCA_HTB_MAX+1] = {
[TCA_HTB_INIT] = { .minlen = sizeof(struct tc_htb_glob) },
[TCA_HTB_PARMS] = { .minlen = sizeof(struct tc_htb_opt) },
[TCA_HTB_RATE64] = { .minlen = sizeof(uint64_t) },
[TCA_HTB_CEIL64] = { .minlen = sizeof(uint64_t) },
};

static int htb_qdisc_msg_parser(struct rtnl_tc *tc, void *data)
Expand Down Expand Up @@ -86,10 +88,16 @@ static int htb_class_msg_parser(struct rtnl_tc *tc, void *data)
htb->ch_prio = opts.prio;
rtnl_copy_ratespec(&htb->ch_rate, &opts.rate);
rtnl_copy_ratespec(&htb->ch_ceil, &opts.ceil);
htb->ch_rbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.buffer),
opts.rate.rate);
htb->ch_cbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.cbuffer),
opts.ceil.rate);

if (tb[TCA_HTB_RATE64])
nla_memcpy(&htb->ch_rate.rs_rate64, tb[TCA_HTB_RATE64], sizeof(uint64_t));
if (tb[TCA_HTB_CEIL64])
nla_memcpy(&htb->ch_ceil.rs_rate64, tb[TCA_HTB_CEIL64], sizeof(uint64_t));

htb->ch_rbuffer = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.buffer),
htb->ch_rate.rs_rate64);
htb->ch_cbuffer = rtnl_tc_calc_bufsize64(nl_ticks2us(opts.cbuffer),
htb->ch_ceil.rs_rate64);
htb->ch_quantum = opts.quantum;
htb->ch_level = opts.level;

Expand Down Expand Up @@ -135,8 +143,8 @@ static void htb_class_dump_line(struct rtnl_tc *tc, void *data,
double r, rbit;
char *ru, *rubit;

r = nl_cancel_down_bytes(htb->ch_rate.rs_rate, &ru);
rbit = nl_cancel_down_bits(htb->ch_rate.rs_rate*8, &rubit);
r = nl_cancel_down_bytes(htb->ch_rate.rs_rate64, &ru);
rbit = nl_cancel_down_bits(htb->ch_rate.rs_rate64*8, &rubit);

nl_dump(p, " rate %.2f%s/s (%.0f%s) log %u",
r, ru, rbit, rubit, 1<<htb->ch_rate.rs_cell_log);
Expand All @@ -156,8 +164,8 @@ static void htb_class_dump_details(struct rtnl_tc *tc, void *data,
double r, rbit;
char *ru, *rubit;

r = nl_cancel_down_bytes(htb->ch_ceil.rs_rate, &ru);
rbit = nl_cancel_down_bits(htb->ch_ceil.rs_rate*8, &rubit);
r = nl_cancel_down_bytes(htb->ch_ceil.rs_rate64, &ru);
rbit = nl_cancel_down_bits(htb->ch_ceil.rs_rate64*8, &rubit);

nl_dump(p, " ceil %.2f%s/s (%.0f%s) log %u",
r, ru, rbit, rubit, 1<<htb->ch_ceil.rs_cell_log);
Expand Down Expand Up @@ -213,6 +221,8 @@ static int htb_class_msg_fill(struct rtnl_tc *tc, void *data,
uint32_t mtu, rtable[RTNL_TC_RTABLE_SIZE], ctable[RTNL_TC_RTABLE_SIZE];
struct tc_htb_opt opts;
int buffer, cbuffer;
uint64_t rate64;
uint64_t ceil64;

if (!htb || !(htb->ch_mask & SCH_HTB_HAS_RATE))
BUG();
Expand All @@ -227,36 +237,43 @@ static int htb_class_msg_fill(struct rtnl_tc *tc, void *data,

rtnl_tc_build_rate_table(tc, &htb->ch_rate, rtable);
rtnl_rcopy_ratespec(&opts.rate, &htb->ch_rate);
rate64 = htb->ch_rate.rs_rate64;

if (htb->ch_mask & SCH_HTB_HAS_CEIL) {
rtnl_tc_build_rate_table(tc, &htb->ch_ceil, ctable);
rtnl_rcopy_ratespec(&opts.ceil, &htb->ch_ceil);
ceil64 = htb->ch_ceil.rs_rate64;
} else {
/*
* If not set, configured rate is used as ceil, which implies
* no borrowing.
*/
memcpy(&opts.ceil, &opts.rate, sizeof(struct tc_ratespec));
ceil64 = rate64;
}

if (htb->ch_mask & SCH_HTB_HAS_RBUFFER)
buffer = htb->ch_rbuffer;
else
buffer = opts.rate.rate / nl_get_psched_hz() + mtu; /* XXX */
buffer = rate64 / nl_get_psched_hz() + mtu; /* XXX */

opts.buffer = nl_us2ticks(rtnl_tc_calc_txtime(buffer, opts.rate.rate));
opts.buffer = nl_us2ticks(rtnl_tc_calc_txtime64(buffer, rate64));

if (htb->ch_mask & SCH_HTB_HAS_CBUFFER)
cbuffer = htb->ch_cbuffer;
else
cbuffer = opts.ceil.rate / nl_get_psched_hz() + mtu; /* XXX */
cbuffer = ceil64 / nl_get_psched_hz() + mtu; /* XXX */

opts.cbuffer = nl_us2ticks(rtnl_tc_calc_txtime(cbuffer, opts.ceil.rate));
opts.cbuffer = nl_us2ticks(rtnl_tc_calc_txtime64(cbuffer, ceil64));

if (htb->ch_mask & SCH_HTB_HAS_QUANTUM)
opts.quantum = htb->ch_quantum;

NLA_PUT(msg, TCA_HTB_PARMS, sizeof(opts), &opts);
if (rate64 > 0xFFFFFFFFull)
NLA_PUT(msg, TCA_HTB_RATE64, sizeof(uint64_t), &rate64);
if (ceil64 > 0xFFFFFFFFull)
NLA_PUT(msg, TCA_HTB_CEIL64, sizeof(uint64_t), &ceil64);
NLA_PUT(msg, TCA_HTB_RTAB, sizeof(rtable), &rtable);
NLA_PUT(msg, TCA_HTB_CTAB, sizeof(ctable), &ctable);

Expand Down Expand Up @@ -383,16 +400,41 @@ int rtnl_htb_set_prio(struct rtnl_class *class, uint32_t prio)
* Return rate of HTB class
* @arg class htb class object
*
* @return Rate in bytes/s or 0 if unspecified.
* @return Rate in bytes/s or 0 if unspecified. If the value
* cannot be represented as 32 bit integer, (1<<32) is returned.
* Use rtnl_htb_get_rate64() instead.
*/
uint32_t rtnl_htb_get_rate(struct rtnl_class *class)
{
struct rtnl_htb_class *htb;

if ((htb = htb_class_data(class, NULL)) &&
(htb->ch_mask & SCH_HTB_HAS_RATE))
return htb->ch_rate.rs_rate;
if ( !(htb = htb_class_data(class, NULL))
|| !(htb->ch_mask & SCH_HTB_HAS_RATE))
return 0;

if (htb->ch_rate.rs_rate64 > 0xFFFFFFFFull)
return 0xFFFFFFFFull;

return htb->ch_rate.rs_rate64;
}

/**
* Return rate of HTB class
* @arg class htb class object
* @arg out_rate64 on success, the set rate.
*
* @return 0 on success or a negative error code.
*/
int rtnl_htb_get_rate64(struct rtnl_class *class, uint64_t *out_rate64)
{
struct rtnl_htb_class *htb;

if (!(htb = htb_class_data(class, NULL)))
return -NLE_INVAL;
if (!(htb->ch_mask & SCH_HTB_HAS_RATE))
return -NLE_NOATTR;

*out_rate64 = htb->ch_rate.rs_rate64;
return 0;
}

Expand All @@ -404,6 +446,18 @@ uint32_t rtnl_htb_get_rate(struct rtnl_class *class)
* @return 0 on success or a negative error code.
*/
int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
{
return rtnl_htb_set_rate64(class, rate);
}

/**
* Set rate of HTB class
* @arg class htb class object
* @arg rate new rate in bytes per second
*
* @return 0 on success or a negative error code.
*/
int rtnl_htb_set_rate64(struct rtnl_class *class, uint64_t rate)
{
struct rtnl_htb_class *htb;
int err;
Expand All @@ -412,7 +466,7 @@ int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
return err;

htb->ch_rate.rs_cell_log = UINT8_MAX; /* use default value */
htb->ch_rate.rs_rate = rate;
htb->ch_rate.rs_rate64 = rate;
htb->ch_mask |= SCH_HTB_HAS_RATE;

return 0;
Expand All @@ -422,16 +476,41 @@ int rtnl_htb_set_rate(struct rtnl_class *class, uint32_t rate)
* Return ceil rate of HTB class
* @arg class htb class object
*
* @return Ceil rate in bytes/s or 0 if unspecified
* @return Ceil rate in bytes/s or 0 if unspecified. If the value
* cannot be represented as 32 bit integer, (1<<32) is returned.
* Use rtnl_htb_get_ceil64() instead.
*/
uint32_t rtnl_htb_get_ceil(struct rtnl_class *class)
{
struct rtnl_htb_class *htb;

if ((htb = htb_class_data(class, NULL)) &&
(htb->ch_mask & SCH_HTB_HAS_CEIL))
return htb->ch_ceil.rs_rate;
if ( !(htb = htb_class_data(class, NULL))
|| !(htb->ch_mask & SCH_HTB_HAS_CEIL))
return 0;

if (htb->ch_ceil.rs_rate64 > 0xFFFFFFFFull)
return 0xFFFFFFFFull;

return htb->ch_ceil.rs_rate64;
}

/**
* Return ceil rate of HTB class
* @arg class htb class object
* @arg out_ceil64 on success, the set ceil value.
*
* @return 0 on success or a negative error code.
*/
int rtnl_htb_get_ceil64(struct rtnl_class *class, uint64_t *out_ceil64)
{
struct rtnl_htb_class *htb;

if (!(htb = htb_class_data(class, NULL)))
return -NLE_INVAL;
if (!(htb->ch_mask & SCH_HTB_HAS_CEIL))
return -NLE_NOATTR;

*out_ceil64 = htb->ch_ceil.rs_rate64;
return 0;
}

Expand All @@ -443,6 +522,18 @@ uint32_t rtnl_htb_get_ceil(struct rtnl_class *class)
* @return 0 on success or a negative error code.
*/
int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil)
{
return rtnl_htb_set_ceil64(class, ceil);
}

/**
* Set ceil rate of HTB class
* @arg class htb class object
* @arg ceil64 new ceil rate number of bytes per second
*
* @return 0 on success or a negative error code.
*/
int rtnl_htb_set_ceil64(struct rtnl_class *class, uint64_t ceil64)
{
struct rtnl_htb_class *htb;
int err;
Expand All @@ -451,7 +542,7 @@ int rtnl_htb_set_ceil(struct rtnl_class *class, uint32_t ceil)
return err;

htb->ch_ceil.rs_cell_log = UINT8_MAX; /* use default value */
htb->ch_ceil.rs_rate = ceil;
htb->ch_ceil.rs_rate64 = ceil64;
htb->ch_mask |= SCH_HTB_HAS_CEIL;

return 0;
Expand Down
Loading

0 comments on commit 2c862a6

Please sign in to comment.