Rebase to the latest version
Rebase bcc to v0.26.0, fix slabratetop and readahead issues. Resolves: rhbz#2117708 Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
This commit is contained in:
parent
4489dbca3c
commit
07de9f90bf
1
.gitignore
vendored
1
.gitignore
vendored
@ -18,3 +18,4 @@
|
|||||||
/bcc-0.22.0.tar.gz
|
/bcc-0.22.0.tar.gz
|
||||||
/bcc-0.24.0.tar.gz
|
/bcc-0.24.0.tar.gz
|
||||||
/bcc-0.25.0.tar.gz
|
/bcc-0.25.0.tar.gz
|
||||||
|
/bcc-0.26.0.tar.gz
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
From 62ded75dca77dc53cbfb2a25ba825510de7600a0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yonghong Song <yhs@fb.com>
|
|
||||||
Date: Sat, 13 Aug 2022 17:50:07 -0700
|
|
||||||
Subject: [PATCH] Fix bpf_pseudo_fd() type conversion error
|
|
||||||
|
|
||||||
With llvm15 and llvm16, the following command line
|
|
||||||
sudo ./trace.py 'smp_call_function_single "%K", arg1'
|
|
||||||
will cause error:
|
|
||||||
/virtual/main.c:60:36: error: incompatible integer to pointer conversion passing 'u64'
|
|
||||||
(aka 'unsigned long long') to parameter of type 'void *' [-Wint-conversion]
|
|
||||||
bpf_perf_event_output(ctx, bpf_pseudo_fd(1, -1), CUR_CPU_IDENTIFIER, &__data, sizeof(__data));
|
|
||||||
^~~~~~~~~~~~~~~~~~~~
|
|
||||||
1 error generated.
|
|
||||||
Failed to compile BPF module <text>
|
|
||||||
|
|
||||||
In helpers.h, we have
|
|
||||||
u64 bpf_pseudo_fd(u64, u64) asm("llvm.bpf.pseudo");
|
|
||||||
Apparently, <= llvm14 can tolerate u64 -> 'void *' conversion, but
|
|
||||||
llvm15 by default will cause an error.
|
|
||||||
|
|
||||||
Let us explicitly convert bpf_pseudo_fd to 'void *' to avoid
|
|
||||||
such errors.
|
|
||||||
|
|
||||||
Signed-off-by: Yonghong Song <yhs@fb.com>
|
|
||||||
---
|
|
||||||
src/cc/frontends/clang/b_frontend_action.cc | 10 +++++-----
|
|
||||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/cc/frontends/clang/b_frontend_action.cc b/src/cc/frontends/clang/b_frontend_action.cc
|
|
||||||
index a4e05b16..dbeba3e4 100644
|
|
||||||
--- a/src/cc/frontends/clang/b_frontend_action.cc
|
|
||||||
+++ b/src/cc/frontends/clang/b_frontend_action.cc
|
|
||||||
@@ -957,7 +957,7 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
|
|
||||||
string arg0 = rewriter_.getRewrittenText(expansionRange(Call->getArg(0)->getSourceRange()));
|
|
||||||
string args_other = rewriter_.getRewrittenText(expansionRange(SourceRange(GET_BEGINLOC(Call->getArg(1)),
|
|
||||||
GET_ENDLOC(Call->getArg(2)))));
|
|
||||||
- txt = "bpf_perf_event_output(" + arg0 + ", bpf_pseudo_fd(1, " + fd + ")";
|
|
||||||
+ txt = "bpf_perf_event_output(" + arg0 + ", (void *)bpf_pseudo_fd(1, " + fd + ")";
|
|
||||||
txt += ", CUR_CPU_IDENTIFIER, " + args_other + ")";
|
|
||||||
|
|
||||||
// e.g.
|
|
||||||
@@ -986,7 +986,7 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
|
|
||||||
string meta_len = rewriter_.getRewrittenText(expansionRange(Call->getArg(3)->getSourceRange()));
|
|
||||||
txt = "bpf_perf_event_output(" +
|
|
||||||
skb + ", " +
|
|
||||||
- "bpf_pseudo_fd(1, " + fd + "), " +
|
|
||||||
+ "(void *)bpf_pseudo_fd(1, " + fd + "), " +
|
|
||||||
"((__u64)" + skb_len + " << 32) | BPF_F_CURRENT_CPU, " +
|
|
||||||
meta + ", " +
|
|
||||||
meta_len + ");";
|
|
||||||
@@ -1006,12 +1006,12 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
|
|
||||||
string keyp = rewriter_.getRewrittenText(expansionRange(Call->getArg(1)->getSourceRange()));
|
|
||||||
string flag = rewriter_.getRewrittenText(expansionRange(Call->getArg(2)->getSourceRange()));
|
|
||||||
txt = "bpf_" + string(memb_name) + "(" + ctx + ", " +
|
|
||||||
- "bpf_pseudo_fd(1, " + fd + "), " + keyp + ", " + flag + ");";
|
|
||||||
+ "(void *)bpf_pseudo_fd(1, " + fd + "), " + keyp + ", " + flag + ");";
|
|
||||||
} else if (memb_name == "ringbuf_output") {
|
|
||||||
string name = string(Ref->getDecl()->getName());
|
|
||||||
string args = rewriter_.getRewrittenText(expansionRange(SourceRange(GET_BEGINLOC(Call->getArg(0)),
|
|
||||||
GET_ENDLOC(Call->getArg(2)))));
|
|
||||||
- txt = "bpf_ringbuf_output(bpf_pseudo_fd(1, " + fd + ")";
|
|
||||||
+ txt = "bpf_ringbuf_output((void *)bpf_pseudo_fd(1, " + fd + ")";
|
|
||||||
txt += ", " + args + ")";
|
|
||||||
|
|
||||||
// e.g.
|
|
||||||
@@ -1033,7 +1033,7 @@ bool BTypeVisitor::VisitCallExpr(CallExpr *Call) {
|
|
||||||
} else if (memb_name == "ringbuf_reserve") {
|
|
||||||
string name = string(Ref->getDecl()->getName());
|
|
||||||
string arg0 = rewriter_.getRewrittenText(expansionRange(Call->getArg(0)->getSourceRange()));
|
|
||||||
- txt = "bpf_ringbuf_reserve(bpf_pseudo_fd(1, " + fd + ")";
|
|
||||||
+ txt = "bpf_ringbuf_reserve((void *)bpf_pseudo_fd(1, " + fd + ")";
|
|
||||||
txt += ", " + arg0 + ", 0)"; // Flags in reserve are meaningless
|
|
||||||
} else if (memb_name == "ringbuf_discard") {
|
|
||||||
string name = string(Ref->getDecl()->getName());
|
|
||||||
--
|
|
||||||
2.37.3
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
|||||||
From ff39c45fb063ec448e7aff8b6cc83cb5c625e573 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Jerome Marchand <jmarchan@redhat.com>
|
|
||||||
Date: Wed, 26 Oct 2022 14:41:54 +0200
|
|
||||||
Subject: [PATCH] Fix clang 15 int to pointer conversion errors
|
|
||||||
|
|
||||||
Since version 15, clang issues error for implicit conversion of
|
|
||||||
integer to pointer. Several tools are broken. This patch add explicit
|
|
||||||
pointer cast where needed.
|
|
||||||
|
|
||||||
Fixes the following errors:
|
|
||||||
/virtual/main.c:37:18: error: incompatible integer to pointer conversion initializing 'struct request *' with an expression of type 'unsigned long' [-Wint-conversion]
|
|
||||||
struct request *req = ctx->di;
|
|
||||||
^ ~~~~~~~
|
|
||||||
/virtual/main.c:49:18: error: incompatible integer to pointer conversion initializing 'struct request *' with an expression of type 'unsigned long' [-Wint-conversion]
|
|
||||||
struct request *req = ctx->di;
|
|
||||||
^ ~~~~~~~
|
|
||||||
2 errors generated.
|
|
||||||
|
|
||||||
/virtual/main.c:73:19: error: incompatible integer to pointer conversion initializing 'struct pt_regs *' with an expression of type 'unsigned long' [-Wint-conversion]
|
|
||||||
struct pt_regs * __ctx = ctx->di;
|
|
||||||
^ ~~~~~~~
|
|
||||||
/virtual/main.c:100:240: error: incompatible integer to pointer conversion passing 'u64' (aka 'unsigned long long') to parameter of type 'const void *' [-Wint-conversion]
|
|
||||||
data.ppid = ({ typeof(pid_t) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (u64)&({ typeof(struct task_struct *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (u64)&task->real_parent); _val; })->tgid); _val; });
|
|
||||||
^~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
/virtual/main.c:100:118: error: incompatible integer to pointer conversion passing 'u64' (aka 'unsigned long long') to parameter of type 'const void *' [-Wint-conversion]
|
|
||||||
data.ppid = ({ typeof(pid_t) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (u64)&({ typeof(struct task_struct *) _val; __builtin_memset(&_val, 0, sizeof(_val)); bpf_probe_read(&_val, sizeof(_val), (u64)&task->real_parent); _val; })->tgid); _val; });
|
|
||||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
|
||||||
---
|
|
||||||
src/cc/frontends/clang/b_frontend_action.cc | 18 +++++++++---------
|
|
||||||
1 file changed, 9 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/cc/frontends/clang/b_frontend_action.cc b/src/cc/frontends/clang/b_frontend_action.cc
|
|
||||||
index d0cf995e..9939011c 100644
|
|
||||||
--- a/src/cc/frontends/clang/b_frontend_action.cc
|
|
||||||
+++ b/src/cc/frontends/clang/b_frontend_action.cc
|
|
||||||
@@ -521,9 +521,9 @@ bool ProbeVisitor::VisitUnaryOperator(UnaryOperator *E) {
|
|
||||||
string pre, post;
|
|
||||||
pre = "({ typeof(" + E->getType().getAsString() + ") _val; __builtin_memset(&_val, 0, sizeof(_val));";
|
|
||||||
if (cannot_fall_back_safely)
|
|
||||||
- pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (u64)";
|
|
||||||
+ pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (void *)";
|
|
||||||
else
|
|
||||||
- pre += " bpf_probe_read(&_val, sizeof(_val), (u64)";
|
|
||||||
+ pre += " bpf_probe_read(&_val, sizeof(_val), (void *)";
|
|
||||||
post = "); _val; })";
|
|
||||||
rewriter_.ReplaceText(expansionLoc(E->getOperatorLoc()), 1, pre);
|
|
||||||
rewriter_.InsertTextAfterToken(expansionLoc(GET_ENDLOC(sub)), post);
|
|
||||||
@@ -585,9 +585,9 @@ bool ProbeVisitor::VisitMemberExpr(MemberExpr *E) {
|
|
||||||
string pre, post;
|
|
||||||
pre = "({ typeof(" + E->getType().getAsString() + ") _val; __builtin_memset(&_val, 0, sizeof(_val));";
|
|
||||||
if (cannot_fall_back_safely)
|
|
||||||
- pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (u64)&";
|
|
||||||
+ pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (void *)&";
|
|
||||||
else
|
|
||||||
- pre += " bpf_probe_read(&_val, sizeof(_val), (u64)&";
|
|
||||||
+ pre += " bpf_probe_read(&_val, sizeof(_val), (void *)&";
|
|
||||||
post = rhs + "); _val; })";
|
|
||||||
rewriter_.InsertText(expansionLoc(GET_BEGINLOC(E)), pre);
|
|
||||||
rewriter_.ReplaceText(expansionRange(SourceRange(member, GET_ENDLOC(E))), post);
|
|
||||||
@@ -639,9 +639,9 @@ bool ProbeVisitor::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
|
|
||||||
|
|
||||||
pre = "({ typeof(" + E->getType().getAsString() + ") _val; __builtin_memset(&_val, 0, sizeof(_val));";
|
|
||||||
if (cannot_fall_back_safely)
|
|
||||||
- pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (u64)((";
|
|
||||||
+ pre += " bpf_probe_read_kernel(&_val, sizeof(_val), (void *)((";
|
|
||||||
else
|
|
||||||
- pre += " bpf_probe_read(&_val, sizeof(_val), (u64)((";
|
|
||||||
+ pre += " bpf_probe_read(&_val, sizeof(_val), (void *)((";
|
|
||||||
if (isMemberDereference(base)) {
|
|
||||||
pre += "&";
|
|
||||||
// If the base of the array subscript is a member dereference, we'll rewrite
|
|
||||||
@@ -751,8 +751,8 @@ void BTypeVisitor::genParamDirectAssign(FunctionDecl *D, string& preamble,
|
|
||||||
arg->addAttr(UnavailableAttr::CreateImplicit(C, "ptregs"));
|
|
||||||
size_t d = idx - 1;
|
|
||||||
const char *reg = calling_conv_regs[d];
|
|
||||||
- preamble += " " + text + " = " + fn_args_[0]->getName().str() + "->" +
|
|
||||||
- string(reg) + ";";
|
|
||||||
+ preamble += " " + text + " = (" + arg->getType().getAsString() + ")" +
|
|
||||||
+ fn_args_[0]->getName().str() + "->" + string(reg) + ";";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -766,7 +766,7 @@ void BTypeVisitor::genParamIndirectAssign(FunctionDecl *D, string& preamble,
|
|
||||||
|
|
||||||
if (idx == 0) {
|
|
||||||
new_ctx = "__" + arg->getName().str();
|
|
||||||
- preamble += " struct pt_regs * " + new_ctx + " = " +
|
|
||||||
+ preamble += " struct pt_regs * " + new_ctx + " = (void *)" +
|
|
||||||
arg->getName().str() + "->" +
|
|
||||||
string(calling_conv_regs[0]) + ";";
|
|
||||||
} else {
|
|
||||||
--
|
|
||||||
2.37.3
|
|
||||||
|
|
11
bcc.spec
11
bcc.spec
@ -24,14 +24,14 @@
|
|||||||
|
|
||||||
|
|
||||||
Name: bcc
|
Name: bcc
|
||||||
Version: 0.25.0
|
Version: 0.26.0
|
||||||
Release: 2%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: BPF Compiler Collection (BCC)
|
Summary: BPF Compiler Collection (BCC)
|
||||||
License: ASL 2.0
|
License: ASL 2.0
|
||||||
URL: https://github.com/iovisor/bcc
|
URL: https://github.com/iovisor/bcc
|
||||||
Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
|
Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
|
||||||
Patch0: Fix-bpf_pseudo_fd-type-conversion-error.patch
|
Patch0: tools-slabratetop-Fix-error-incomplete-definition-of.patch
|
||||||
Patch1: Fix-clang-15-int-to-pointer-conversion-errors.patch
|
Patch1: tools-readahead-Fix-Failed-to-attach-BPF-program-ent.patch
|
||||||
|
|
||||||
# Arches will be included as upstream support is added and dependencies are
|
# Arches will be included as upstream support is added and dependencies are
|
||||||
# satisfied in the respective arches
|
# satisfied in the respective arches
|
||||||
@ -239,6 +239,9 @@ cp -a libbpf-tools/tmp-install/bin/* %{buildroot}/%{_sbindir}/
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Fri Mar 10 2023 Jerome Marchand <jmarchan@redhat.com> - 0.26.0-1
|
||||||
|
- Rebase to the latest release version
|
||||||
|
|
||||||
* Wed Jan 18 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0.25.0-2
|
* Wed Jan 18 2023 Fedora Release Engineering <releng@fedoraproject.org> - 0.25.0-2
|
||||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
|
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
|
||||||
|
|
||||||
|
2
sources
2
sources
@ -1 +1 @@
|
|||||||
SHA512 (bcc-0.25.0.tar.gz) = 9f71f6c21d1f66054985562168d5848352f5029383e9c65c907a6f044258bc23df842cc65db20bfaaf33789e69c9b8e7b606a32dc882cbdf093b71768c8b521d
|
SHA512 (bcc-0.26.0.tar.gz) = 394872a5780cc7651c91b584ccc13f18f64585b5843364433c042d9ded70faaf15a2e1125d51498508427b089f5bf826f13004d15a1892aada1a5f228a2a8adb
|
||||||
|
159
tools-readahead-Fix-Failed-to-attach-BPF-program-ent.patch
Normal file
159
tools-readahead-Fix-Failed-to-attach-BPF-program-ent.patch
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
From c5152f68588d2195295e66daccff2126de1c35cf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rong Tao <rongtao@cestc.cn>
|
||||||
|
Date: Mon, 30 Jan 2023 17:39:35 +0800
|
||||||
|
Subject: [PATCH] tools/readahead: Fix: Failed to attach BPF program
|
||||||
|
entry__do_page_cache_readahead
|
||||||
|
|
||||||
|
since commit 56a4d67c264e("mm/readahead: Switch to page_cache_ra_order") switch
|
||||||
|
do_page_cache_ra() to page_cache_ra_order() (v5.17), and commit bb3c579e25e5
|
||||||
|
("mm/filemap: Add filemap_alloc_folio") swap __page_cache_alloc() to
|
||||||
|
filemap_alloc_folio() (since v5.15)
|
||||||
|
|
||||||
|
Reprocude the error(fedora37, 6.1.7-200.fc37.aarch64):
|
||||||
|
|
||||||
|
$ sudo ./readahead.py
|
||||||
|
cannot attach kprobe, probe entry may not exist
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "/home/rongtao/Git/bcc/tools/./readahead.py", line 159, in <module>
|
||||||
|
b.attach_kprobe(event=ra_event, fn_name="entry__do_page_cache_readahead")
|
||||||
|
File "/usr/lib/python3.11/site-packages/bcc/__init__.py", line 840, in attach_kprobe
|
||||||
|
raise Exception("Failed to attach BPF program %s to kprobe %s" %
|
||||||
|
Exception: Failed to attach BPF program b'entry__do_page_cache_readahead' to kprobe b'do_page_cache_ra'
|
||||||
|
|
||||||
|
Signed-off-by: Rong Tao <rongtao@cestc.cn>
|
||||||
|
---
|
||||||
|
tools/readahead.py | 69 +++++++++++++++++++++++++++++++++++++---------
|
||||||
|
1 file changed, 56 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tools/readahead.py b/tools/readahead.py
|
||||||
|
index f2afdcb3..adad2ea8 100755
|
||||||
|
--- a/tools/readahead.py
|
||||||
|
+++ b/tools/readahead.py
|
||||||
|
@@ -12,6 +12,7 @@
|
||||||
|
#
|
||||||
|
# 20-Aug-2020 Suchakra Sharma Ported from bpftrace to BCC
|
||||||
|
# 17-Sep-2021 Hengqi Chen Migrated to kfunc
|
||||||
|
+# 30-Jan-2023 Rong Tao Support more kfunc/kprobe, introduce folio
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from bcc import BPF
|
||||||
|
@@ -38,6 +39,7 @@ args = parser.parse_args()
|
||||||
|
bpf_text = """
|
||||||
|
#include <uapi/linux/ptrace.h>
|
||||||
|
#include <linux/mm_types.h>
|
||||||
|
+#include <linux/mm.h>
|
||||||
|
|
||||||
|
BPF_HASH(flag, u32, u8); // used to track if we are in do_page_cache_readahead()
|
||||||
|
BPF_HASH(birth, struct page*, u64); // used to track timestamps of cache alloc'ed page
|
||||||
|
@@ -65,7 +67,7 @@ int exit__do_page_cache_readahead(struct pt_regs *ctx) {
|
||||||
|
int exit__page_cache_alloc(struct pt_regs *ctx) {
|
||||||
|
u32 pid;
|
||||||
|
u64 ts;
|
||||||
|
- struct page *retval = (struct page*) PT_REGS_RC(ctx);
|
||||||
|
+ struct page *retval = (struct page*) GET_RETVAL_PAGE;
|
||||||
|
u32 zero = 0; // static key for accessing pages[0]
|
||||||
|
pid = bpf_get_current_pid_tgid();
|
||||||
|
u8 *f = flag.lookup(&pid);
|
||||||
|
@@ -111,6 +113,23 @@ KRETFUNC_PROBE(RA_FUNC)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+KFUNC_PROBE(mark_page_accessed, struct page *arg0)
|
||||||
|
+{
|
||||||
|
+ u64 ts, delta;
|
||||||
|
+ u32 zero = 0; // static key for accessing pages[0]
|
||||||
|
+ u64 *bts = birth.lookup(&arg0);
|
||||||
|
+
|
||||||
|
+ if (bts != NULL) {
|
||||||
|
+ delta = bpf_ktime_get_ns() - *bts;
|
||||||
|
+ dist.atomic_increment(bpf_log2l(delta/1000000));
|
||||||
|
+ pages.atomic_increment(zero, -1);
|
||||||
|
+ birth.delete(&arg0); // remove the entry from hashmap
|
||||||
|
+ }
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+"""
|
||||||
|
+
|
||||||
|
+bpf_text_kfunc_cache_alloc_ret_page = """
|
||||||
|
KRETFUNC_PROBE(__page_cache_alloc, gfp_t gfp, struct page *retval)
|
||||||
|
{
|
||||||
|
u64 ts;
|
||||||
|
@@ -125,18 +144,22 @@ KRETFUNC_PROBE(__page_cache_alloc, gfp_t gfp, struct page *retval)
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+"""
|
||||||
|
|
||||||
|
-KFUNC_PROBE(mark_page_accessed, struct page *arg0)
|
||||||
|
+bpf_text_kfunc_cache_alloc_ret_folio = """
|
||||||
|
+KRETFUNC_PROBE(filemap_alloc_folio, gfp_t gfp, unsigned int order,
|
||||||
|
+ struct folio *retval)
|
||||||
|
{
|
||||||
|
- u64 ts, delta;
|
||||||
|
+ u64 ts;
|
||||||
|
u32 zero = 0; // static key for accessing pages[0]
|
||||||
|
- u64 *bts = birth.lookup(&arg0);
|
||||||
|
+ u32 pid = bpf_get_current_pid_tgid();
|
||||||
|
+ u8 *f = flag.lookup(&pid);
|
||||||
|
+ struct page *page = folio_page(retval, 0);
|
||||||
|
|
||||||
|
- if (bts != NULL) {
|
||||||
|
- delta = bpf_ktime_get_ns() - *bts;
|
||||||
|
- dist.atomic_increment(bpf_log2l(delta/1000000));
|
||||||
|
- pages.atomic_increment(zero, -1);
|
||||||
|
- birth.delete(&arg0); // remove the entry from hashmap
|
||||||
|
+ if (f != NULL && *f == 1) {
|
||||||
|
+ ts = bpf_ktime_get_ns();
|
||||||
|
+ birth.update(&page, &ts);
|
||||||
|
+ pages.atomic_increment(zero);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -145,20 +168,40 @@ KFUNC_PROBE(mark_page_accessed, struct page *arg0)
|
||||||
|
if BPF.support_kfunc():
|
||||||
|
if BPF.get_kprobe_functions(b"__do_page_cache_readahead"):
|
||||||
|
ra_func = "__do_page_cache_readahead"
|
||||||
|
- else:
|
||||||
|
+ elif BPF.get_kprobe_functions(b"do_page_cache_ra"):
|
||||||
|
ra_func = "do_page_cache_ra"
|
||||||
|
+ elif BPF.get_kprobe_functions(b"page_cache_ra_order"):
|
||||||
|
+ ra_func = "page_cache_ra_order"
|
||||||
|
+ else:
|
||||||
|
+ print("Not found any kfunc.")
|
||||||
|
+ exit()
|
||||||
|
bpf_text += bpf_text_kfunc.replace("RA_FUNC", ra_func)
|
||||||
|
+ if BPF.get_kprobe_functions(b"__page_cache_alloc"):
|
||||||
|
+ bpf_text += bpf_text_kfunc_cache_alloc_ret_page
|
||||||
|
+ else:
|
||||||
|
+ bpf_text += bpf_text_kfunc_cache_alloc_ret_folio
|
||||||
|
b = BPF(text=bpf_text)
|
||||||
|
else:
|
||||||
|
bpf_text += bpf_text_kprobe
|
||||||
|
- b = BPF(text=bpf_text)
|
||||||
|
if BPF.get_kprobe_functions(b"__do_page_cache_readahead"):
|
||||||
|
ra_event = "__do_page_cache_readahead"
|
||||||
|
- else:
|
||||||
|
+ elif BPF.get_kprobe_functions(b"do_page_cache_ra"):
|
||||||
|
ra_event = "do_page_cache_ra"
|
||||||
|
+ elif BPF.get_kprobe_functions(b"page_cache_ra_order"):
|
||||||
|
+ ra_event = "page_cache_ra_order"
|
||||||
|
+ else:
|
||||||
|
+ print("Not found any kprobe.")
|
||||||
|
+ exit()
|
||||||
|
+ if BPF.get_kprobe_functions(b"__page_cache_alloc"):
|
||||||
|
+ cache_func = "__page_cache_alloc"
|
||||||
|
+ bpf_text = bpf_text.replace('GET_RETVAL_PAGE', 'PT_REGS_RC(ctx)')
|
||||||
|
+ else:
|
||||||
|
+ cache_func = "filemap_alloc_folio"
|
||||||
|
+ bpf_text = bpf_text.replace('GET_RETVAL_PAGE', 'folio_page((struct folio *)PT_REGS_RC(ctx), 0)')
|
||||||
|
+ b = BPF(text=bpf_text)
|
||||||
|
b.attach_kprobe(event=ra_event, fn_name="entry__do_page_cache_readahead")
|
||||||
|
b.attach_kretprobe(event=ra_event, fn_name="exit__do_page_cache_readahead")
|
||||||
|
- b.attach_kretprobe(event="__page_cache_alloc", fn_name="exit__page_cache_alloc")
|
||||||
|
+ b.attach_kretprobe(event=cache_func, fn_name="exit__page_cache_alloc")
|
||||||
|
b.attach_kprobe(event="mark_page_accessed", fn_name="entry_mark_page_accessed")
|
||||||
|
|
||||||
|
# header
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
140
tools-slabratetop-Fix-error-incomplete-definition-of.patch
Normal file
140
tools-slabratetop-Fix-error-incomplete-definition-of.patch
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
From 01b7a5320857676f4f5b610db588d4e7d14a2372 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Rong Tao <rongtao@cestc.cn>
|
||||||
|
Date: Sun, 22 Jan 2023 15:44:46 +0800
|
||||||
|
Subject: [PATCH] tools/slabratetop: Fix error: incomplete definition of type
|
||||||
|
'struct slab'
|
||||||
|
|
||||||
|
kernel commit 40f3bf0cb04c("mm: Convert struct page to struct slab in functions
|
||||||
|
used by other subsystems") introduce slab_address() function, commit 6e48a966dfd1
|
||||||
|
("mm/kasan: Convert to struct folio and struct slab") linux/kasan.h adds a
|
||||||
|
dependency on the slab struct, This leads to the following problems:
|
||||||
|
|
||||||
|
$ sudo ./slabratetop.py
|
||||||
|
In file included from /virtual/main.c:13:
|
||||||
|
include/linux/slub_def.h:162:26: warning: call to undeclared function 'slab_address';
|
||||||
|
ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
|
||||||
|
void *object = x - (x - slab_address(slab)) % cache->size;
|
||||||
|
^
|
||||||
|
include/linux/slub_def.h:162:46: error: invalid operands to binary expression ('void *' and 'unsigned int')
|
||||||
|
void *object = x - (x - slab_address(slab)) % cache->size;
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~
|
||||||
|
include/linux/slub_def.h:164:8: error: incomplete definition of type 'struct slab'
|
||||||
|
(slab->objects - 1) * cache->size;
|
||||||
|
~~~~^
|
||||||
|
include/linux/kasan.h:13:8: note: forward declaration of 'struct slab'
|
||||||
|
struct slab;
|
||||||
|
^
|
||||||
|
...
|
||||||
|
|
||||||
|
At first, I wanted to fix this with a kernel patch [1], however, bcc as a
|
||||||
|
downstream project of the kernel, this issue should be solved inside the bcc
|
||||||
|
project. This is agreed by kernel maintainer and bcc maintainer @yonghong-song.
|
||||||
|
|
||||||
|
This solution is provided by @yonghong-song [0].
|
||||||
|
|
||||||
|
[0] https://github.com/iovisor/bcc/issues/4438
|
||||||
|
[1] https://lore.kernel.org/all/tencent_ABA832E296819D1053D6C625ADCAF76BC706@qq.com/
|
||||||
|
|
||||||
|
Signed-off-by: Rong Tao <rongtao@cestc.cn>
|
||||||
|
Signed-off-by: Yonghong Song <yhs@fb.com>
|
||||||
|
---
|
||||||
|
tools/slabratetop.py | 76 ++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 76 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/tools/slabratetop.py b/tools/slabratetop.py
|
||||||
|
index ac44b2bd..8fbcac5e 100755
|
||||||
|
--- a/tools/slabratetop.py
|
||||||
|
+++ b/tools/slabratetop.py
|
||||||
|
@@ -14,6 +14,9 @@
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License")
|
||||||
|
#
|
||||||
|
# 15-Oct-2016 Brendan Gregg Created this.
|
||||||
|
+# 23-Jan-2023 Rong Tao Introduce kernel internal data structure and
|
||||||
|
+# functions to temporarily solve problem for
|
||||||
|
+# >=5.16(TODO: fix this workaround)
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
from bcc import BPF
|
||||||
|
@@ -65,6 +68,79 @@ bpf_text = """
|
||||||
|
// 5.9, but it does not hurt to have it here for versions 5.4 to 5.8.
|
||||||
|
struct memcg_cache_params {};
|
||||||
|
|
||||||
|
+// introduce kernel interval slab structure and slab_address() function, solved
|
||||||
|
+// 'undefined' error for >=5.16. TODO: we should fix this workaround if BCC
|
||||||
|
+// framework support BTF/CO-RE.
|
||||||
|
+struct slab {
|
||||||
|
+ unsigned long __page_flags;
|
||||||
|
+
|
||||||
|
+#if defined(CONFIG_SLAB)
|
||||||
|
+
|
||||||
|
+ struct kmem_cache *slab_cache;
|
||||||
|
+ union {
|
||||||
|
+ struct {
|
||||||
|
+ struct list_head slab_list;
|
||||||
|
+ void *freelist; /* array of free object indexes */
|
||||||
|
+ void *s_mem; /* first object */
|
||||||
|
+ };
|
||||||
|
+ struct rcu_head rcu_head;
|
||||||
|
+ };
|
||||||
|
+ unsigned int active;
|
||||||
|
+
|
||||||
|
+#elif defined(CONFIG_SLUB)
|
||||||
|
+
|
||||||
|
+ struct kmem_cache *slab_cache;
|
||||||
|
+ union {
|
||||||
|
+ struct {
|
||||||
|
+ union {
|
||||||
|
+ struct list_head slab_list;
|
||||||
|
+#ifdef CONFIG_SLUB_CPU_PARTIAL
|
||||||
|
+ struct {
|
||||||
|
+ struct slab *next;
|
||||||
|
+ int slabs; /* Nr of slabs left */
|
||||||
|
+ };
|
||||||
|
+#endif
|
||||||
|
+ };
|
||||||
|
+ /* Double-word boundary */
|
||||||
|
+ void *freelist; /* first free object */
|
||||||
|
+ union {
|
||||||
|
+ unsigned long counters;
|
||||||
|
+ struct {
|
||||||
|
+ unsigned inuse:16;
|
||||||
|
+ unsigned objects:15;
|
||||||
|
+ unsigned frozen:1;
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+ struct rcu_head rcu_head;
|
||||||
|
+ };
|
||||||
|
+ unsigned int __unused;
|
||||||
|
+
|
||||||
|
+#elif defined(CONFIG_SLOB)
|
||||||
|
+
|
||||||
|
+ struct list_head slab_list;
|
||||||
|
+ void *__unused_1;
|
||||||
|
+ void *freelist; /* first free block */
|
||||||
|
+ long units;
|
||||||
|
+ unsigned int __unused_2;
|
||||||
|
+
|
||||||
|
+#else
|
||||||
|
+#error "Unexpected slab allocator configured"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ atomic_t __page_refcount;
|
||||||
|
+#ifdef CONFIG_MEMCG
|
||||||
|
+ unsigned long memcg_data;
|
||||||
|
+#endif
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+// slab_address() will not be used, and NULL will be returned directly, which
|
||||||
|
+// can avoid adaptation of different kernel versions
|
||||||
|
+static inline void *slab_address(const struct slab *slab)
|
||||||
|
+{
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
#ifdef CONFIG_SLUB
|
||||||
|
#include <linux/slub_def.h>
|
||||||
|
#else
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
Loading…
Reference in New Issue
Block a user