diff --git a/include/netlink/utils.h b/include/netlink/utils.h index 4d7b969..502341a 100644 --- a/include/netlink/utils.h +++ b/include/netlink/utils.h @@ -56,6 +56,7 @@ extern long nl_prob2int(const char *); /* time translations */ extern int nl_get_user_hz(void); +extern int nl_get_psched_hz(void); extern uint32_t nl_us2ticks(uint32_t); extern uint32_t nl_ticks2us(uint32_t); extern int nl_str2msec(const char *, uint64_t *); diff --git a/lib/route/qdisc/htb.c b/lib/route/qdisc/htb.c index f1d0e75..4298580 100644 --- a/lib/route/qdisc/htb.c +++ b/lib/route/qdisc/htb.c @@ -86,9 +86,9 @@ 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(opts.buffer, + htb->ch_rbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.buffer), opts.rate.rate); - htb->ch_cbuffer = rtnl_tc_calc_bufsize(opts.cbuffer, + htb->ch_cbuffer = rtnl_tc_calc_bufsize(nl_ticks2us(opts.cbuffer), opts.ceil.rate); htb->ch_quantum = opts.quantum; htb->ch_level = opts.level; @@ -242,16 +242,16 @@ static int htb_class_msg_fill(struct rtnl_tc *tc, void *data, if (htb->ch_mask & SCH_HTB_HAS_RBUFFER) buffer = htb->ch_rbuffer; else - buffer = opts.rate.rate / nl_get_user_hz() + mtu; /* XXX */ + buffer = opts.rate.rate / nl_get_psched_hz() + mtu; /* XXX */ - opts.buffer = rtnl_tc_calc_txtime(buffer, opts.rate.rate); + opts.buffer = nl_us2ticks(rtnl_tc_calc_txtime(buffer, opts.rate.rate)); if (htb->ch_mask & SCH_HTB_HAS_CBUFFER) cbuffer = htb->ch_cbuffer; else - cbuffer = opts.ceil.rate / nl_get_user_hz() + mtu; /* XXX */ + cbuffer = opts.ceil.rate / nl_get_psched_hz() + mtu; /* XXX */ - opts.cbuffer = rtnl_tc_calc_txtime(cbuffer, opts.ceil.rate); + opts.cbuffer = nl_us2ticks(rtnl_tc_calc_txtime(cbuffer, opts.ceil.rate)); if (htb->ch_mask & SCH_HTB_HAS_QUANTUM) opts.quantum = htb->ch_quantum; diff --git a/lib/route/qdisc/tbf.c b/lib/route/qdisc/tbf.c index 8a6c400..81bd84c 100644 --- a/lib/route/qdisc/tbf.c +++ b/lib/route/qdisc/tbf.c @@ -290,7 +290,7 @@ void rtnl_qdisc_tbf_set_rate(struct rtnl_qdisc *qdisc, int rate, int bucket, tbf->qt_rate.rs_rate = rate; tbf->qt_rate_bucket = bucket; tbf->qt_rate.rs_cell_log = cell_log; - tbf->qt_rate_txtime = rtnl_tc_calc_txtime(bucket, rate); + tbf->qt_rate_txtime = nl_us2ticks(rtnl_tc_calc_txtime(bucket, rate)); tbf->qt_mask |= TBF_ATTR_RATE; } @@ -372,7 +372,7 @@ int rtnl_qdisc_tbf_set_peakrate(struct rtnl_qdisc *qdisc, int rate, int bucket, tbf->qt_peakrate.rs_rate = rate; tbf->qt_peakrate_bucket = bucket; tbf->qt_peakrate.rs_cell_log = cell_log; - tbf->qt_peakrate_txtime = rtnl_tc_calc_txtime(bucket, rate); + tbf->qt_peakrate_txtime = nl_us2ticks(rtnl_tc_calc_txtime(bucket, rate)); tbf->qt_mask |= TBF_ATTR_PEAKRATE; diff --git a/lib/route/tc.c b/lib/route/tc.c index 6826a05..6c72c15 100644 --- a/lib/route/tc.c +++ b/lib/route/tc.c @@ -710,7 +710,7 @@ int rtnl_tc_build_rate_table(struct rtnl_tc *tc, struct rtnl_ratespec *spec, for (i = 0; i < RTNL_TC_RTABLE_SIZE; i++) { size = adjust_size((i + 1) << cell_log, spec->rs_mpu, linktype); - dst[i] = rtnl_tc_calc_txtime(size, spec->rs_rate); + dst[i] = nl_us2ticks(rtnl_tc_calc_txtime(size, spec->rs_rate)); } spec->rs_cell_align = -1; diff --git a/lib/utils.c b/lib/utils.c index 36b6292..efb2cf4 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -359,12 +359,13 @@ long nl_prob2int(const char *str) * @{ */ -#ifdef USER_HZ -static uint32_t user_hz = USER_HZ; -#else -static uint32_t user_hz = 100; +#ifndef USER_HZ +#define USER_HZ 100 #endif +static uint32_t user_hz = USER_HZ; +static uint32_t psched_hz = USER_HZ; + static double ticks_per_usec = 1.0f; /* Retrieves the configured HZ and ticks/us value in the kernel. @@ -394,6 +395,8 @@ static void __init get_psched_settings(void) if (!got_hz) user_hz = sysconf(_SC_CLK_TCK); + psched_hz = user_hz; + if (getenv("TICKS_PER_USEC")) { double t = strtod(getenv("TICKS_PER_USEC"), NULL); ticks_per_usec = t; @@ -408,14 +411,16 @@ static void __init get_psched_settings(void) strncpy(name, "/proc/net/psched", sizeof(name) - 1); if ((fd = fopen(name, "r"))) { - uint32_t ns_per_usec, ns_per_tick; - /* the file contains 4 hexadecimals, but we just use - the first two of them */ - fscanf(fd, "%08x %08x", &ns_per_usec, &ns_per_tick); + uint32_t ns_per_usec, ns_per_tick, nom, denom; + + fscanf(fd, "%08x %08x %08x %08x", + &ns_per_usec, &ns_per_tick, &nom, &denom); ticks_per_usec = (double) ns_per_usec / (double) ns_per_tick; + if (nom == 1000000) + psched_hz = denom; fclose(fd); } @@ -431,6 +436,13 @@ int nl_get_user_hz(void) return user_hz; } +/** + * Return the value of packet scheduler HZ + */ +int nl_get_psched_hz(void) +{ + return psched_hz; +} /** * Convert micro seconds to ticks