Skip to content

Commit faea8c8

Browse files
committed
Add TableStorage class for wrapping bpf map tracking
Adds a TableStorage class for use by language frontends to store/access references to loaded bpf maps. Includes support for shared and namespaced maps, in a directory-like hierarchy. Add a FileDesc helper class to automatically wrap open file descriptors. The object prevents implicit copying of the fd (allows only rvalue/move()), and takes care of the close() call. Add a reference implementation of a TableStorageImpl that performs the current default behavior expected by BPF_TABLE_PUBLIC, which is to share maps between BPFModules in the same-process only. A stub implementation for bpffs is started. Update b/clang frontends to use this new class. Also included is a framework for extracting the type information of maps in an extensible way. Migrate BMapDeclVisitor to use this as the first consumer. Signed-off-by: Brenden Blanco <[email protected]>
1 parent 271056f commit faea8c8

23 files changed

+806
-278
lines changed

.clang-format

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ BasedOnStyle: Google
33
AllowShortIfStatementsOnASingleLine: false
44
AllowShortLoopsOnASingleLine: false
55
IndentCaseLabels: false
6-
AccessModifierOffset: -2
6+
AccessModifierOffset: -1

src/cc/BPF.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@
2828
#include "bcc_exception.h"
2929
#include "bcc_syms.h"
3030
#include "bpf_module.h"
31+
#include "common.h"
3132
#include "libbpf.h"
3233
#include "perf_reader.h"
33-
#include "common.h"
34+
#include "table_storage.h"
3435
#include "usdt.h"
3536

3637
#include "BPF.h"

src/cc/BPF.h

+10-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "bpf_module.h"
2727
#include "compat/linux/bpf.h"
2828
#include "libbpf.h"
29+
#include "table_storage.h"
2930

3031
static const int DEFAULT_PERF_BUFFER_PAGE_CNT = 8;
3132

@@ -38,12 +39,14 @@ struct open_probe_t {
3839
};
3940

4041
class USDT;
42+
class TableStorage;
4143

4244
class BPF {
4345
public:
4446
static const int BPF_MAX_STACK_DEPTH = 127;
4547

46-
explicit BPF(unsigned int flag = 0) : bpf_module_(new BPFModule(flag)) {}
48+
explicit BPF(unsigned int flag = 0, TableStorage* ts = nullptr)
49+
: bpf_module_(new BPFModule(flag, ts)), ts_(ts) {}
4750
StatusTuple init(const std::string& bpf_program,
4851
std::vector<std::string> cflags = {},
4952
std::vector<USDT> usdt = {});
@@ -90,6 +93,11 @@ class BPF {
9093

9194
template <class KeyType, class ValueType>
9295
BPFHashTable<KeyType, ValueType> get_hash_table(const std::string& name) {
96+
if (ts_) {
97+
TableStorage::iterator it;
98+
if (ts_->Find(Path({name}), it))
99+
return BPFHashTable<KeyType, ValueType>(it->second);
100+
}
93101
return BPFHashTable<KeyType, ValueType>(bpf_module_.get(), name);
94102
}
95103

@@ -152,6 +160,7 @@ class BPF {
152160
uint64_t symbol_addr, bcc_symbol* output);
153161

154162
std::unique_ptr<BPFModule> bpf_module_;
163+
TableStorage* ts_;
155164

156165
std::map<std::string, int> funcs_;
157166

src/cc/BPFTable.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "bpf_module.h"
2929
#include "libbpf.h"
3030
#include "perf_reader.h"
31+
#include "table_desc.h"
3132

3233
namespace ebpf {
3334

@@ -44,6 +45,10 @@ class BPFTableBase {
4445
fd_ = bpf_module->table_fd(id_);
4546
capacity_ = bpf_module->table_max_entries(id_);
4647
};
48+
explicit BPFTableBase(const TableDesc& desc) {
49+
fd_ = desc.fd;
50+
capacity_ = desc.max_entries;
51+
}
4752

4853
bool lookup(KeyType* key, ValueType* value) {
4954
return bpf_lookup_elem(fd_, static_cast<void*>(key),
@@ -70,7 +75,8 @@ class BPFTableBase {
7075

7176
template <class KeyType, class ValueType>
7277
class BPFHashTable : protected BPFTableBase<KeyType, ValueType> {
73-
public:
78+
public:
79+
explicit BPFHashTable(const TableDesc& desc) : BPFTableBase<KeyType, ValueType>(desc) {}
7480
BPFHashTable(BPFModule* bpf_module, const std::string& name)
7581
: BPFTableBase<KeyType, ValueType>(bpf_module, name) {}
7682

src/cc/CMakeLists.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ if (CMAKE_COMPILER_IS_GNUCC AND LIBCLANG_ISSTATIC)
3535
endif()
3636
endif()
3737

38-
add_library(bcc-shared SHARED bpf_common.cc bpf_module.cc libbpf.c perf_reader.c shared_table.cc exported_files.cc bcc_elf.c bcc_perf_map.c bcc_proc.c bcc_syms.cc usdt_args.cc usdt.cc common.cc BPF.cc BPFTable.cc)
38+
add_library(bcc-shared SHARED bpf_common.cc bpf_module.cc libbpf.c perf_reader.c table_storage.cc shared_table.cc bpffs_table.cc json_map_decl_visitor.cc exported_files.cc bcc_elf.c bcc_perf_map.c bcc_proc.c bcc_syms.cc usdt_args.cc usdt.cc common.cc BPF.cc BPFTable.cc)
3939
set_target_properties(bcc-shared PROPERTIES VERSION ${REVISION_LAST} SOVERSION 0)
4040
set_target_properties(bcc-shared PROPERTIES OUTPUT_NAME bcc)
4141

4242
add_library(bcc-loader-static STATIC libbpf.c perf_reader.c bcc_elf.c bcc_perf_map.c bcc_proc.c)
43-
add_library(bcc-static STATIC bpf_common.cc bpf_module.cc shared_table.cc exported_files.cc bcc_syms.cc usdt_args.cc usdt.cc common.cc BPF.cc BPFTable.cc)
43+
add_library(bcc-static STATIC bpf_common.cc bpf_module.cc shared_table.cc bpffs_table.cc json_map_decl_visitor.cc table_storage.cc exported_files.cc bcc_syms.cc usdt_args.cc usdt.cc common.cc BPF.cc BPFTable.cc)
4444
set_target_properties(bcc-static PROPERTIES OUTPUT_NAME bcc)
4545

4646
set(llvm_raw_libs bitwriter bpfcodegen irreader linker
@@ -67,7 +67,7 @@ target_link_libraries(bcc-static b_frontend clang_frontend bcc-loader-static ${c
6767

6868
install(TARGETS bcc-shared LIBRARY COMPONENT libbcc
6969
DESTINATION ${CMAKE_INSTALL_LIBDIR})
70-
install(FILES bpf_common.h bpf_module.h bcc_syms.h bcc_exception.h libbpf.h perf_reader.h BPF.h BPFTable.h shared_table.h COMPONENT libbcc
70+
install(FILES bpf_common.h bpf_module.h bcc_syms.h bcc_exception.h libbpf.h perf_reader.h BPF.h BPFTable.h shared_table.h table_desc.h COMPONENT libbcc
7171
DESTINATION include/bcc)
7272
install(DIRECTORY compat/linux/ COMPONENT libbcc
7373
DESTINATION include/bcc/compat/linux

src/cc/bpf_module.cc

+56-44
Original file line numberDiff line numberDiff line change
@@ -101,30 +101,26 @@ class MyMemoryManager : public SectionMemoryManager {
101101
map<string, tuple<uint8_t *, uintptr_t>> *sections_;
102102
};
103103

104-
BPFModule::BPFModule(unsigned flags)
105-
: flags_(flags), ctx_(new LLVMContext) {
104+
BPFModule::BPFModule(unsigned flags, TableStorage *ts)
105+
: flags_(flags), ctx_(new LLVMContext), ts_(ts) {
106106
InitializeNativeTarget();
107107
InitializeNativeTargetAsmPrinter();
108108
LLVMInitializeBPFTarget();
109109
LLVMInitializeBPFTargetMC();
110110
LLVMInitializeBPFTargetInfo();
111111
LLVMInitializeBPFAsmPrinter();
112112
LLVMLinkInMCJIT(); /* call empty function to force linking of MCJIT */
113+
if (!ts_) {
114+
local_ts_ = createSharedTableStorage();
115+
ts_ = &*local_ts_;
116+
}
113117
}
114118

115119
BPFModule::~BPFModule() {
116120
engine_.reset();
117121
rw_engine_.reset();
118122
ctx_.reset();
119-
if (tables_) {
120-
for (auto table : *tables_) {
121-
if (table.is_shared) {
122-
SharedTables::instance()->remove_fd(table.name);
123-
} else if (!table.is_extern) {
124-
close(table.fd);
125-
}
126-
}
127-
}
123+
ts_->DeletePrefix(Path({std::to_string((uintptr_t)this)}));
128124
}
129125

130126
static void debug_printf(Module *mod, IRBuilder<> &B, const string &fmt, vector<Value *> args) {
@@ -326,7 +322,8 @@ unique_ptr<ExecutionEngine> BPFModule::finalize_rw(unique_ptr<Module> m) {
326322
// load an entire c file as a module
327323
int BPFModule::load_cfile(const string &file, bool in_memory, const char *cflags[], int ncflags) {
328324
clang_loader_ = make_unique<ClangLoader>(&*ctx_, flags_);
329-
if (clang_loader_->parse(&mod_, &tables_, file, in_memory, cflags, ncflags))
325+
if (clang_loader_->parse(&mod_, *ts_, file, in_memory, cflags, ncflags,
326+
std::to_string((uintptr_t)this)))
330327
return -1;
331328
return 0;
332329
}
@@ -338,7 +335,7 @@ int BPFModule::load_cfile(const string &file, bool in_memory, const char *cflags
338335
// build an ExecutionEngine.
339336
int BPFModule::load_includes(const string &text) {
340337
clang_loader_ = make_unique<ClangLoader>(&*ctx_, flags_);
341-
if (clang_loader_->parse(&mod_, &tables_, text, true, nullptr, 0))
338+
if (clang_loader_->parse(&mod_, *ts_, text, true, nullptr, 0, ""))
342339
return -1;
343340
return 0;
344341
}
@@ -352,7 +349,10 @@ int BPFModule::annotate() {
352349
auto m = make_unique<Module>("sscanf", *ctx_);
353350

354351
size_t id = 0;
355-
for (auto &table : *tables_) {
352+
Path path({std::to_string((uintptr_t)this)});
353+
for (auto it = ts_->lower_bound(path), up = ts_->upper_bound(path); it != up; ++it) {
354+
TableDesc &table = it->second;
355+
tables_.push_back(&it->second);
356356
table_names_[table.name] = id++;
357357
GlobalValue *gvar = mod_->getNamedValue(table.name);
358358
if (!gvar) continue;
@@ -507,9 +507,7 @@ unsigned BPFModule::kern_version() const {
507507
return *(unsigned *)get<0>(section->second);
508508
}
509509

510-
size_t BPFModule::num_tables() const {
511-
return tables_->size();
512-
}
510+
size_t BPFModule::num_tables() const { return tables_.size(); }
513511

514512
size_t BPFModule::table_id(const string &name) const {
515513
auto it = table_names_.find(name);
@@ -522,46 +520,52 @@ int BPFModule::table_fd(const string &name) const {
522520
}
523521

524522
int BPFModule::table_fd(size_t id) const {
525-
if (id >= tables_->size()) return -1;
526-
return (*tables_)[id].fd;
523+
if (id >= tables_.size())
524+
return -1;
525+
return tables_[id]->fd;
527526
}
528527

529528
int BPFModule::table_type(const string &name) const {
530529
return table_type(table_id(name));
531530
}
532531

533532
int BPFModule::table_type(size_t id) const {
534-
if (id >= tables_->size()) return -1;
535-
return (*tables_)[id].type;
533+
if (id >= tables_.size())
534+
return -1;
535+
return tables_[id]->type;
536536
}
537537

538538
size_t BPFModule::table_max_entries(const string &name) const {
539539
return table_max_entries(table_id(name));
540540
}
541541

542542
size_t BPFModule::table_max_entries(size_t id) const {
543-
if (id >= tables_->size()) return 0;
544-
return (*tables_)[id].max_entries;
543+
if (id >= tables_.size())
544+
return 0;
545+
return tables_[id]->max_entries;
545546
}
546547

547548
int BPFModule::table_flags(const string &name) const {
548549
return table_flags(table_id(name));
549550
}
550551

551552
int BPFModule::table_flags(size_t id) const {
552-
if (id >= tables_->size()) return -1;
553-
return (*tables_)[id].flags;
553+
if (id >= tables_.size())
554+
return -1;
555+
return tables_[id]->flags;
554556
}
555557

556558
const char * BPFModule::table_name(size_t id) const {
557-
if (id >= tables_->size()) return nullptr;
558-
return (*tables_)[id].name.c_str();
559+
if (id >= tables_.size())
560+
return nullptr;
561+
return tables_[id]->name.c_str();
559562
}
560563

561564
const char * BPFModule::table_key_desc(size_t id) const {
562565
if (b_loader_) return nullptr;
563-
if (id >= tables_->size()) return nullptr;
564-
return (*tables_)[id].key_desc.c_str();
566+
if (id >= tables_.size())
567+
return nullptr;
568+
return tables_[id]->key_desc.c_str();
565569
}
566570

567571
const char * BPFModule::table_key_desc(const string &name) const {
@@ -570,24 +574,27 @@ const char * BPFModule::table_key_desc(const string &name) const {
570574

571575
const char * BPFModule::table_leaf_desc(size_t id) const {
572576
if (b_loader_) return nullptr;
573-
if (id >= tables_->size()) return nullptr;
574-
return (*tables_)[id].leaf_desc.c_str();
577+
if (id >= tables_.size())
578+
return nullptr;
579+
return tables_[id]->leaf_desc.c_str();
575580
}
576581

577582
const char * BPFModule::table_leaf_desc(const string &name) const {
578583
return table_leaf_desc(table_id(name));
579584
}
580585
size_t BPFModule::table_key_size(size_t id) const {
581-
if (id >= tables_->size()) return 0;
582-
return (*tables_)[id].key_size;
586+
if (id >= tables_.size())
587+
return 0;
588+
return tables_[id]->key_size;
583589
}
584590
size_t BPFModule::table_key_size(const string &name) const {
585591
return table_key_size(table_id(name));
586592
}
587593

588594
size_t BPFModule::table_leaf_size(size_t id) const {
589-
if (id >= tables_->size()) return 0;
590-
return (*tables_)[id].leaf_size;
595+
if (id >= tables_.size())
596+
return 0;
597+
return tables_[id]->leaf_size;
591598
}
592599
size_t BPFModule::table_leaf_size(const string &name) const {
593600
return table_leaf_size(table_id(name));
@@ -603,8 +610,9 @@ struct TableIterator {
603610
};
604611

605612
int BPFModule::table_key_printf(size_t id, char *buf, size_t buflen, const void *key) {
606-
if (id >= tables_->size()) return -1;
607-
const TableDesc &desc = (*tables_)[id];
613+
if (id >= tables_.size())
614+
return -1;
615+
const TableDesc &desc = *tables_[id];
608616
if (!desc.key_snprintf) {
609617
fprintf(stderr, "Key snprintf not available\n");
610618
return -1;
@@ -627,8 +635,9 @@ int BPFModule::table_key_printf(size_t id, char *buf, size_t buflen, const void
627635
}
628636

629637
int BPFModule::table_leaf_printf(size_t id, char *buf, size_t buflen, const void *leaf) {
630-
if (id >= tables_->size()) return -1;
631-
const TableDesc &desc = (*tables_)[id];
638+
if (id >= tables_.size())
639+
return -1;
640+
const TableDesc &desc = *tables_[id];
632641
if (!desc.leaf_snprintf) {
633642
fprintf(stderr, "Key snprintf not available\n");
634643
return -1;
@@ -651,8 +660,9 @@ int BPFModule::table_leaf_printf(size_t id, char *buf, size_t buflen, const void
651660
}
652661

653662
int BPFModule::table_key_scanf(size_t id, const char *key_str, void *key) {
654-
if (id >= tables_->size()) return -1;
655-
const TableDesc &desc = (*tables_)[id];
663+
if (id >= tables_.size())
664+
return -1;
665+
const TableDesc &desc = *tables_[id];
656666
if (!desc.key_sscanf) {
657667
fprintf(stderr, "Key sscanf not available\n");
658668
return -1;
@@ -672,8 +682,9 @@ int BPFModule::table_key_scanf(size_t id, const char *key_str, void *key) {
672682
}
673683

674684
int BPFModule::table_leaf_scanf(size_t id, const char *leaf_str, void *leaf) {
675-
if (id >= tables_->size()) return -1;
676-
const TableDesc &desc = (*tables_)[id];
685+
if (id >= tables_.size())
686+
return -1;
687+
const TableDesc &desc = *tables_[id];
677688
if (!desc.leaf_sscanf) {
678689
fprintf(stderr, "Key sscanf not available\n");
679690
return -1;
@@ -714,7 +725,8 @@ int BPFModule::load_b(const string &filename, const string &proto_filename) {
714725
return rc;
715726

716727
b_loader_.reset(new BLoader(flags_));
717-
if (int rc = b_loader_->parse(&*mod_, filename, proto_filename, &tables_))
728+
if (int rc =
729+
b_loader_->parse(&*mod_, filename, proto_filename, *ts_, std::to_string((uintptr_t)this)))
718730
return rc;
719731
if (int rc = annotate())
720732
return rc;

src/cc/bpf_module.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ class Type;
3131
}
3232

3333
namespace ebpf {
34-
struct TableDesc;
34+
class TableDesc;
35+
class TableStorage;
3536
class BLoader;
3637
class ClangLoader;
3738

@@ -52,7 +53,7 @@ class BPFModule {
5253
int kbuild_flags(const char *uname_release, std::vector<std::string> *cflags);
5354
int run_pass_manager(llvm::Module &mod);
5455
public:
55-
BPFModule(unsigned flags);
56+
BPFModule(unsigned flags, TableStorage *ts = nullptr);
5657
~BPFModule();
5758
int load_b(const std::string &filename, const std::string &proto_filename);
5859
int load_c(const std::string &filename, const char *cflags[], int ncflags);
@@ -99,11 +100,13 @@ class BPFModule {
99100
std::unique_ptr<BLoader> b_loader_;
100101
std::unique_ptr<ClangLoader> clang_loader_;
101102
std::map<std::string, std::tuple<uint8_t *, uintptr_t>> sections_;
102-
std::unique_ptr<std::vector<TableDesc>> tables_;
103+
std::vector<TableDesc *> tables_;
103104
std::map<std::string, size_t> table_names_;
104105
std::vector<std::string> function_names_;
105106
std::map<llvm::Type *, llvm::Function *> readers_;
106107
std::map<llvm::Type *, llvm::Function *> writers_;
108+
TableStorage *ts_;
109+
std::unique_ptr<TableStorage> local_ts_;
107110
};
108111

109112
} // namespace ebpf

0 commit comments

Comments
 (0)