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

Is there a problem with the calculation of dcstat #5210

Open
kiraskyler opened this issue Feb 10, 2025 · 1 comment
Open

Is there a problem with the calculation of dcstat #5210

kiraskyler opened this issue Feb 10, 2025 · 1 comment

Comments

@kiraskyler
Copy link
Contributor

This is the original code for dcstat

void count_fast(struct pt_regs *ctx) {
    int key = S_REFS;
    stats.atomic_increment(key);
}

void count_lookup(struct pt_regs *ctx) {
    int key = S_SLOW;
    stats.atomic_increment(key);
    if (PT_REGS_RC(ctx) == 0) {
        key = S_MISS;
        stats.atomic_increment(key);
    }
}

b = BPF(text=bpf_text)
b.attach_kprobe(event_re=r'^lookup_fast$|^lookup_fast.constprop.*.\d$', fn_name="count_fast")
b.attach_kretprobe(event="d_lookup", fn_name="count_lookup")

kernel code

fs/namei.c

static struct dentry *lookup_fast(struct nameidata *nd,
				  struct inode **inode,
			          unsigned *seqp)
{
    if (nd->flags & LOOKUP_RCU) {
	        dentry = __d_lookup_rcu(parent, &nd->last, &seq);
    } else {
		dentry = __d_lookup(parent, &nd->last);

Is there a problem here

  • No miss was counted when lookup_fast failed
  • Lookup_fast may also run to __d_lookup, __d_lookup will also be called by d_lookup, which represents SLOW, where fast statistics may also go to slow statistics
void count_fast(struct pt_regs *ctx) {
    int key = S_REFS;
    stats.atomic_increment(key);
    if (PT_REGS_RC(ctx) == 0) {
        key = S_MISS;
        stats.atomic_increment(key);
    }
}

b.attach_kprobe(event='__d_lookup_rcu', fn_name="count_fast")
b.attach_kretprobe(event="__d_lookup", fn_name="count_lookup")

Not using __d_lookup_rcu and __d_lookup may be related to the following reasons, although I didn't understand what they mean

 * First problem: the current implementation takes a path and then does a
 * lookup of each component. So how do we count a reference? Once for the path
 * lookup, or once for every component lookup? I've chosen the latter
 * since it seems to map more closely to actual dcache lookups (via
 * __d_lookup_rcu()). It's counted via calls to lookup_fast().

Keeping the original code unchanged, without considering modifying the event, add b.attach_kretprobe' (event_de=r '^ lookup_fast $| ^ lookup_fast. const prop. *. \ d $', whether the return is null when counting the number of new misses, and whether it should be added correctly?

@kiraskyler
Copy link
Contributor Author

@brendangregg tks

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

1 participant