// Copyright 2016 Netflix, Inc. // Licensed under the Apache License, Version 2.0 (the "License") #include #include #include #define OP_NAME_LEN 8 typedef struct dist_key { char op[OP_NAME_LEN]; u64 slot; } dist_key_t; BPF_HASH(start, u32); BPF_HISTOGRAM(dist, dist_key_t); // time operation int trace_entry(struct pt_regs *ctx) { u32 pid = bpf_get_current_pid_tgid(); if (FILTER_PID) return 0; u64 ts = bpf_ktime_get_ns(); start.update(&pid, &ts); return 0; } static int trace_return(struct pt_regs *ctx, const char *op) { u64 *tsp; u32 pid = bpf_get_current_pid_tgid(); // fetch timestamp and calculate delta tsp = start.lookup(&pid); if (tsp == 0) { return 0; // missed start or filtered } u64 delta = (bpf_ktime_get_ns() - *tsp) / 1000; // store as histogram dist_key_t key = {.slot = bpf_log2l(delta)}; __builtin_memcpy(&key.op, op, sizeof(key.op)); dist.increment(key); start.delete(&pid); return 0; } int trace_read_return(struct pt_regs *ctx) { char *op = "read"; return trace_return(ctx, op); } int trace_write_return(struct pt_regs *ctx) { char *op = "write"; return trace_return(ctx, op); } int trace_open_return(struct pt_regs *ctx) { char *op = "open"; return trace_return(ctx, op); } int trace_fsync_return(struct pt_regs *ctx) { char *op = "fsync"; return trace_return(ctx, op); }