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

How can I get the filename from page fault? #3097

Closed
nagmat1 opened this issue Sep 14, 2020 · 5 comments
Closed

How can I get the filename from page fault? #3097

nagmat1 opened this issue Sep 14, 2020 · 5 comments

Comments

@nagmat1
Copy link

nagmat1 commented Sep 14, 2020

I want to know the source of file where the page fault occurs? I have tried the code below but not successfull.
I am attaching handle_mm_fault on front-end.

b.attach_kretprobe(event="handle_mm_fault", fn_name="output1")
int output_1(struct pt_regs *ctx, struct vm_area_struct *vma)
{
    struct val_t *valp;
    u32 pid  = bpf_get_current_pid_tgid();
    u64 fts = bpf_ktime_get_ns();
    valp = entryinfo.lookup(&pid);
    if (valp == 0 ) {
        // missed tracing issue
        return 0;
    }

    bpf_trace_printk("rw_return %d \\n ", pid);
    struct data_t data = {};
    data.pid = pid;
    data.sts = valp->ts;
    entryinfo.delete(&pid);
    data.fts = fts;
    struct file *f = vma->vm_file;
    struct dentry *de = f->f_path.dentry;
    struct qstr d_name = de->d_name;
    bpf_probe_read(&data.filename,sizeof(data.filename),d_name.name);
    bpf_probe_read(&data.comm, sizeof(data.comm), valp->comm);
    events.perf_submit(ctx,&data,sizeof(data));

    return 0;
}
@yonghong-song
Copy link
Collaborator

This won't work. For kretprobe, there is no guarantee that at times of func exit, the first argument is still kept in the same register. That register may have been reused in the function body. The better way is to use kfunc_exit.

@nagmat1
Copy link
Author

nagmat1 commented Sep 15, 2020

Can I get the filename where pagefault is occuring using kprobe(Not kretprobe)?

@nagmat1
Copy link
Author

nagmat1 commented Sep 16, 2020

I want to know the source of file where the page fault occurs? I have tried the code below but not successfull.
I am attaching handle_mm_fault kprobe on front-end.

b.attach_kprobe(event="handle_mm_fault", fn_name="output1")
int output_1(struct pt_regs *ctx, struct vm_area_struct *vma)
{
    struct val_t *valp;
    u32 pid  = bpf_get_current_pid_tgid();
    u64 fts = bpf_ktime_get_ns();
    valp = entryinfo.lookup(&pid);
    if (valp == 0 ) {
        // missed tracing issue
        return 0;
    }

    bpf_trace_printk("rw_return %d \\n ", pid);
    struct data_t data = {};
    data.pid = pid;
    data.sts = valp->ts;
    entryinfo.delete(&pid);
    data.fts = fts;
    struct file *f = vma->vm_file;
    struct dentry *de = f->f_path.dentry;
    struct qstr d_name = de->d_name;
    bpf_probe_read(&data.filename,sizeof(data.filename),d_name.name);
    bpf_probe_read(&data.comm, sizeof(data.comm), valp->comm);
    events.perf_submit(ctx,&data,sizeof(data));

    return 0;
}

@yonghong-song
Copy link
Collaborator

You probably want to double check whether you got 0 for any of the following statements.

    struct file *f = vma->vm_file;
    struct dentry *de = f->f_path.dentry;

@nagmat1
Copy link
Author

nagmat1 commented Sep 18, 2020

Thank you very much for kind support. This is the last version of the program which counts page faults based on filename :

from __future__ import print_function
from bcc import BPF
from time import sleep
from sys import argv

interval = 99999999
# load BPF program
b = BPF(text="""
#include <uapi/linux/ptrace.h>
#include <linux/uio.h>
#include <linux/fs.h>
#include <linux/sched.h>

struct key_t {
   char faylady[15];
};
BPF_HASH(counts, struct key_t, u64, 256);
int do_count(struct pt_regs *ctx, struct vm_area_struct *vma) {
    struct key_t key = {};
    struct file *file = vma->vm_file;
    if (file == 0) {return 0;}
    struct dentry *de = file->f_path.dentry;
    struct qstr d_name = de->d_name;
    bpf_probe_read(&key.faylady,sizeof(key.faylady),d_name.name);
    counts.increment(key);
    return 0;
}
""")
b.attach_kprobe(event="handle_mm_fault", fn_name="do_count")

# header
print("Tracing... Ctrl-C to end.")
# output
try:
    sleep(interval)
except KeyboardInterrupt:
    pass

print("\n%-26s %8s" % ("Filename", "COUNT"))
counts = b.get_table("counts")
for k, v in sorted(counts.items(), key=lambda counts: counts[1].value):
    print("%-26s %8d" % (k.faylady, v.value))

@nagmat1 nagmat1 closed this as completed Sep 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants