/csum_vs_tree_checker.py
Created Apr 3, 2019
Checksum vs Tree-checker performance analyse
| #!/usr/bin/python2 | |
| # @lint-avoid-python-3-compatibility-imports | |
| from __future__ import print_function | |
| from bcc import BPF | |
| text_bpf = ''' | |
| #include <uapi/linux/ptrace.h> | |
| #define CSUM_TREE_BLOCK 0 | |
| #define TREE_CHECKER_READ 1 | |
| #define TREE_CHECKER_WRITE 2 | |
| struct entry_t { | |
| u64 start_ns; | |
| }; | |
| struct data_t { | |
| u64 diff_ns; | |
| u64 type; | |
| }; | |
| BPF_HASH(entrylist, u64, struct entry_t); | |
| BPF_PERF_OUTPUT(events); | |
| struct extent_buffer; | |
| struct btrfs_fs_info; | |
| int common_entry(struct pt_regs *ctx) | |
| { | |
| u64 id = bpf_get_current_pid_tgid(); | |
| struct entry_t entry = {0}; | |
| entry.start_ns = bpf_ktime_get_ns(); | |
| entrylist.update(&id, &entry); | |
| return 0; | |
| } | |
| static int common_return(struct pt_regs *ctx, u64 type) | |
| { | |
| struct entry_t *entryp; | |
| struct data_t data = {0}; | |
| u64 id = bpf_get_current_pid_tgid(); | |
| u64 end_ns = bpf_ktime_get_ns(); | |
| entryp = entrylist.lookup(&id); | |
| if (!entryp) | |
| return 0; | |
| data.diff_ns = end_ns - entryp->start_ns; | |
| data.type = type; | |
| entrylist.delete(&id); | |
| events.perf_submit(ctx, &data, sizeof(data)); | |
| return 0; | |
| } | |
| int trace_csum_return(struct pt_regs *ctx) | |
| { | |
| return common_return(ctx, CSUM_TREE_BLOCK); | |
| } | |
| int trace_tree_checker_write_return(struct pt_regs *ctx) | |
| { | |
| return common_return(ctx, TREE_CHECKER_WRITE); | |
| } | |
| int trace_tree_checker_read_return(struct pt_regs *ctx) | |
| { | |
| return common_return(ctx, TREE_CHECKER_READ); | |
| } | |
| ''' | |
| result_table = {'CSUM_TREE_BLOCK' : [0, 0L], | |
| 'TREE_CHECKER_READ' : [0, 0L], | |
| 'TREE_CHECKER_WRITE': [0, 0L]} | |
| def process_event(cpu, data, size): | |
| event = b["events"].event(data) | |
| event_type = 'CSUM_TREE_BLOCK' | |
| if event.type == 1: | |
| event_type = 'TREE_CHECKER_READ' | |
| if event.type == 2: | |
| event_type = 'TREE_CHECKER_WRITE' | |
| result_table[event_type][0] += 1 | |
| result_table[event_type][1] += event.diff_ns | |
| def print_one_result(type): | |
| if result_table[type][0] == 0: | |
| avg = 0 | |
| else: | |
| avg = result_table[type][1] / result_table[type][0] | |
| print("%s: nr=%d total=%d avg=%d" % (type, | |
| result_table[type][0], | |
| result_table[type][1], avg)) | |
| def print_results(): | |
| print_one_result('CSUM_TREE_BLOCK') | |
| print_one_result('TREE_CHECKER_READ') | |
| print_one_result('TREE_CHECKER_WRITE') | |
| b = BPF(text=text_bpf) | |
| b.attach_kprobe(event="csum_tree_block", fn_name="common_entry") | |
| b.attach_kretprobe(event="csum_tree_block", fn_name="trace_csum_return") | |
| b.attach_kprobe(event="btrfs_check_leaf_full", fn_name="common_entry") | |
| b.attach_kretprobe(event="btrfs_check_leaf_full", fn_name="trace_tree_checker_read_return") | |
| b.attach_kprobe(event="btrfs_check_leaf_write", fn_name="common_entry") | |
| b.attach_kretprobe(event="btrfs_check_leaf_write", fn_name="trace_tree_checker_write_return") | |
| b["events"].open_perf_buffer(process_event, page_cnt=64) | |
| print("start recording") | |
| while 1: | |
| try: | |
| b.perf_buffer_poll() | |
| except KeyboardInterrupt: | |
| print_results() | |
| exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment