Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tools/readahead compatible with kernel version >= 5.10 #3507

12 changes: 8 additions & 4 deletions tools/readahead.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

# arguments
examples = """examples:
./readahead -d 20 # monitor for 10 seconds and generate stats
./readahead -d 20 # monitor for 20 seconds and generate stats
"""

parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -95,15 +95,19 @@
"""

b = BPF(text=program)
b.attach_kprobe(event="__do_page_cache_readahead", fn_name="entry__do_page_cache_readahead")
b.attach_kretprobe(event="__do_page_cache_readahead", fn_name="exit__do_page_cache_readahead")
if BPF.get_kprobe_functions(b"__do_page_cache_readahead"):
ra_event = "__do_page_cache_readahead"
else:
ra_event = "do_page_cache_ra"
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")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let us just do first try attach_kprobe with __do_page_cache_readahead(), if failed, try do_page_cache_ra(). You can look at nfsdist.py as an example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, adjutsted.

b.attach_kretprobe(event="__page_cache_alloc", fn_name="exit__page_cache_alloc")
b.attach_kprobe(event="mark_page_accessed", fn_name="entry_mark_page_accessed")

# header
print("Tracing... Hit Ctrl-C to end.")

# print
# print
def print_stats():
print()
print("Read-ahead unused pages: %d" % (b["pages"][ct.c_ulong(0)].value))
Expand Down
22 changes: 11 additions & 11 deletions tools/readahead_example.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ Demonstration of readahead, the Linux eBPF/bcc version

Read-ahead mechanism is used by operation sytems to optimize sequential operations
by reading ahead some pages to avoid more expensive filesystem operations. This tool
shows the performance of the read-ahead caching on the system under a given load to
shows the performance of the read-ahead caching on the system under a given load to
investigate any caching issues. It shows a count for unused pages in the cache and
also prints a histogram showing how long they have remianed there.

Usage Scenario
==============

Consider that you are developing a React Native application which performs aggressive
Consider that you are developing a React Native application which performs aggressive
reads while re-encoding a video in local-storage. Usually such an app would be multi-
layered and have transitional library dependencies. The actual read may be performed
by some unknown native library which may or may not be using hints to the OS, such as
madvise(p, LEN, MADV_SEQUENTIAL). If high IOPS is observed in such an app, running
readahead may pin the issue much faster in this case as the developer digs deeper
into what may be causing this.
layered and have transitional library dependencies. The actual read may be performed
by some unknown native library which may or may not be using hints to the OS, such as
madvise(p, LEN, MADV_SEQUENTIAL). If high IOPS is observed in such an app, running
readahead may pin the issue much faster in this case as the developer digs deeper
into what may be causing this.

An example where such an issue can surface is: https://github.com/boltdb/bolt/issues/691

Expand All @@ -40,7 +40,7 @@ Histogram of read-ahead used page age (ms):
2048 -> 4095 : 439 |**** |
4096 -> 8191 : 188 |* |

In the example above, we recorded system-wide stats for 30 seconds. We can observe that
In the example above, we recorded system-wide stats for 30 seconds. We can observe that
while most of the pages stayed in the readahead cache for quite less time, after 30
seconds 6765 pages still remained in the cache, yet unaccessed.

Expand All @@ -49,12 +49,12 @@ Note on Kprobes Usage

This tool uses Kprobes on the following kernel functions:

__do_page_cache_readahead()
__do_page_cache_readahead()/do_page_cache_ra() (After kernel version 5.10 (include), __do_page_cache_readahead was renamed to do_page_cache_ra)
__page_cache_alloc()
mark_page_accessed()

Since the tool uses Kprobes, depending on your linux kernel's compilation, these
functions may be inlined and hence not available for Kprobes. To see whether you have
Since the tool uses Kprobes, depending on your linux kernel's compilation, these
functions may be inlined and hence not available for Kprobes. To see whether you have
the functions available, check vmlinux source and binary to confirm whether inlining is
happening or not. You can also check /proc/kallsyms on the host and verify if the target
functions are present there before using this tool.