Skip to content

Commit

Permalink
Support for hardware offload (iovisor#2502)
Browse files Browse the repository at this point in the history
 Support for hardware offload
 Update XDP example to support HW offload

Signed-off-by: Paul Chaignon <[email protected]>
  • Loading branch information
pchaigno authored and yonghong-song committed Sep 3, 2019
1 parent 496a2b1 commit d147588
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 37 deletions.
30 changes: 18 additions & 12 deletions examples/networking/xdp/xdp_drop_count.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,29 @@
def usage():
print("Usage: {0} [-S] <ifdev>".format(sys.argv[0]))
print(" -S: use skb mode\n")
print(" -H: use hardware offload mode\n")
print("e.g.: {0} eth0\n".format(sys.argv[0]))
exit(1)

if len(sys.argv) < 2 or len(sys.argv) > 3:
usage()

offload_device = None
if len(sys.argv) == 2:
device = sys.argv[1]
elif len(sys.argv) == 3:
device = sys.argv[2]

maptype = "percpu_array"
if len(sys.argv) == 3:
if "-S" in sys.argv:
# XDP_FLAGS_SKB_MODE
flags |= 2 << 0

if "-S" == sys.argv[1]:
device = sys.argv[2]
else:
device = sys.argv[1]
flags |= (1 << 1)
if "-H" in sys.argv:
# XDP_FLAGS_HW_MODE
maptype = "array"
offload_device = device
flags |= (1 << 3)

mode = BPF.XDP
#mode = BPF.SCHED_CLS
Expand All @@ -56,8 +61,7 @@ def usage():
#include <linux/ip.h>
#include <linux/ipv6.h>
BPF_TABLE("percpu_array", uint32_t, long, dropcnt, 256);
BPF_TABLE(MAPTYPE, uint32_t, long, dropcnt, 256);
static inline int parse_ipv4(void *data, u64 nh_off, void *data_end) {
struct iphdr *iph = data + nh_off;
Expand Down Expand Up @@ -119,13 +123,15 @@ def usage():
value = dropcnt.lookup(&index);
if (value)
*value += 1;
__sync_fetch_and_add(value, 1);
return rc;
}
""", cflags=["-w", "-DRETURNCODE=%s" % ret, "-DCTXTYPE=%s" % ctxtype])
""", cflags=["-w", "-DRETURNCODE=%s" % ret, "-DCTXTYPE=%s" % ctxtype,
"-DMAPTYPE=\"%s\"" % maptype],
device=offload_device)

fn = b.load_func("xdp_prog1", mode)
fn = b.load_func("xdp_prog1", mode, offload_device)

if mode == BPF.XDP:
b.attach_xdp(device, fn, flags)
Expand All @@ -143,7 +149,7 @@ def usage():
while 1:
try:
for k in dropcnt.keys():
val = dropcnt.sum(k).value
val = dropcnt[k].value if maptype == "array" else dropcnt.sum(k).value
i = k.value
if val:
delta = val - prev[i]
Expand Down
18 changes: 10 additions & 8 deletions src/cc/bcc_common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
#include "bpf_module.h"

