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.24.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
|
||||
Version: 0.25.0
|
||||
Release: 2%{?dist}
|
||||
Version: 0.26.0
|
||||
Release: 1%{?dist}
|
||||
Summary: BPF Compiler Collection (BCC)
|
||||
License: ASL 2.0
|
||||
URL: https://github.com/iovisor/bcc
|
||||
Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
|
||||
Patch0: Fix-bpf_pseudo_fd-type-conversion-error.patch
|
||||
Patch1: Fix-clang-15-int-to-pointer-conversion-errors.patch
|
||||
Patch0: tools-slabratetop-Fix-error-incomplete-definition-of.patch
|
||||
Patch1: tools-readahead-Fix-Failed-to-attach-BPF-program-ent.patch
|
||||
|
||||
# Arches will be included as upstream support is added and dependencies are
|
||||
# satisfied in the respective arches
|
||||
@ -239,6 +239,9 @@ cp -a libbpf-tools/tmp-install/bin/* %{buildroot}/%{_sbindir}/
|
||||
%endif
|
||||
|
||||
%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
|
||||
- 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