Suchakra Sharma | 561a71e | 2020-09-24 08:27:15 -0700 | [diff] [blame] | 1 | Demonstration of readahead, the Linux eBPF/bcc version |
| 2 | |
| 3 | Read-ahead mechanism is used by operation sytems to optimize sequential operations |
| 4 | by reading ahead some pages to avoid more expensive filesystem operations. This tool |
zcy | 97c2076 | 2021-06-25 10:16:53 +0800 | [diff] [blame] | 5 | shows the performance of the read-ahead caching on the system under a given load to |
Suchakra Sharma | 561a71e | 2020-09-24 08:27:15 -0700 | [diff] [blame] | 6 | investigate any caching issues. It shows a count for unused pages in the cache and |
| 7 | also prints a histogram showing how long they have remianed there. |
| 8 | |
| 9 | Usage Scenario |
| 10 | ============== |
| 11 | |
zcy | 97c2076 | 2021-06-25 10:16:53 +0800 | [diff] [blame] | 12 | Consider that you are developing a React Native application which performs aggressive |
Suchakra Sharma | 561a71e | 2020-09-24 08:27:15 -0700 | [diff] [blame] | 13 | reads while re-encoding a video in local-storage. Usually such an app would be multi- |
zcy | 97c2076 | 2021-06-25 10:16:53 +0800 | [diff] [blame] | 14 | layered and have transitional library dependencies. The actual read may be performed |
| 15 | by some unknown native library which may or may not be using hints to the OS, such as |
| 16 | madvise(p, LEN, MADV_SEQUENTIAL). If high IOPS is observed in such an app, running |
| 17 | readahead may pin the issue much faster in this case as the developer digs deeper |
| 18 | into what may be causing this. |
Suchakra Sharma | 561a71e | 2020-09-24 08:27:15 -0700 | [diff] [blame] | 19 | |
| 20 | An example where such an issue can surface is: https://github.com/boltdb/bolt/issues/691 |
| 21 | |
| 22 | # readahead -d 30 |
| 23 | Tracing... Hit Ctrl-C to end. |
| 24 | ^C |
| 25 | Read-ahead unused pages: 6765 |
| 26 | Histogram of read-ahead used page age (ms): |
| 27 | |
| 28 | age (ms) : count distribution |
| 29 | 0 -> 1 : 4236 |****************************************| |
| 30 | 2 -> 3 : 394 |*** | |
| 31 | 4 -> 7 : 1670 |*************** | |
| 32 | 8 -> 15 : 2132 |******************** | |
| 33 | 16 -> 31 : 401 |*** | |
| 34 | 32 -> 63 : 1256 |*********** | |
| 35 | 64 -> 127 : 2352 |********************** | |
| 36 | 128 -> 255 : 357 |*** | |
| 37 | 256 -> 511 : 369 |*** | |
| 38 | 512 -> 1023 : 366 |*** | |
| 39 | 1024 -> 2047 : 181 |* | |
| 40 | 2048 -> 4095 : 439 |**** | |
| 41 | 4096 -> 8191 : 188 |* | |
| 42 | |
zcy | 97c2076 | 2021-06-25 10:16:53 +0800 | [diff] [blame] | 43 | In the example above, we recorded system-wide stats for 30 seconds. We can observe that |
Suchakra Sharma | 561a71e | 2020-09-24 08:27:15 -0700 | [diff] [blame] | 44 | while most of the pages stayed in the readahead cache for quite less time, after 30 |
| 45 | seconds 6765 pages still remained in the cache, yet unaccessed. |
| 46 | |
| 47 | Note on Kprobes Usage |
| 48 | ===================== |
| 49 | |
| 50 | This tool uses Kprobes on the following kernel functions: |
| 51 | |
zcy | 97c2076 | 2021-06-25 10:16:53 +0800 | [diff] [blame] | 52 | __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) |
Suchakra Sharma | 561a71e | 2020-09-24 08:27:15 -0700 | [diff] [blame] | 53 | __page_cache_alloc() |
| 54 | mark_page_accessed() |
| 55 | |
zcy | 97c2076 | 2021-06-25 10:16:53 +0800 | [diff] [blame] | 56 | Since the tool uses Kprobes, depending on your linux kernel's compilation, these |
| 57 | functions may be inlined and hence not available for Kprobes. To see whether you have |
Suchakra Sharma | 561a71e | 2020-09-24 08:27:15 -0700 | [diff] [blame] | 58 | the functions available, check vmlinux source and binary to confirm whether inlining is |
| 59 | happening or not. You can also check /proc/kallsyms on the host and verify if the target |
| 60 | functions are present there before using this tool. |