Skip to content

Commit

Permalink
Fix compatibility issues with kernel >= 5.10 (#384)
Browse files Browse the repository at this point in the history
* Update BCC to v0.20.0
* Fixes compatibility issues with kernel >= 5.10: use a spin lock instead of rcu lock to access the slow path -> fast path ring

rcu_read_lock() and rcu_read_unlock() are no longer accepted by the
verifier in kernel >= 5.10. The rcu_read_lock was probably not
guaranteeing exclusive update of the index of the ring anyway.
  • Loading branch information
FedeParola committed Jul 5, 2021
1 parent 1629c9f commit e949d5e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/libs/bcc
Submodule bcc updated 54 files
+14 −0 debian/changelog
+1 −0 docs/kernel-versions.md
+84 −26 docs/reference_guide.md
+2 −0 libbpf-tools/.gitignore
+4 −2 libbpf-tools/Makefile
+26 −7 libbpf-tools/biolatency.bpf.c
+22 −4 libbpf-tools/biosnoop.bpf.c
+0 −1 libbpf-tools/biostacks.bpf.c
+17 −2 libbpf-tools/bitesize.bpf.c
+9 −9 libbpf-tools/cpudist.bpf.c
+165 −0 libbpf-tools/ext4dist.bpf.c
+255 −0 libbpf-tools/ext4dist.c
+19 −0 libbpf-tools/ext4dist.h
+110 −0 libbpf-tools/offcputime.bpf.c
+342 −0 libbpf-tools/offcputime.c
+19 −0 libbpf-tools/offcputime.h
+751 −6 libbpf-tools/trace_helpers.c
+56 −0 libbpf-tools/trace_helpers.h
+25 −2 libbpf-tools/uprobe_helpers.c
+4 −0 libbpf-tools/uprobe_helpers.h
+35 −5 libbpf-tools/vfsstat.bpf.c
+28 −7 libbpf-tools/vfsstat.c
+0 −2 libbpf-tools/xfsslower.bpf.c
+8 −1 man/man8/biolatency.8
+3 −0 man/man8/funclatency.8
+8 −0 src/cc/api/BPFTable.cc
+1 −0 src/cc/api/BPFTable.h
+7 −2 src/cc/bcc_debug.cc
+30 −20 src/cc/bpf_module.cc
+804 −8 src/cc/compat/linux/virtual_bpf.h
+11 −0 src/cc/export/bpf_workaround.h
+20 −0 src/cc/export/helpers.h
+4 −0 src/cc/exported_files.cc
+5 −0 src/cc/frontends/clang/arch_helper.h
+28 −10 src/cc/frontends/clang/b_frontend_action.cc
+2 −1 src/cc/frontends/clang/b_frontend_action.h
+5 −3 src/cc/frontends/clang/kbuild_helper.cc
+14 −0 src/cc/frontends/clang/loader.cc
+1 −1 src/cc/libbpf
+72 −2 src/cc/libbpf.c
+2 −0 src/cc/libbpf.h
+1 −1 src/cc/table_storage.h
+1 −1 src/python/bcc/__init__.py
+9 −1 src/python/bcc/libbcc.py
+105 −6 src/python/bcc/table.py
+3 −2 tests/cc/test_pinned_table.cc
+77 −10 tests/python/test_map_batch_ops.py
+20 −6 tests/python/test_queuestack.py
+60 −18 tools/biolatency.py
+28 −0 tools/biolatency_example.txt
+1 −1 tools/dcsnoop.py
+1 −1 tools/dcstat.py
+157 −23 tools/funclatency.py
+3 −1 tools/funclatency_example.txt
80 changes: 45 additions & 35 deletions src/polycubed/src/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,45 +59,50 @@ const std::string CTRL_TC_RX = R"(
BPF_TABLE("extern", int, int, nodes, _POLYCUBE_MAX_NODES);
struct metadata {
u16 module_index;
u16 module_index;
u8 is_netdev;
u16 port_id;
u16 port_id;
u32 flags;
} __attribute__((packed));
struct index_value {
u32 index;
struct bpf_spin_lock lock;
};
BPF_TABLE("array", u32, struct metadata, md_map_rx, MD_MAP_SIZE);
BPF_TABLE("array", u32, u32, index_map_rx, 1);
BPF_ARRAY(index_map_rx, struct index_value, 1);
int controller_module_rx(struct __sk_buff *ctx) {
pcn_log(ctx, LOG_TRACE, "[tc-decapsulator]: from controller");
u32 zero = 0;
u32 *index = index_map_rx.lookup(&zero);
if (!index) {
u32 zero = 0;
struct index_value *val = index_map_rx.lookup(&zero);
if (!val) {
pcn_log(ctx, LOG_ERR, "[tc-decapsulator]: !index");
return 2;
}
rcu_read_lock();
(*index)++;
*index %= MD_MAP_SIZE;
rcu_read_unlock();
return 2;
}
u32 i = *index;
// Compute the index of the next packet in the ring. This operation must be
// mutually exclusive.
bpf_spin_lock(&val->lock);
val->index++;
val->index %= MD_MAP_SIZE;
u32 i = val->index;
bpf_spin_unlock(&val->lock);
struct metadata *md = md_map_rx.lookup(&i);
if (!md) {
pcn_log(ctx, LOG_ERR, "[tc-decapsulator]: !md");
return 2;
}
struct metadata *md = md_map_rx.lookup(&i);
if (!md) {
pcn_log(ctx, LOG_ERR, "[tc-decapsulator]: !md");
return 2;
}
u16 in_port = md->port_id;
u16 module_index = md->module_index;
u16 in_port = md->port_id;
u16 module_index = md->module_index;
u8 is_netdev = md->is_netdev;
u32 flags = md->flags;
ctx->cb[0] = in_port << 16 | module_index;
ctx->cb[0] = in_port << 16 | module_index;
ctx->cb[2] = flags;
if (is_netdev) {
return bpf_redirect(module_index, 0);
Expand All @@ -110,9 +115,9 @@ int controller_module_rx(struct __sk_buff *ctx) {
}
}
nodes.call(ctx, module_index);
nodes.call(ctx, module_index);
pcn_log(ctx, LOG_ERR, "[tc-decapsulator]: 'nodes.call'. Module is: %d", module_index);
return 2;
return 2;
}
)";

