Module ImportFrom alias ImportFrom alias ImportFrom alias ImportFrom alias alias ImportFrom alias FunctionDef arguments args defaults body Expr Call NameLoad BinOpMod Str SubscriptLoad NameLoad Index Num Expr Call NameLoad decorator_list Assign NameStore Num Assign NameStore Num If CompareGt Call NameLoad NameLoad Num body TryExcept body Assign NameStore Call NameLoad SubscriptLoad NameLoad Index Num If CompareEq NameLoad Num body Raise If CompareGt Call NameLoad NameLoad Num body Assign NameStore Call NameLoad SubscriptLoad NameLoad Index Num handlers ExceptHandler body Expr Call NameLoad Assign NameStore Str Assign NameStore Call NameLoad keyword NameLoad Expr Call AttributeLoad NameLoad attr keyword Str keyword Str Expr Call AttributeLoad NameLoad attr keyword Str keyword Str Assign NameStore Dict Str Str Str Num Num Num Expr Call NameLoad BinOpMod Str Str keyword Str For TupleStore NameStore NameStore Call NameLoad Call AttributeLoad NameLoad attr keyword Lambda arguments args NameParam defaults TupleLoad SubscriptLoad NameLoad Index Num SubscriptLoad NameLoad Index Num body Expr Call NameLoad BinOpMod Str BinOpAdd NameLoad Str keyword Str Expr Call NameLoad BinOpMod Str Str Assign NameStore Num While Num body If CompareGt NameLoad Num body AugAssignAdd NameStore Num If CompareGt NameLoad NameLoad body Expr Call NameLoad TryExcept body Expr Call NameLoad NameLoad handlers ExceptHandler type NameLoad body Pass Expr Call NameLoad Expr Call NameLoad BinOpMod Str Call NameLoad Str keyword Str For TupleStore NameStore NameStore Call NameLoad Call AttributeLoad NameLoad attr keyword Lambda arguments args NameParam defaults TupleLoad SubscriptLoad NameLoad Index Num SubscriptLoad NameLoad Index Num body TryExcept body Assign NameStore BinOpDiv AttributeLoad SubscriptLoad SubscriptLoad NameLoad Index Str Index Call NameLoad NameLoad attr NameLoad Expr Call NameLoad BinOpMod Str NameLoad keyword Str handlers ExceptHandler body Expr Call NameLoad BinOpMod Str Num keyword Str TryExcept body Assign NameStore AttributeLoad SubscriptLoad SubscriptLoad NameLoad Index Str Index Call NameLoad SubscriptLoad NameLoad Index Str attr Assign NameStore AttributeLoad SubscriptLoad SubscriptLoad NameLoad Index Str Index Call NameLoad SubscriptLoad NameLoad Index Str attr Assign NameStore BinOpSub NameLoad NameLoad Assign NameStore BinOpDiv BinOpMult Call NameLoad Num NameLoad NameLoad Expr Call NameLoad BinOpMod Str NameLoad handlers ExceptHandler body Expr Call NameLoad BinOpMod Str Str Expr Call AttributeLoad SubscriptLoad NameLoad Index Str attr
N/A __future__ print_function bcc BPF ctypes c_int time sleep strftime sys argv usage N/A N/A N/A N/A N/A N/A print N/A USAGE: %s [interval [count]] N/A argv N/A 0 N/A N/A exit N/A N/A interval 1 N/A count -1 N/A N/A N/A len argv 1 N/A N/A N/A N/A interval N/A int N/A argv N/A 1 N/A N/A interval 0 N/A N/A N/A N/A N/A len argv 2 N/A N/A count N/A int N/A argv N/A 2 N/A N/A N/A N/A N/A usage N/A bpf_text 
#include <uapi/linux/ptrace.h>

enum stats {
    S_REFS = 1,
    S_SLOW,
    S_MISS,
    S_MAXSTAT
};

BPF_TABLE("array", int, u64, stats, S_MAXSTAT + 1);

/*
 * How this is instrumented, and how to interpret the statistics, is very much
 * tied to the current kernel implementation (this was written on Linux 4.4).
 * This will need maintenance to keep working as the implementation changes. To
 * aid future adventurers, this is is what the current code does, and why.
 *
 * 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().
 *
 * The implementation tries different, progressively slower, approaches to
 * lookup a file. At what point do we call it a dcache miss? I've choosen when
 * a d_lookup() (which is called during lookup_slow()) returns zero.
 *
 * I've also included a "SLOW" statistic to show how often the fast lookup
 * failed. Whether this exists or is interesting is an implementation detail,
 * and the "SLOW" statistic may be removed in future versions.
 */
void count_fast(struct pt_regs *ctx) {
    int key = S_REFS;
    u64 *leaf = stats.lookup(&key);
    if (leaf) (*leaf)++;
}

void count_lookup(struct pt_regs *ctx) {
    int key = S_SLOW;
    u64 *leaf = stats.lookup(&key);
    if (leaf) (*leaf)++;
    if (ctx->ax == 0) {
        key = S_MISS;
        leaf = stats.lookup(&key);
        if (leaf) (*leaf)++;
    }
}
 N/A b N/A BPF text bpf_text N/A N/A N/A b attach_kprobe event lookup_fast fn_name count_fast N/A N/A N/A b attach_kretprobe event d_lookup fn_name count_lookup N/A stats N/A REFS SLOW MISS 1 2 3 N/A N/A print N/A %-8s   TIME end N/A N/A stype idx N/A sorted N/A N/A stats items key N/A N/A N/A k_v N/A N/A N/A k_v N/A 1 N/A k_v N/A 0 N/A N/A N/A print N/A  %8s N/A stype /s end N/A N/A print N/A  %8s HIT% N/A i 0 N/A 1 N/A N/A N/A count 0 N/A N/A i 1 N/A N/A i count N/A N/A N/A exit N/A N/A N/A N/A sleep interval N/A N/A N/A KeyboardInterrupt N/A N/A N/A N/A exit N/A N/A print N/A %-8s:  N/A strftime %H:%M:%S end N/A N/A stype idx N/A sorted N/A N/A stats items key N/A N/A N/A k_v N/A N/A N/A k_v N/A 1 N/A k_v N/A 0 N/A N/A N/A N/A val N/A N/A N/A N/A b N/A stats N/A N/A c_int idx value interval N/A N/A print N/A  %8d val end N/A N/A N/A N/A N/A print N/A  %8d 0 end N/A N/A N/A ref N/A N/A N/A b N/A stats N/A N/A c_int N/A stats N/A REFS value N/A miss N/A N/A N/A b N/A stats N/A N/A c_int N/A stats N/A MISS value N/A hit N/A ref miss N/A pct N/A N/A N/A float 100 hit ref N/A N/A print N/A  %8.2f pct N/A N/A N/A N/A N/A print N/A  %7s%% - N/A N/A N/A N/A b N/A stats clear