CHROMIUM: net: sched: Adaptive Rate Liming Qdisc
Adaptive Rate Limiting Qdisc (ARL) is designed for home routers to
eliminate bufferbloat at upstream CPE (Cable/DSL) modem. It prevents
a standing queue from forming at the upstream node by limit egress
throughput to match the available upstream bandwidth. ARL does not
use a statically preconfigured limit for its rate limiting. Instead,
it passively measures the latency of the TCP connctions on its egress
link in realtime and throttles the rate when the minimuim latency of
all connections is seen to increase, which indicates the presence of
excessive queue at the upstream device.
ARL can be applied as root qdisc for WAN interface to prevent upstream
bufferbloat at the CPE modem. Queue is then managed locally at the
router, by applying another qdisc such as fq_codel as child qdisc.
This is a port from chromeos-3.18 to chromeos-4.14-gw of CL:1121778
(ported from commit cee41c3dd7f50e0605368402c1625863ba278216)
Note changes introduced as part of Linux-3.18 -> 4.14 porting...
* Removed usage of nla_put_u64() [deprecated by Linux
commit 50225243 ("netlink: kill nla_put_u64()")], replaced with
nla_put_u64_64bit() [introduced by Linux
commit 73520786 ("libnl: add nla_put_u64_64bit() helper")] that
forces 64bit alignment of attribute. This also required definition
of TCA_ARL_PAD attribute used for alignment pad.
* Removed usage of out-of-line struct ewma [deprecated by Linux
commit f4e774f5 ("average: remove out-of-line implementation")]
replaced with static / inline macro [introduced by Linux commit
commit 2377799c ("average: provide macro to create static
EWMA")] and adapted to change in 'factor' parameter to 'precision'
[introduced by Linux commit eb1e011a ("average: change to
declare precision, not factor")]. The old 'weight' parameter of 8
remains unchanged, just renamed 'weight_rcp'. The old 'factor'
parameter of 8 translates to 3 bits 'precision'.
* Adapt to changes in kernel nanosecond timer APIs, ktime (and
ktime_t) are now simple signed 64bit value rather than a union
type [Linux commit 2456e855 ("ktime: Get rid of the union")].
* The 'zone' parameter passed into nf_conntrack_find_get() is no
longer an integer identifier
[Linux commit 308ac914 ("netfilter: nf_conntrack: push zone
object into functions")], a pointer to the 'nf_ct_zone_dflt' global
const object is now required.
* Removed all references to NF_CT_ASSERT() macro. The nf_conn
'timeout' field checked was never actually referenced within the
ARL code, the 'timeout.data' pointer was eliminated by conntrack
change that switched from using kernel timer to simple timestamp
[Linux commit f330a7fd ("netfilter: conntrack: get rid of
conntrack timer")], and the macro has now been totally deprecated
[Linux commit 9efdb14f ("net: Remove CONFIG_NETFILTER_DEBUG and
_ASSERT() macros.")].
* Remove nf_ct_is_untracked() check, the UNTRACKED state was
deprecated [Linux commit cc41c84b ("netfilter: kill the fake
untracked conntrack objects")] and then the API was completely
removed [Linux commit ab8bc7ed ("netfilter: remove
nf_ct_is_untracked")].
* Adapt to changes in Qdisc_class_ops:
- graft(): Replaced function body with call to qdisc_replace(),
this appears to be what all the supported Qdisc have migrated
to.
- get()/put(): APIs were deprecated
[Linux commit 143976ce ("net_sched: remove tc class reference
counting")], new find() API is introduced and basically identical
to old get().
* Adapt to changes in Qdisc_ops:
- enqueue(): Accepts new packets 'to_free' list, and use
qdisc_drop() rather than qdisc_reshape_fail() when packet
cannot be forwarded. gso_segment() helper function now also
utilizes packets 'to_free' list and qdisc_tree_reduce_backlog()
rather than qdisc_tree_decrease_qlen() to update queue length
accounting.
- dequeue(): Removed call to qdisc_unthrottled(), generic throttled
management was deprecated [Linux commit 45f50bed ("net_sched:
remove generic throttled management")].
- drop(): Deprecated [Linux commit a09ceb0e ("sched: remove
qdisc->drop")].
- change(): Added call to qdisc_hash_add() after default FIFO child
Qdisc is created and when adjusting queue length accounting
utilize qdisc_tree_reduce_backlog() rather than
qdisc_tree_decrease_qlen(). This is based on coding practices
observed in other supported Qdisc (e.g. sch_tbf, sch_prio).
Note changes introduced as part of 64bit porting...
* Added explicit cast (unsigned long) for first parameter of clamp()
when 'lo'/'hi' are 'UL' constants. clamp() strongly enforces type
equality at compile time. On 64bit architecture the first parameter
(2 * minmax_get() / 1000L) (i.e. int * u32 * long) results in
'signed long' which doesn't match the 'unsigned long' second
parameter type.
BUG=b:138685581
TEST=Latency test with heavy upstream traffic.
Cq-Depend: chromium:1727770, chromium:1730603
Change-Id: I727e4737ba45b8136e70643f159534cf7d06739e
Signed-off-by:
Danny J. Mitzel <mitzel@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1731583
Tested-by:
Danny Mitzel <mitzel@google.com>
Commit-Ready: Danny Mitzel <mitzel@google.com>
Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org>
Reviewed-by:
Kan Yan <kyan@chromium.org>
Loading
Please sign in to comment