Commit ffd81558 authored by brakmo's avatar brakmo Committed by Alexei Starovoitov

bpf: Add cn support to hbm_out_kern.c

Update hbm_out_kern.c to support returning cn notifications.
Also updates relevant files to allow disabling cn notifications.
Signed-off-by: default avatarLawrence Brakmo <brakmo@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 956fe219
...@@ -13,10 +13,10 @@ Usage() { ...@@ -13,10 +13,10 @@ Usage() {
echo "egress or ingress bandwidht. It then uses iperf3 or netperf to create" echo "egress or ingress bandwidht. It then uses iperf3 or netperf to create"
echo "loads. The output is the goodput in Mbps (unless -D was used)." echo "loads. The output is the goodput in Mbps (unless -D was used)."
echo "" echo ""
echo "USAGE: $name [out] [-b=<prog>|--bpf=<prog>] [-c=<cc>|--cc=<cc>] [-D]" echo "USAGE: $name [out] [-b=<prog>|--bpf=<prog>] [-c=<cc>|--cc=<cc>]"
echo " [-d=<delay>|--delay=<delay>] [--debug] [-E]" echo " [-D] [-d=<delay>|--delay=<delay>] [--debug] [-E]"
echo " [-f=<#flows>|--flows=<#flows>] [-h] [-i=<id>|--id=<id >]" echo " [-f=<#flows>|--flows=<#flows>] [-h] [-i=<id>|--id=<id >]"
echo " [-l] [-N] [-p=<port>|--port=<port>] [-P]" echo " [-l] [-N] [--no_cn] [-p=<port>|--port=<port>] [-P]"
echo " [-q=<qdisc>] [-R] [-s=<server>|--server=<server]" echo " [-q=<qdisc>] [-R] [-s=<server>|--server=<server]"
echo " [-S|--stats] -t=<time>|--time=<time>] [-w] [cubic|dctcp]" echo " [-S|--stats] -t=<time>|--time=<time>] [-w] [cubic|dctcp]"
echo " Where:" echo " Where:"
...@@ -33,6 +33,7 @@ Usage() { ...@@ -33,6 +33,7 @@ Usage() {
echo " -f or --flows number of concurrent flows (default=1)" echo " -f or --flows number of concurrent flows (default=1)"
echo " -i or --id cgroup id (an integer, default is 1)" echo " -i or --id cgroup id (an integer, default is 1)"
echo " -N use netperf instead of iperf3" echo " -N use netperf instead of iperf3"
echo " --no_cn Do not return CN notifications"
echo " -l do not limit flows using loopback" echo " -l do not limit flows using loopback"
echo " -h Help" echo " -h Help"
echo " -p or --port iperf3 port (default is 5201)" echo " -p or --port iperf3 port (default is 5201)"
...@@ -115,6 +116,9 @@ processArgs () { ...@@ -115,6 +116,9 @@ processArgs () {
-c=*|--cc=*) -c=*|--cc=*)
cc="${i#*=}" cc="${i#*=}"
;; ;;
--no_cn)
flags="$flags --no_cn"
;;
--debug) --debug)
flags="$flags -d" flags="$flags -d"
debug_flag=1 debug_flag=1
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
* -l Also limit flows doing loopback * -l Also limit flows doing loopback
* -n <#> To create cgroup \"/hbm#\" and attach prog * -n <#> To create cgroup \"/hbm#\" and attach prog
* Default is /hbm1 * Default is /hbm1
* --no_cn Do not return cn notifications
* -r <rate> Rate limit in Mbps * -r <rate> Rate limit in Mbps
* -s Get HBM stats (marked, dropped, etc.) * -s Get HBM stats (marked, dropped, etc.)
* -t <time> Exit after specified seconds (default is 0) * -t <time> Exit after specified seconds (default is 0)
...@@ -42,6 +43,7 @@ ...@@ -42,6 +43,7 @@
#include <linux/bpf.h> #include <linux/bpf.h>
#include <bpf/bpf.h> #include <bpf/bpf.h>
#include <getopt.h>
#include "bpf_load.h" #include "bpf_load.h"
#include "bpf_rlimit.h" #include "bpf_rlimit.h"
...@@ -59,6 +61,7 @@ bool stats_flag; ...@@ -59,6 +61,7 @@ bool stats_flag;
bool loopback_flag; bool loopback_flag;
bool debugFlag; bool debugFlag;
bool work_conserving_flag; bool work_conserving_flag;
bool no_cn_flag;
static void Usage(void); static void Usage(void);
static void read_trace_pipe2(void); static void read_trace_pipe2(void);
...@@ -185,6 +188,7 @@ static int run_bpf_prog(char *prog, int cg_id) ...@@ -185,6 +188,7 @@ static int run_bpf_prog(char *prog, int cg_id)
qstats.rate = rate; qstats.rate = rate;
qstats.stats = stats_flag ? 1 : 0; qstats.stats = stats_flag ? 1 : 0;
qstats.loopback = loopback_flag ? 1 : 0; qstats.loopback = loopback_flag ? 1 : 0;
qstats.no_cn = no_cn_flag ? 1 : 0;
if (bpf_map_update_elem(map_fd, &key, &qstats, BPF_ANY)) { if (bpf_map_update_elem(map_fd, &key, &qstats, BPF_ANY)) {
printf("ERROR: Could not update map element\n"); printf("ERROR: Could not update map element\n");
goto err; goto err;
...@@ -366,14 +370,15 @@ static void Usage(void) ...@@ -366,14 +370,15 @@ static void Usage(void)
{ {
printf("This program loads a cgroup skb BPF program to enforce\n" printf("This program loads a cgroup skb BPF program to enforce\n"
"cgroup output (egress) bandwidth limits.\n\n" "cgroup output (egress) bandwidth limits.\n\n"
"USAGE: hbm [-o] [-d] [-l] [-n <id>] [-r <rate>] [-s]\n" "USAGE: hbm [-o] [-d] [-l] [-n <id>] [--no_cn] [-r <rate>]\n"
" [-t <secs>] [-w] [-h] [prog]\n" " [-s] [-t <secs>] [-w] [-h] [prog]\n"
" Where:\n" " Where:\n"
" -o indicates egress direction (default)\n" " -o indicates egress direction (default)\n"
" -d print BPF trace debug buffer\n" " -d print BPF trace debug buffer\n"
" -l also limit flows using loopback\n" " -l also limit flows using loopback\n"
" -n <#> to create cgroup \"/hbm#\" and attach prog\n" " -n <#> to create cgroup \"/hbm#\" and attach prog\n"
" Default is /hbm1\n" " Default is /hbm1\n"
" --no_cn disable CN notifcations\n"
" -r <rate> Rate in Mbps\n" " -r <rate> Rate in Mbps\n"
" -s Update HBM stats\n" " -s Update HBM stats\n"
" -t <time> Exit after specified seconds (default is 0)\n" " -t <time> Exit after specified seconds (default is 0)\n"
...@@ -393,9 +398,16 @@ int main(int argc, char **argv) ...@@ -393,9 +398,16 @@ int main(int argc, char **argv)
int k; int k;
int cg_id = 1; int cg_id = 1;
char *optstring = "iodln:r:st:wh"; char *optstring = "iodln:r:st:wh";
struct option loptions[] = {
{"no_cn", 0, NULL, 1},
{NULL, 0, NULL, 0}
};
while ((k = getopt(argc, argv, optstring)) != -1) { while ((k = getopt_long(argc, argv, optstring, loptions, NULL)) != -1) {
switch (k) { switch (k) {
case 1:
no_cn_flag = true;
break;
case'o': case'o':
break; break;
case 'd': case 'd':
......
...@@ -19,7 +19,8 @@ struct hbm_vqueue { ...@@ -19,7 +19,8 @@ struct hbm_vqueue {
struct hbm_queue_stats { struct hbm_queue_stats {
unsigned long rate; /* in Mbps*/ unsigned long rate; /* in Mbps*/
unsigned long stats:1, /* get HBM stats (marked, dropped,..) */ unsigned long stats:1, /* get HBM stats (marked, dropped,..) */
loopback:1; /* also limit flows using loopback */ loopback:1, /* also limit flows using loopback */
no_cn:1; /* do not use cn flags */
unsigned long long pkts_marked; unsigned long long pkts_marked;
unsigned long long bytes_marked; unsigned long long bytes_marked;
unsigned long long pkts_dropped; unsigned long long pkts_dropped;
......
...@@ -119,13 +119,16 @@ int _hbm_out_cg(struct __sk_buff *skb) ...@@ -119,13 +119,16 @@ int _hbm_out_cg(struct __sk_buff *skb)
// Set flags (drop, congestion, cwr) // Set flags (drop, congestion, cwr)
// Dropping => we are congested, so ignore congestion flag // Dropping => we are congested, so ignore congestion flag
if (credit < -DROP_THRESH || if (credit < -DROP_THRESH ||
(len > LARGE_PKT_THRESH && (len > LARGE_PKT_THRESH && credit < -LARGE_PKT_DROP_THRESH)) {
credit < -LARGE_PKT_DROP_THRESH)) { // Very congested, set drop packet
// Very congested, set drop flag
drop_flag = true; drop_flag = true;
if (pkti.ecn)
congestion_flag = true;
else if (pkti.is_tcp)
cwr_flag = true;
} else if (credit < 0) { } else if (credit < 0) {
// Congested, set congestion flag // Congested, set congestion flag
if (pkti.ecn) { if (pkti.ecn || pkti.is_tcp) {
if (credit < -MARK_THRESH) if (credit < -MARK_THRESH)
congestion_flag = true; congestion_flag = true;
else else
...@@ -137,7 +140,15 @@ int _hbm_out_cg(struct __sk_buff *skb) ...@@ -137,7 +140,15 @@ int _hbm_out_cg(struct __sk_buff *skb)
if (congestion_flag) { if (congestion_flag) {
if (!bpf_skb_ecn_set_ce(skb)) { if (!bpf_skb_ecn_set_ce(skb)) {
if (len > LARGE_PKT_THRESH) { if (pkti.is_tcp) {
unsigned int rand = bpf_get_prandom_u32();
if (-credit >= MARK_THRESH +
(rand % MARK_REGION_SIZE)) {
// Do congestion control
cwr_flag = true;
}
} else if (len > LARGE_PKT_THRESH) {
// Problem if too many small packets? // Problem if too many small packets?
drop_flag = true; drop_flag = true;
} }
...@@ -146,12 +157,17 @@ int _hbm_out_cg(struct __sk_buff *skb) ...@@ -146,12 +157,17 @@ int _hbm_out_cg(struct __sk_buff *skb)
if (drop_flag) if (drop_flag)
rv = DROP_PKT; rv = DROP_PKT;
if (qsp != NULL)
if (qsp->no_cn)
cwr_flag = false;
hbm_update_stats(qsp, len, curtime, congestion_flag, drop_flag); hbm_update_stats(qsp, len, curtime, congestion_flag, drop_flag);
if (rv == DROP_PKT) if (rv == DROP_PKT)
__sync_add_and_fetch(&(qdp->credit), len); __sync_add_and_fetch(&(qdp->credit), len);
if (cwr_flag)
rv |= 2;
return rv; return rv;
} }
char _license[] SEC("license") = "GPL"; char _license[] SEC("license") = "GPL";
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment