Skip to content

Commit

Permalink
Add node builtin to get NUMA Node ID, as follows:
Browse files Browse the repository at this point in the history
    $ sudo ./bpftrace -e 'BEGIN{printf("node = %d\n", node);}'
    Attaching 1 probe...
    node = 0

It't useful in multi-node system, like `numactl --hardware`:

    $ numactl --hardware
    [...]
    node   0   1   2   3   4   5   6   7
      0:  10  16  16  16  28  28  22  28
      1:  16  10  16  16  28  28  28  22
      2:  16  16  10  16  22  28  28  28
      3:  16  16  16  10  28  22  28  28
      4:  28  28  22  28  10  16  16  16
      5:  28  28  28  22  16  10  16  16
      6:  22  28  28  28  16  16  10  16
      7:  28  22  28  28  16  16  16  10
  • Loading branch information
Rtoax committed Mar 30, 2022
1 parent c56676c commit ffddc31
Show file tree
Hide file tree
Showing 9 changed files with 39 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/reference_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -1831,6 +1831,7 @@ NetworkManager:1155 /var/lib/sss/mc/passwd (deleted)
- `gid` - Group ID
- `nsecs` - Nanosecond timestamp
- `elapsed` - Nanoseconds since bpftrace initialization
- `node` - NUMA Node ID
- `cpu` - Processor ID
- `comm` - Process name
- `kstack` - Kernel stack trace
Expand Down
13 changes: 13 additions & 0 deletions src/ast/irbuilderbpf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,19 @@ CallInst *IRBuilderBPF::CreateGetUidGid()
return createCall(getuidgid_func, {}, "get_uid_gid");
}

CallInst *IRBuilderBPF::CreateGetNodeId()
{
// u32 bpf_get_numa_node_id(void)
// Return: NUMA Node ID
FunctionType *getnodeid_func_type = FunctionType::get(getInt64Ty(), false);
PointerType *getnodeid_func_ptr_type = PointerType::get(getnodeid_func_type, 0);
Constant *getnodeid_func = ConstantExpr::getCast(
Instruction::IntToPtr,
getInt64(libbpf::BPF_FUNC_get_numa_node_id),
getnodeid_func_ptr_type);
return createCall(getnodeid_func, {}, "get_node_id");
}

CallInst *IRBuilderBPF::CreateGetCpuId()
{
// u32 bpf_raw_smp_processor_id(void)
Expand Down
1 change: 1 addition & 0 deletions src/ast/irbuilderbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ class IRBuilderBPF : public IRBuilder<>
CallInst *CreateGetPidTgid();
CallInst *CreateGetCurrentCgroupId();
CallInst *CreateGetUidGid();
CallInst *CreateGetNodeId();
CallInst *CreateGetCpuId();
CallInst *CreateGetCurrentTask();
CallInst *CreateGetRandom();
Expand Down
4 changes: 4 additions & 0 deletions src/ast/passes/codegen_llvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,10 @@ void CodegenLLVM::visit(Builtin &builtin)
expr_ = b_.CreateLShr(uidgid, 32);
}
}
else if (builtin.ident == "node")
{
expr_ = b_.CreateGetNodeId();
}
else if (builtin.ident == "cpu")
{
expr_ = b_.CreateGetCpuId();
Expand Down
2 changes: 1 addition & 1 deletion src/ast/passes/semantic_analyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ void SemanticAnalyser::visit(Builtin &builtin)
builtin.ident == "pid" || builtin.ident == "tid" ||
builtin.ident == "cgroup" || builtin.ident == "uid" ||
builtin.ident == "gid" || builtin.ident == "cpu" ||
builtin.ident == "rand")
builtin.ident == "rand" || builtin.ident == "node")
{
builtin.type = CreateUInt64();
if (builtin.ident == "cgroup" &&
Expand Down
2 changes: 1 addition & 1 deletion src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ hspace [ \t]
vspace [\n\r]
space {hspace}|{vspace}
path :(\\.|[_\-\./a-zA-Z0-9#\*])+
builtin arg[0-9]|args|cgroup|comm|cpid|cpu|ctx|curtask|elapsed|func|gid|nsecs|pid|probe|rand|retval|sarg[0-9]|tid|uid|username
builtin arg[0-9]|args|cgroup|comm|cpid|node|cpu|ctx|curtask|elapsed|func|gid|nsecs|pid|probe|rand|retval|sarg[0-9]|tid|uid|username
call avg|buf|cat|cgroupid|clear|count|delete|exit|hist|join|kaddr|kptr|ksym|lhist|macaddr|max|min|ntop|override|print|printf|cgroup_path|reg|signal|sizeof|stats|str|strftime|strncmp|sum|system|time|uaddr|uptr|usym|zero|path|unwatch

/* Don't add to this! Use builtin OR call not both */
Expand Down
16 changes: 16 additions & 0 deletions tests/codegen/builtin_node.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#include "common.h"

namespace bpftrace {
namespace test {
namespace codegen {

TEST(codegen, builtin_node)
{
test("kprobe:f { @x = node }",

NAME);
}

} // namespace codegen
} // namespace test
} // namespace bpftrace
1 change: 1 addition & 0 deletions tests/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ TEST(Parser, builtin_variables)
test("kprobe:f { gid }", "Program\n kprobe:f\n builtin: gid\n");
test("kprobe:f { nsecs }", "Program\n kprobe:f\n builtin: nsecs\n");
test("kprobe:f { elapsed }", "Program\n kprobe:f\n builtin: elapsed\n");
test("kprobe:f { node }", "Program\n kprobe:f\n builtin: node\n");
test("kprobe:f { cpu }", "Program\n kprobe:f\n builtin: cpu\n");
test("kprobe:f { curtask }", "Program\n kprobe:f\n builtin: curtask\n");
test("kprobe:f { rand }", "Program\n kprobe:f\n builtin: rand\n");
Expand Down
1 change: 1 addition & 0 deletions tests/semantic_analyser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ TEST(semantic_analyser, builtin_variables)
test("kprobe:f { gid }", 0);
test("kprobe:f { nsecs }", 0);
test("kprobe:f { elapsed }", 0);
test("kprobe:f { node }", 0);
test("kprobe:f { cpu }", 0);
test("kprobe:f { curtask }", 0);
test("kprobe:f { rand }", 0);
Expand Down

0 comments on commit ffddc31

Please sign in to comment.