Skip to content
New issue

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

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

Already on GitHub? # 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

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant