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

bpf: Add more stats to HBM

Adds more stats to HBM, including average cwnd and rtt of all TCP
flows, percents of packets that are ecn ce marked and distribution
of return values.
Signed-off-by: default avatarLawrence Brakmo <brakmo@fb.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent ffd81558
...@@ -316,6 +316,14 @@ static int run_bpf_prog(char *prog, int cg_id) ...@@ -316,6 +316,14 @@ static int run_bpf_prog(char *prog, int cg_id)
double percent_pkts, percent_bytes; double percent_pkts, percent_bytes;
char fname[100]; char fname[100];
FILE *fout; FILE *fout;
int k;
static const char *returnValNames[] = {
"DROP_PKT",
"ALLOW_PKT",
"DROP_PKT_CWR",
"ALLOW_PKT_CWR"
};
#define RET_VAL_COUNT 4
// Future support of ingress // Future support of ingress
// if (!outFlag) // if (!outFlag)
...@@ -350,6 +358,31 @@ static int run_bpf_prog(char *prog, int cg_id) ...@@ -350,6 +358,31 @@ static int run_bpf_prog(char *prog, int cg_id)
(qstats.bytes_total + 1); (qstats.bytes_total + 1);
fprintf(fout, "pkts_dropped_percent:%6.2f\n", percent_pkts); fprintf(fout, "pkts_dropped_percent:%6.2f\n", percent_pkts);
fprintf(fout, "bytes_dropped_percent:%6.2f\n", percent_bytes); fprintf(fout, "bytes_dropped_percent:%6.2f\n", percent_bytes);
// ECN CE markings
percent_pkts = (qstats.pkts_ecn_ce * 100.0) /
(qstats.pkts_total + 1);
fprintf(fout, "pkts_ecn_ce:%6.2f (%d)\n", percent_pkts,
(int)qstats.pkts_ecn_ce);
// Average cwnd
fprintf(fout, "avg cwnd:%d\n",
(int)(qstats.sum_cwnd / (qstats.sum_cwnd_cnt + 1)));
// Average rtt
fprintf(fout, "avg rtt:%d\n",
(int)(qstats.sum_rtt / (qstats.pkts_total + 1)));
// Average credit
fprintf(fout, "avg credit:%d\n",
(int)(qstats.sum_credit /
(1500 * ((int)qstats.pkts_total) + 1)));
// Return values stats
for (k = 0; k < RET_VAL_COUNT; k++) {
percent_pkts = (qstats.returnValCount[k] * 100.0) /
(qstats.pkts_total + 1);
fprintf(fout, "%s:%6.2f (%d)\n", returnValNames[k],
percent_pkts, (int)qstats.returnValCount[k]);
}
fclose(fout); fclose(fout);
} }
......
...@@ -29,4 +29,10 @@ struct hbm_queue_stats { ...@@ -29,4 +29,10 @@ struct hbm_queue_stats {
unsigned long long bytes_total; unsigned long long bytes_total;
unsigned long long firstPacketTime; unsigned long long firstPacketTime;
unsigned long long lastPacketTime; unsigned long long lastPacketTime;
unsigned long long pkts_ecn_ce;
unsigned long long returnValCount[4];
unsigned long long sum_cwnd;
unsigned long long sum_rtt;
unsigned long long sum_cwnd_cnt;
long long sum_credit;
}; };
...@@ -65,17 +65,43 @@ struct bpf_map_def SEC("maps") queue_stats = { ...@@ -65,17 +65,43 @@ struct bpf_map_def SEC("maps") queue_stats = {
BPF_ANNOTATE_KV_PAIR(queue_stats, int, struct hbm_queue_stats); BPF_ANNOTATE_KV_PAIR(queue_stats, int, struct hbm_queue_stats);
struct hbm_pkt_info { struct hbm_pkt_info {
int cwnd;
int rtt;
bool is_ip; bool is_ip;
bool is_tcp; bool is_tcp;
short ecn; short ecn;
}; };
static int get_tcp_info(struct __sk_buff *skb, struct hbm_pkt_info *pkti)
{
struct bpf_sock *sk;
struct bpf_tcp_sock *tp;
sk = skb->sk;
if (sk) {
sk = bpf_sk_fullsock(sk);
if (sk) {
if (sk->protocol == IPPROTO_TCP) {
tp = bpf_tcp_sock(sk);
if (tp) {
pkti->cwnd = tp->snd_cwnd;
pkti->rtt = tp->srtt_us >> 3;
return 0;
}
}
}
}
return 1;
}
static __always_inline void hbm_get_pkt_info(struct __sk_buff *skb, static __always_inline void hbm_get_pkt_info(struct __sk_buff *skb,
struct hbm_pkt_info *pkti) struct hbm_pkt_info *pkti)
{ {
struct iphdr iph; struct iphdr iph;
struct ipv6hdr *ip6h; struct ipv6hdr *ip6h;
pkti->cwnd = 0;
pkti->rtt = 0;
bpf_skb_load_bytes(skb, 0, &iph, 12); bpf_skb_load_bytes(skb, 0, &iph, 12);
if (iph.version == 6) { if (iph.version == 6) {
ip6h = (struct ipv6hdr *)&iph; ip6h = (struct ipv6hdr *)&iph;
...@@ -91,6 +117,8 @@ static __always_inline void hbm_get_pkt_info(struct __sk_buff *skb, ...@@ -91,6 +117,8 @@ static __always_inline void hbm_get_pkt_info(struct __sk_buff *skb,
pkti->is_tcp = false; pkti->is_tcp = false;
pkti->ecn = 0; pkti->ecn = 0;
} }
if (pkti->is_tcp)
get_tcp_info(skb, pkti);
} }
static __always_inline void hbm_init_vqueue(struct hbm_vqueue *qdp, int rate) static __always_inline void hbm_init_vqueue(struct hbm_vqueue *qdp, int rate)
...@@ -105,8 +133,14 @@ static __always_inline void hbm_update_stats(struct hbm_queue_stats *qsp, ...@@ -105,8 +133,14 @@ static __always_inline void hbm_update_stats(struct hbm_queue_stats *qsp,
int len, int len,
unsigned long long curtime, unsigned long long curtime,
bool congestion_flag, bool congestion_flag,
bool drop_flag) bool drop_flag,
bool cwr_flag,
bool ecn_ce_flag,
struct hbm_pkt_info *pkti,
int credit)
{ {
int rv = ALLOW_PKT;
if (qsp != NULL) { if (qsp != NULL) {
// Following is needed for work conserving // Following is needed for work conserving
__sync_add_and_fetch(&(qsp->bytes_total), len); __sync_add_and_fetch(&(qsp->bytes_total), len);
...@@ -116,7 +150,7 @@ static __always_inline void hbm_update_stats(struct hbm_queue_stats *qsp, ...@@ -116,7 +150,7 @@ static __always_inline void hbm_update_stats(struct hbm_queue_stats *qsp,
qsp->firstPacketTime = curtime; qsp->firstPacketTime = curtime;
qsp->lastPacketTime = curtime; qsp->lastPacketTime = curtime;
__sync_add_and_fetch(&(qsp->pkts_total), 1); __sync_add_and_fetch(&(qsp->pkts_total), 1);
if (congestion_flag || drop_flag) { if (congestion_flag) {
__sync_add_and_fetch(&(qsp->pkts_marked), 1); __sync_add_and_fetch(&(qsp->pkts_marked), 1);
__sync_add_and_fetch(&(qsp->bytes_marked), len); __sync_add_and_fetch(&(qsp->bytes_marked), len);
} }
...@@ -125,6 +159,34 @@ static __always_inline void hbm_update_stats(struct hbm_queue_stats *qsp, ...@@ -125,6 +159,34 @@ static __always_inline void hbm_update_stats(struct hbm_queue_stats *qsp,
__sync_add_and_fetch(&(qsp->bytes_dropped), __sync_add_and_fetch(&(qsp->bytes_dropped),
len); len);
} }
if (ecn_ce_flag)
__sync_add_and_fetch(&(qsp->pkts_ecn_ce), 1);
if (pkti->cwnd) {
__sync_add_and_fetch(&(qsp->sum_cwnd),
pkti->cwnd);
__sync_add_and_fetch(&(qsp->sum_cwnd_cnt), 1);
}
if (pkti->rtt)
__sync_add_and_fetch(&(qsp->sum_rtt),
pkti->rtt);
__sync_add_and_fetch(&(qsp->sum_credit), credit);
if (drop_flag)
rv = DROP_PKT;
if (cwr_flag)
rv |= 2;
if (rv == DROP_PKT)
__sync_add_and_fetch(&(qsp->returnValCount[0]),
1);
else if (rv == ALLOW_PKT)
__sync_add_and_fetch(&(qsp->returnValCount[1]),
1);
else if (rv == 2)
__sync_add_and_fetch(&(qsp->returnValCount[2]),
1);
else if (rv == 3)
__sync_add_and_fetch(&(qsp->returnValCount[3]),
1);
} }
} }
} }
...@@ -62,11 +62,12 @@ int _hbm_out_cg(struct __sk_buff *skb) ...@@ -62,11 +62,12 @@ int _hbm_out_cg(struct __sk_buff *skb)
unsigned int queue_index = 0; unsigned int queue_index = 0;
unsigned long long curtime; unsigned long long curtime;
int credit; int credit;
signed long long delta = 0, zero = 0; signed long long delta = 0, new_credit;
int max_credit = MAX_CREDIT; int max_credit = MAX_CREDIT;
bool congestion_flag = false; bool congestion_flag = false;
bool drop_flag = false; bool drop_flag = false;
bool cwr_flag = false; bool cwr_flag = false;
bool ecn_ce_flag = false;
struct hbm_vqueue *qdp; struct hbm_vqueue *qdp;
struct hbm_queue_stats *qsp = NULL; struct hbm_queue_stats *qsp = NULL;
int rv = ALLOW_PKT; int rv = ALLOW_PKT;
...@@ -99,9 +100,11 @@ int _hbm_out_cg(struct __sk_buff *skb) ...@@ -99,9 +100,11 @@ int _hbm_out_cg(struct __sk_buff *skb)
*/ */
if (delta > 0) { if (delta > 0) {
qdp->lasttime = curtime; qdp->lasttime = curtime;
credit += CREDIT_PER_NS(delta, qdp->rate); new_credit = credit + CREDIT_PER_NS(delta, qdp->rate);
if (credit > MAX_CREDIT) if (new_credit > MAX_CREDIT)
credit = MAX_CREDIT; credit = MAX_CREDIT;
else
credit = new_credit;
} }
credit -= len; credit -= len;
qdp->credit = credit; qdp->credit = credit;
...@@ -139,7 +142,9 @@ int _hbm_out_cg(struct __sk_buff *skb) ...@@ -139,7 +142,9 @@ 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)) {
ecn_ce_flag = true;
} else {
if (pkti.is_tcp) { if (pkti.is_tcp) {
unsigned int rand = bpf_get_prandom_u32(); unsigned int rand = bpf_get_prandom_u32();
...@@ -155,16 +160,17 @@ int _hbm_out_cg(struct __sk_buff *skb) ...@@ -155,16 +160,17 @@ int _hbm_out_cg(struct __sk_buff *skb)
} }
} }
if (drop_flag)
rv = DROP_PKT;
if (qsp != NULL) if (qsp != NULL)
if (qsp->no_cn) if (qsp->no_cn)
cwr_flag = false; cwr_flag = false;
hbm_update_stats(qsp, len, curtime, congestion_flag, drop_flag); hbm_update_stats(qsp, len, curtime, congestion_flag, drop_flag,
cwr_flag, ecn_ce_flag, &pkti, credit);
if (rv == DROP_PKT) if (drop_flag) {
__sync_add_and_fetch(&(qdp->credit), len); __sync_add_and_fetch(&(qdp->credit), len);
rv = DROP_PKT;
}
if (cwr_flag) if (cwr_flag)
rv |= 2; rv |= 2;
......
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