Expand All @@ -138,10 +143,15 @@ struct pkt_metadata {
u32 md[3]; // generic metadata
} __attribute__((packed));
struct index_value {
u32 index;
struct bpf_spin_lock lock;
};
BPF_TABLE("extern", int, int, xdp_nodes, _POLYCUBE_MAX_NODES);
BPF_TABLE_PUBLIC("percpu_array", u32, struct pkt_metadata, port_md, 1);
BPF_TABLE("array", u32, struct xdp_metadata, md_map_rx, MD_MAP_SIZE);
BPF_TABLE("array", u32, u32, xdp_index_map_rx, 1);
BPF_ARRAY(xdp_index_map_rx, struct index_value, 1);
int controller_module_rx(struct xdp_md *ctx) {
pcn_log(ctx, LOG_TRACE, "[xdp-decapsulator]: from controller");
Expand All @@ -152,19 +162,19 @@ int controller_module_rx(struct xdp_md *ctx) {
return XDP_ABORTED;
}
u32 *index = xdp_index_map_rx.lookup(&zero);
if (!index) {
struct index_value *val = xdp_index_map_rx.lookup(&zero);
if (!val) {
pcn_log(ctx, LOG_ERR, "[xdp-decapsulator]: !index");
return XDP_ABORTED;
}
rcu_read_lock();
(*index)++;
*index %= MD_MAP_SIZE;
rcu_read_unlock();
u32 i = *index;
// Compute the index of the next packet in the ring. This operation must be
// mutually exclusive.
bpf_spin_lock(&val->lock);
val->index++;
val->index %= MD_MAP_SIZE;
u32 i = val->index;
bpf_spin_unlock(&val->lock);
struct xdp_metadata *xdp_md = md_map_rx.lookup(&i);
if (!xdp_md) {
Expand Down

0 comments on commit e949d5e

Please sign in to comment.