extern "C" {
void * bpf_module_create_b(const char *filename, const char *proto_filename, unsigned flags) {
auto mod = new ebpf::BPFModule(flags);
void * bpf_module_create_b(const char *filename, const char *proto_filename, unsigned flags,
const char *dev_name) {
auto mod = new ebpf::BPFModule(flags, nullptr, true, "", true, dev_name);
if (mod->load_b(filename, proto_filename) != 0) {
delete mod;
return nullptr;
Expand All @@ -27,8 +28,8 @@ void * bpf_module_create_b(const char *filename, const char *proto_filename, uns
}

void * bpf_module_create_c(const char *filename, unsigned flags, const char *cflags[],
int ncflags, bool allow_rlimit) {
auto mod = new ebpf::BPFModule(flags, nullptr, true, "", allow_rlimit);
int ncflags, bool allow_rlimit, const char *dev_name) {
auto mod = new ebpf::BPFModule(flags, nullptr, true, "", allow_rlimit, dev_name);
if (mod->load_c(filename, cflags, ncflags) != 0) {
delete mod;
return nullptr;
Expand All @@ -37,8 +38,8 @@ void * bpf_module_create_c(const char *filename, unsigned flags, const char *cfl
}

void * bpf_module_create_c_from_string(const char *text, unsigned flags, const char *cflags[],
int ncflags, bool allow_rlimit) {
auto mod = new ebpf::BPFModule(flags, nullptr, true, "", allow_rlimit);
int ncflags, bool allow_rlimit, const char *dev_name) {
auto mod = new ebpf::BPFModule(flags, nullptr, true, "", allow_rlimit, dev_name);
if (mod->load_string(text, cflags, ncflags) != 0) {
delete mod;
return nullptr;
Expand Down Expand Up @@ -240,12 +241,13 @@ int bpf_table_leaf_sscanf(void *program, size_t id, const char *buf, void *leaf)
int bcc_func_load(void *program, int prog_type, const char *name,
const struct bpf_insn *insns, int prog_len,
const char *license, unsigned kern_version,
int log_level, char *log_buf, unsigned log_buf_size) {
int log_level, char *log_buf, unsigned log_buf_size,
const char *dev_name) {
auto mod = static_cast<ebpf::BPFModule *>(program);
if (!mod) return -1;
return mod->bcc_func_load(prog_type, name, insns, prog_len,
license, kern_version, log_level,
log_buf, log_buf_size);
log_buf, log_buf_size, dev_name);

}

Expand Down
11 changes: 7 additions & 4 deletions src/cc/bcc_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
extern "C" {
#endif

void * bpf_module_create_b(const char *filename, const char *proto_filename, unsigned flags);
void * bpf_module_create_b(const char *filename, const char *proto_filename, unsigned flags,
const char *dev_name);
void * bpf_module_create_c(const char *filename, unsigned flags, const char *cflags[], int ncflags,
bool allow_rlimit);
bool allow_rlimit, const char *dev_name);
void * bpf_module_create_c_from_string(const char *text, unsigned flags, const char *cflags[],
int ncflags, bool allow_rlimit);
int ncflags, bool allow_rlimit,
const char *dev_name);
void bpf_module_destroy(void *program);
char * bpf_module_license(void *program);
unsigned bpf_module_kern_version(void *program);
Expand Down Expand Up @@ -69,7 +71,8 @@ struct bpf_insn;
int bcc_func_load(void *program, int prog_type, const char *name,
const struct bpf_insn *insns, int prog_len,
const char *license, unsigned kern_version,
int log_level, char *log_buf, unsigned log_buf_size);
int log_level, char *log_buf, unsigned log_buf_size,
const char *dev_name);

#ifdef __cplusplus
}
Expand Down
11 changes: 9 additions & 2 deletions src/cc/bpf_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <unistd.h>
#include <vector>
#include <linux/bpf.h>
#include <net/if.h>

#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
Expand Down Expand Up @@ -93,7 +94,8 @@ class MyMemoryManager : public SectionMemoryManager {
};

BPFModule::BPFModule(unsigned flags, TableStorage *ts, bool rw_engine_enabled,
const std::string &maps_ns, bool allow_rlimit)
const std::string &maps_ns, bool allow_rlimit,
const char *dev_name)
: flags_(flags),
rw_engine_enabled_(rw_engine_enabled && bpf_module_rw_engine_enabled()),
used_b_loader_(false),
Expand All @@ -102,6 +104,7 @@ BPFModule::BPFModule(unsigned flags, TableStorage *ts, bool rw_engine_enabled,
id_(std::to_string((uintptr_t)this)),
maps_ns_(maps_ns),
ts_(ts), btf_(nullptr) {
ifindex_ = dev_name ? if_nametoindex(dev_name) : 0;
initialize_rw_engine();
LLVMInitializeBPFTarget();
LLVMInitializeBPFTargetMC();
Expand Down Expand Up @@ -338,6 +341,7 @@ int BPFModule::load_maps(sec_map_def &sections) {
attr.value_size = value_size;
attr.max_entries = max_entries;
attr.map_flags = map_flags;
attr.map_ifindex = ifindex_;

if (map_tids.find(map_name) != map_tids.end()) {
attr.btf_fd = btf_->get_fd();
Expand Down Expand Up @@ -847,7 +851,8 @@ int BPFModule::load_string(const string &text, const char *cflags[], int ncflags
int BPFModule::bcc_func_load(int prog_type, const char *name,
const struct bpf_insn *insns, int prog_len,
const char *license, unsigned kern_version,
int log_level, char *log_buf, unsigned log_buf_size) {
int log_level, char *log_buf, unsigned log_buf_size,
const char *dev_name) {
struct bpf_load_program_attr attr = {};
unsigned func_info_cnt, line_info_cnt, finfo_rec_size, linfo_rec_size;
void *func_info = NULL, *line_info = NULL;
Expand All @@ -859,6 +864,8 @@ int BPFModule::bcc_func_load(int prog_type, const char *name,
attr.license = license;
attr.kern_version = kern_version;
attr.log_level = log_level;
if (dev_name)
attr.prog_ifindex = if_nametoindex(dev_name);

if (btf_) {
int btf_fd = btf_->get_fd();
Expand Down
7 changes: 5 additions & 2 deletions src/cc/bpf_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ class BPFModule {

public:
BPFModule(unsigned flags, TableStorage *ts = nullptr, bool rw_engine_enabled = true,
const std::string &maps_ns = "", bool allow_rlimit = true);
const std::string &maps_ns = "", bool allow_rlimit = true,
const char *dev_name = nullptr);
~BPFModule();
int free_bcc_memory();
int load_b(const std::string &filename, const std::string &proto_filename);
Expand Down Expand Up @@ -138,7 +139,8 @@ class BPFModule {
int bcc_func_load(int prog_type, const char *name,
const struct bpf_insn *insns, int prog_len,
const char *license, unsigned kern_version,
int log_level, char *log_buf, unsigned log_buf_size);
int log_level, char *log_buf, unsigned log_buf_size,
const char *dev_name = nullptr);
size_t perf_event_fields(const char *) const;
const char * perf_event_field(const char *, size_t i) const;

Expand Down Expand Up @@ -168,6 +170,7 @@ class BPFModule {
std::unique_ptr<TableStorage> local_ts_;
BTF *btf_;
fake_fd_map_def fake_fd_map_;
unsigned int ifindex_;

// map of events -- key: event name, value: event fields
std::map<std::string, std::vector<std::string>> perf_events_;
Expand Down
10 changes: 5 additions & 5 deletions src/python/bcc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def is_exe(fpath):
return None

def __init__(self, src_file=b"", hdr_file=b"", text=None, debug=0,
cflags=[], usdt_contexts=[], allow_rlimit=True):
cflags=[], usdt_contexts=[], allow_rlimit=True, device=None):
"""Create a new BPF module with the given source code.
Note:
Expand Down Expand Up @@ -319,7 +319,7 @@ def __init__(self, src_file=b"", hdr_file=b"", text=None, debug=0,

# files that end in ".b" are treated as B files. Everything else is a (BPF-)C file
if src_file.endswith(b".b"):
self.module = lib.bpf_module_create_b(src_file, hdr_file, self.debug)
self.module = lib.bpf_module_create_b(src_file, hdr_file, self.debug, device)
else:
if src_file:
# Read the BPF C source file into the text variable. This ensures,
Expand All @@ -342,7 +342,7 @@ def __init__(self, src_file=b"", hdr_file=b"", text=None, debug=0,
self.module = lib.bpf_module_create_c_from_string(text,
self.debug,
cflags_array, len(cflags_array),
allow_rlimit)
allow_rlimit, device)
if not self.module:
raise Exception("Failed to compile BPF module %s" % (src_file or "<text>"))

Expand All @@ -367,7 +367,7 @@ def load_funcs(self, prog_type=KPROBE):

return fns

def load_func(self, func_name, prog_type):
def load_func(self, func_name, prog_type, device = None):
func_name = _assert_is_bytes(func_name)
if func_name in self.funcs:
return self.funcs[func_name]
Expand All @@ -383,7 +383,7 @@ def load_func(self, func_name, prog_type):
lib.bpf_function_size(self.module, func_name),
lib.bpf_module_license(self.module),
lib.bpf_module_kern_version(self.module),
log_level, None, 0);
log_level, None, 0, device);

if fd < 0:
atexit.register(self.donothing)
Expand Down
7 changes: 4 additions & 3 deletions src/python/bcc/libbcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@

# keep in sync with bcc_common.h
lib.bpf_module_create_b.restype = ct.c_void_p
lib.bpf_module_create_b.argtypes = [ct.c_char_p, ct.c_char_p, ct.c_uint]
lib.bpf_module_create_b.argtypes = [ct.c_char_p, ct.c_char_p, ct.c_uint,
ct.c_char_p]
lib.bpf_module_create_c.restype = ct.c_void_p
lib.bpf_module_create_c.argtypes = [ct.c_char_p, ct.c_uint,
ct.POINTER(ct.c_char_p), ct.c_int, ct.c_bool]
ct.POINTER(ct.c_char_p), ct.c_int, ct.c_bool, ct.c_char_p]
lib.bpf_module_create_c_from_string.restype = ct.c_void_p
lib.bpf_module_create_c_from_string.argtypes = [ct.c_char_p, ct.c_uint,
ct.POINTER(ct.c_char_p), ct.c_int, ct.c_bool]
ct.POINTER(ct.c_char_p), ct.c_int, ct.c_bool, ct.c_char_p]
lib.bpf_module_destroy.restype = None
lib.bpf_module_destroy.argtypes = [ct.c_void_p]
lib.bpf_module_license.restype = ct.c_char_p
Expand Down
2 changes: 1 addition & 1 deletion tests/cc/test_static.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "bcc_common.h"

int main(int argc, char **argv) {
void *mod = bpf_module_create_c_from_string("BPF_TABLE(\"array\", int, int, stats, 10);\n", 4, NULL, 0, true);
void *mod = bpf_module_create_c_from_string("BPF_TABLE(\"array\", int, int, stats, 10);\n", 4, NULL, 0, true, NULL);
return !(mod != NULL);
}

0 comments on commit d147588

Please sign in to comment.