diff options
| author | brakmo <brakmo@fb.com> | 2019-05-28 15:59:39 -0800 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2019-05-31 15:41:29 -0800 |
| commit | ffd81558d56c611b1e93f856c77f42046a2deab5 (patch) | |
| tree | f3c30120e3d5afdf625d155ea139b9851a2b2104 /samples | |
| parent | 956fe2190820df3a6ee530204e059da508159319 (diff) | |
| download | linux-stable-ffd81558d56c611b1e93f856c77f42046a2deab5.tar.gz linux-stable-ffd81558d56c611b1e93f856c77f42046a2deab5.tar.bz2 linux-stable-ffd81558d56c611b1e93f856c77f42046a2deab5.tar.xz linux-stable-ffd81558d56c611b1e93f856c77f42046a2deab5.zip | |
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: Lawrence Brakmo <brakmo@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'samples')
| -rwxr-xr-x | samples/bpf/do_hbm_test.sh | 10 | ||||
| -rw-r--r-- | samples/bpf/hbm.c | 18 | ||||
| -rw-r--r-- | samples/bpf/hbm.h | 3 | ||||
| -rw-r--r-- | samples/bpf/hbm_out_kern.c | 26 |
4 files changed, 45 insertions, 12 deletions
diff --git a/samples/bpf/do_hbm_test.sh b/samples/bpf/do_hbm_test.sh index 56c8b4115c95..e48b047d4646 100755 --- a/samples/bpf/do_hbm_test.sh +++ b/samples/bpf/do_hbm_test.sh | |||
| @@ -13,10 +13,10 @@ Usage() { | |||
| 13 | echo "egress or ingress bandwidht. It then uses iperf3 or netperf to create" | 13 | echo "egress or ingress bandwidht. It then uses iperf3 or netperf to create" |
| 14 | echo "loads. The output is the goodput in Mbps (unless -D was used)." | 14 | echo "loads. The output is the goodput in Mbps (unless -D was used)." |
| 15 | echo "" | 15 | echo "" |
| 16 | echo "USAGE: $name [out] [-b=<prog>|--bpf=<prog>] [-c=<cc>|--cc=<cc>] [-D]" | 16 | echo "USAGE: $name [out] [-b=<prog>|--bpf=<prog>] [-c=<cc>|--cc=<cc>]" |
| 17 | echo " [-d=<delay>|--delay=<delay>] [--debug] [-E]" | 17 | echo " [-D] [-d=<delay>|--delay=<delay>] [--debug] [-E]" |
| 18 | echo " [-f=<#flows>|--flows=<#flows>] [-h] [-i=<id>|--id=<id >]" | 18 | echo " [-f=<#flows>|--flows=<#flows>] [-h] [-i=<id>|--id=<id >]" |
| 19 | echo " [-l] [-N] [-p=<port>|--port=<port>] [-P]" | 19 | echo " [-l] [-N] [--no_cn] [-p=<port>|--port=<port>] [-P]" |
| 20 | echo " [-q=<qdisc>] [-R] [-s=<server>|--server=<server]" | 20 | echo " [-q=<qdisc>] [-R] [-s=<server>|--server=<server]" |
| 21 | echo " [-S|--stats] -t=<time>|--time=<time>] [-w] [cubic|dctcp]" | 21 | echo " [-S|--stats] -t=<time>|--time=<time>] [-w] [cubic|dctcp]" |
| 22 | echo " Where:" | 22 | echo " Where:" |
| @@ -33,6 +33,7 @@ Usage() { | |||
| 33 | echo " -f or --flows number of concurrent flows (default=1)" | 33 | echo " -f or --flows number of concurrent flows (default=1)" |
| 34 | echo " -i or --id cgroup id (an integer, default is 1)" | 34 | echo " -i or --id cgroup id (an integer, default is 1)" |
| 35 | echo " -N use netperf instead of iperf3" | 35 | echo " -N use netperf instead of iperf3" |
| 36 | echo " --no_cn Do not return CN notifications" | ||
| 36 | echo " -l do not limit flows using loopback" | 37 | echo " -l do not limit flows using loopback" |
| 37 | echo " -h Help" | 38 | echo " -h Help" |
| 38 | echo " -p or --port iperf3 port (default is 5201)" | 39 | echo " -p or --port iperf3 port (default is 5201)" |
| @@ -115,6 +116,9 @@ processArgs () { | |||
| 115 | -c=*|--cc=*) | 116 | -c=*|--cc=*) |
| 116 | cc="${i#*=}" | 117 | cc="${i#*=}" |
| 117 | ;; | 118 | ;; |
| 119 | --no_cn) | ||
| 120 | flags="$flags --no_cn" | ||
| 121 | ;; | ||
| 118 | --debug) | 122 | --debug) |
| 119 | flags="$flags -d" | 123 | flags="$flags -d" |
| 120 | debug_flag=1 | 124 | debug_flag=1 |
diff --git a/samples/bpf/hbm.c b/samples/bpf/hbm.c index a79828ab273f..c5629bae67ab 100644 --- a/samples/bpf/hbm.c +++ b/samples/bpf/hbm.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | * -l Also limit flows doing loopback | 16 | * -l Also limit flows doing loopback |
| 17 | * -n <#> To create cgroup \"/hbm#\" and attach prog | 17 | * -n <#> To create cgroup \"/hbm#\" and attach prog |
| 18 | * Default is /hbm1 | 18 | * Default is /hbm1 |
| 19 | * --no_cn Do not return cn notifications | ||
| 19 | * -r <rate> Rate limit in Mbps | 20 | * -r <rate> Rate limit in Mbps |
| 20 | * -s Get HBM stats (marked, dropped, etc.) | 21 | * -s Get HBM stats (marked, dropped, etc.) |
| 21 | * -t <time> Exit after specified seconds (default is 0) | 22 | * -t <time> Exit after specified seconds (default is 0) |
| @@ -42,6 +43,7 @@ | |||
| 42 | 43 | ||
| 43 | #include <linux/bpf.h> | 44 | #include <linux/bpf.h> |
| 44 | #include <bpf/bpf.h> | 45 | #include <bpf/bpf.h> |
| 46 | #include <getopt.h> | ||
| 45 | 47 | ||
| 46 | #include "bpf_load.h" | 48 | #include "bpf_load.h" |
| 47 | #include "bpf_rlimit.h" | 49 | #include "bpf_rlimit.h" |
| @@ -59,6 +61,7 @@ bool stats_flag; | |||
| 59 | bool loopback_flag; | 61 | bool loopback_flag; |
| 60 | bool debugFlag; | 62 | bool debugFlag; |
| 61 | bool work_conserving_flag; | 63 | bool work_conserving_flag; |
| 64 | bool no_cn_flag; | ||
| 62 | 65 | ||
| 63 | static void Usage(void); | 66 | static void Usage(void); |
| 64 | static void read_trace_pipe2(void); | 67 | static void read_trace_pipe2(void); |
| @@ -185,6 +188,7 @@ static int run_bpf_prog(char *prog, int cg_id) | |||
| 185 | qstats.rate = rate; | 188 | qstats.rate = rate; |
| 186 | qstats.stats = stats_flag ? 1 : 0; | 189 | qstats.stats = stats_flag ? 1 : 0; |
| 187 | qstats.loopback = loopback_flag ? 1 : 0; | 190 | qstats.loopback = loopback_flag ? 1 : 0; |
| 191 | qstats.no_cn = no_cn_flag ? 1 : 0; | ||
| 188 | if (bpf_map_update_elem(map_fd, &key, &qstats, BPF_ANY)) { | 192 | if (bpf_map_update_elem(map_fd, &key, &qstats, BPF_ANY)) { |
| 189 | printf("ERROR: Could not update map element\n"); | 193 | printf("ERROR: Could not update map element\n"); |
| 190 | goto err; | 194 | goto err; |
| @@ -366,14 +370,15 @@ static void Usage(void) | |||
| 366 | { | 370 | { |
| 367 | printf("This program loads a cgroup skb BPF program to enforce\n" | 371 | printf("This program loads a cgroup skb BPF program to enforce\n" |
| 368 | "cgroup output (egress) bandwidth limits.\n\n" | 372 | "cgroup output (egress) bandwidth limits.\n\n" |
| 369 | "USAGE: hbm [-o] [-d] [-l] [-n <id>] [-r <rate>] [-s]\n" | 373 | "USAGE: hbm [-o] [-d] [-l] [-n <id>] [--no_cn] [-r <rate>]\n" |
| 370 | " [-t <secs>] [-w] [-h] [prog]\n" | 374 | " [-s] [-t <secs>] [-w] [-h] [prog]\n" |
| 371 | " Where:\n" | 375 | " Where:\n" |
| 372 | " -o indicates egress direction (default)\n" | 376 | " -o indicates egress direction (default)\n" |
| 373 | " -d print BPF trace debug buffer\n" | 377 | " -d print BPF trace debug buffer\n" |
| 374 | " -l also limit flows using loopback\n" | 378 | " -l also limit flows using loopback\n" |
| 375 | " -n <#> to create cgroup \"/hbm#\" and attach prog\n" | 379 | " -n <#> to create cgroup \"/hbm#\" and attach prog\n" |
| 376 | " Default is /hbm1\n" | 380 | " Default is /hbm1\n" |
| 381 | " --no_cn disable CN notifcations\n" | ||
| 377 | " -r <rate> Rate in Mbps\n" | 382 | " -r <rate> Rate in Mbps\n" |
| 378 | " -s Update HBM stats\n" | 383 | " -s Update HBM stats\n" |
| 379 | " -t <time> Exit after specified seconds (default is 0)\n" | 384 | " -t <time> Exit after specified seconds (default is 0)\n" |
| @@ -393,9 +398,16 @@ int main(int argc, char **argv) | |||
| 393 | int k; | 398 | int k; |
| 394 | int cg_id = 1; | 399 | int cg_id = 1; |
| 395 | char *optstring = "iodln:r:st:wh"; | 400 | char *optstring = "iodln:r:st:wh"; |
| 401 | struct option loptions[] = { | ||
| 402 | {"no_cn", 0, NULL, 1}, | ||
| 403 | {NULL, 0, NULL, 0} | ||
| 404 | }; | ||
| 396 | 405 | ||
| 397 | while ((k = getopt(argc, argv, optstring)) != -1) { | 406 | while ((k = getopt_long(argc, argv, optstring, loptions, NULL)) != -1) { |
| 398 | switch (k) { | 407 | switch (k) { |
| 408 | case 1: | ||
| 409 | no_cn_flag = true; | ||
| 410 | break; | ||
| 399 | case'o': | 411 | case'o': |
| 400 | break; | 412 | break; |
| 401 | case 'd': | 413 | case 'd': |
diff --git a/samples/bpf/hbm.h b/samples/bpf/hbm.h index 518e8147d084..c08247cec2a7 100644 --- a/samples/bpf/hbm.h +++ b/samples/bpf/hbm.h | |||
| @@ -19,7 +19,8 @@ struct hbm_vqueue { | |||
| 19 | struct hbm_queue_stats { | 19 | struct hbm_queue_stats { |
| 20 | unsigned long rate; /* in Mbps*/ | 20 | unsigned long rate; /* in Mbps*/ |
| 21 | unsigned long stats:1, /* get HBM stats (marked, dropped,..) */ | 21 | unsigned long stats:1, /* get HBM stats (marked, dropped,..) */ |
| 22 | loopback:1; /* also limit flows using loopback */ | 22 | loopback:1, /* also limit flows using loopback */ |
| 23 | no_cn:1; /* do not use cn flags */ | ||
| 23 | unsigned long long pkts_marked; | 24 | unsigned long long pkts_marked; |
| 24 | unsigned long long bytes_marked; | 25 | unsigned long long bytes_marked; |
| 25 | unsigned long long pkts_dropped; | 26 | unsigned long long pkts_dropped; |
diff --git a/samples/bpf/hbm_out_kern.c b/samples/bpf/hbm_out_kern.c index f806863d0b79..fa3ea92e1564 100644 --- a/samples/bpf/hbm_out_kern.c +++ b/samples/bpf/hbm_out_kern.c | |||
| @@ -119,13 +119,16 @@ int _hbm_out_cg(struct __sk_buff *skb) | |||
| 119 | // Set flags (drop, congestion, cwr) | 119 | // Set flags (drop, congestion, cwr) |
| 120 | // Dropping => we are congested, so ignore congestion flag | 120 | // Dropping => we are congested, so ignore congestion flag |
| 121 | if (credit < -DROP_THRESH || | 121 | if (credit < -DROP_THRESH || |
| 122 | (len > LARGE_PKT_THRESH && | 122 | (len > LARGE_PKT_THRESH && credit < -LARGE_PKT_DROP_THRESH)) { |
| 123 | credit < -LARGE_PKT_DROP_THRESH)) { | 123 | // Very congested, set drop packet |
| 124 | // Very congested, set drop flag | ||
| 125 | drop_flag = true; | 124 | drop_flag = true; |
| 125 | if (pkti.ecn) | ||
| 126 | congestion_flag = true; | ||
| 127 | else if (pkti.is_tcp) | ||
| 128 | cwr_flag = true; | ||
| 126 | } else if (credit < 0) { | 129 | } else if (credit < 0) { |
| 127 | // Congested, set congestion flag | 130 | // Congested, set congestion flag |
| 128 | if (pkti.ecn) { | 131 | if (pkti.ecn || pkti.is_tcp) { |
| 129 | if (credit < -MARK_THRESH) | 132 | if (credit < -MARK_THRESH) |
| 130 | congestion_flag = true; | 133 | congestion_flag = true; |
| 131 | else | 134 | else |
| @@ -137,7 +140,15 @@ int _hbm_out_cg(struct __sk_buff *skb) | |||
| 137 | 140 | ||
| 138 | if (congestion_flag) { | 141 | if (congestion_flag) { |
| 139 | if (!bpf_skb_ecn_set_ce(skb)) { | 142 | if (!bpf_skb_ecn_set_ce(skb)) { |
| 140 | if (len > LARGE_PKT_THRESH) { | 143 | if (pkti.is_tcp) { |
| 144 | unsigned int rand = bpf_get_prandom_u32(); | ||
| 145 | |||
| 146 | if (-credit >= MARK_THRESH + | ||
| 147 | (rand % MARK_REGION_SIZE)) { | ||
| 148 | // Do congestion control | ||
| 149 | cwr_flag = true; | ||
| 150 | } | ||
| 151 | } else if (len > LARGE_PKT_THRESH) { | ||
| 141 | // Problem if too many small packets? | 152 | // Problem if too many small packets? |
| 142 | drop_flag = true; | 153 | drop_flag = true; |
| 143 | } | 154 | } |
| @@ -146,12 +157,17 @@ int _hbm_out_cg(struct __sk_buff *skb) | |||
| 146 | 157 | ||
| 147 | if (drop_flag) | 158 | if (drop_flag) |
| 148 | rv = DROP_PKT; | 159 | rv = DROP_PKT; |
| 160 | if (qsp != NULL) | ||
| 161 | if (qsp->no_cn) | ||
| 162 | cwr_flag = false; | ||
| 149 | 163 | ||
| 150 | hbm_update_stats(qsp, len, curtime, congestion_flag, drop_flag); | 164 | hbm_update_stats(qsp, len, curtime, congestion_flag, drop_flag); |
| 151 | 165 | ||
| 152 | if (rv == DROP_PKT) | 166 | if (rv == DROP_PKT) |
| 153 | __sync_add_and_fetch(&(qdp->credit), len); | 167 | __sync_add_and_fetch(&(qdp->credit), len); |
| 154 | 168 | ||
| 169 | if (cwr_flag) | ||
| 170 | rv |= 2; | ||
| 155 | return rv; | 171 | return rv; |
| 156 | } | 172 | } |
| 157 | char _license[] SEC("license") = "GPL"; | 173 | char _license[] SEC("license") = "GPL"; |
