Server IP : 184.154.167.98 / Your IP : 18.220.63.52 Web Server : Apache System : Linux pink.dnsnetservice.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 User : puertode ( 1767) PHP Version : 7.2.34 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/libexec/pcp/pmdas/bcc/modules/ |
Upload File : |
// Copyright 2016 Netflix, Inc. // Licensed under the Apache License, Version 2.0 (the "License") #include <uapi/linux/ptrace.h> #include <linux/sched.h> #include <linux/nsproxy.h> #include <linux/pid_namespace.h> #include <linux/init_task.h> typedef struct pid_key { u64 id; // work around u64 slot; } pid_key_t; typedef struct pidns_key { u64 id; // work around u64 slot; } pidns_key_t; BPF_HASH(start, u32); STORAGE struct rq; // record enqueue timestamp static int trace_enqueue(u32 tgid, u32 pid) { if (FILTER || pid == 0) return 0; u64 ts = bpf_ktime_get_ns(); start.update(&pid, &ts); return 0; } static __always_inline unsigned int pid_namespace(struct task_struct *task) { /* pids[] was removed from task_struct since commit 2c4704756cab7cfa031ada4dab361562f0e357c0 * Using the macro INIT_PID_LINK as a conditional judgment. */ #ifdef INIT_PID_LINK struct pid_link pids; unsigned int level; struct upid upid; struct ns_common ns; /* get the pid namespace by following task_active_pid_ns(), * pid->numbers[pid->level].ns */ bpf_probe_read_kernel(&pids, sizeof(pids), &task->pids[PIDTYPE_PID]); bpf_probe_read_kernel(&level, sizeof(level), &pids.pid->level); bpf_probe_read_kernel(&upid, sizeof(upid), &pids.pid->numbers[level]); bpf_probe_read_kernel(&ns, sizeof(ns), &upid.ns->ns); return ns.inum; #else struct pid *pid; unsigned int level; struct upid upid; struct ns_common ns; /* get the pid namespace by following task_active_pid_ns(), * pid->numbers[pid->level].ns */ bpf_probe_read_kernel(&pid, sizeof(pid), &task->thread_pid); bpf_probe_read_kernel(&level, sizeof(level), &pid->level); bpf_probe_read_kernel(&upid, sizeof(upid), &pid->numbers[level]); bpf_probe_read_kernel(&ns, sizeof(ns), &upid.ns->ns); return ns.inum; #endif } int trace_wake_up_new_task(struct pt_regs *ctx, struct task_struct *p) { return trace_enqueue(p->tgid, p->pid); } int trace_ttwu_do_wakeup(struct pt_regs *ctx, struct rq *rq, struct task_struct *p, int wake_flags) { return trace_enqueue(p->tgid, p->pid); } // calculate latency int trace_run(struct pt_regs *ctx, struct task_struct *prev) { u32 pid, tgid; // ivcsw: treat like an enqueue event and store timestamp if (prev->STATE_FIELD == TASK_RUNNING) { tgid = prev->tgid; pid = prev->pid; if (!(FILTER || pid == 0)) { u64 ts = bpf_ktime_get_ns(); start.update(&pid, &ts); } } tgid = bpf_get_current_pid_tgid() >> 32; pid = bpf_get_current_pid_tgid(); if (FILTER || pid == 0) return 0; u64 *tsp, delta; // fetch timestamp and calculate delta tsp = start.lookup(&pid); if (tsp == 0) { return 0; // missed enqueue } delta = bpf_ktime_get_ns() - *tsp; FACTOR // store as histogram STORE start.delete(&pid); return 0; }