Skip to content

Commit

Permalink
Added pid filter and minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
gdankel committed Aug 2, 2017
1 parent 8b6812a commit 22e7875
Showing 1 changed file with 35 additions and 14 deletions.
49 changes: 35 additions & 14 deletions tools/lockstat.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ def update(self, count, block_time):
self.elapsed_blocked += block_time
self.thread_count += 1

def run_command_get_pid(command):

This comment has been minimized.

Copy link
@yonghong-song

yonghong-song Aug 3, 2017

Collaborator

Looks run_command_get_pid is not really used?

p = subprocess.Popen(command.split())
return p.pid



examples = """
EXAMPLES:
Expand All @@ -38,7 +43,7 @@ def update(self, count, block_time):
every 5 seconds
./lockstat -p <pid> -t
Trace for a specified pid and print a message on each entry and exit to
sys_futex
sys_futex until interrupted or killed
./lockstat -p <pid> 10
Trace the specified pid and show a message every 10 seconds
./lockstat -c <command> 1 30
Expand Down Expand Up @@ -106,13 +111,11 @@ def update(self, count, block_time):
BPF_HASH(tgid_comm, u32, struct comm_t);
BPF_HASH(lock_stats, struct lock_key_t, struct lock_info_t, 1000000);
static inline int update_stats(u64 pid_tgid, u64 uaddr, u64 block_time) {
static inline int update_stats(u32 pid, u32 tgid, u64 uaddr, u64 block_time) {
struct lock_key_t key = {};
struct lock_info_t zero = {};
struct lock_info_t *info;
u32 pid = pid_tgid;
u32 tgid = (pid_tgid >> 32);
key.pid = pid;
key.tgid = tgid;
key.uaddr = uaddr;
Expand All @@ -136,21 +139,31 @@ def update(self, count, block_time):
if (cmd != FUTEX_WAIT)
return 0;
u32 pid = bpf_get_current_pid_tgid();
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid;
u32 tgid = pid_tgid >> 32;
if (!(THREAD_FILTER))
return 0;
u64 timestamp = bpf_ktime_get_ns();
u64 uaddr64 = (u64) uaddr;
pid_lock.update(&pid, &uaddr64);
pid_blocktime.update(&pid, &timestamp);
if (SHOULD_PRINT)
bpf_trace_printk("enter sys_futex, pid = %u, uaddr = %u, "
bpf_trace_printk("enter sys_futex, pid = %u, uaddr = %x, "
"cmd = %u\\n", pid, uaddr64, cmd);
return 0;
}
int sys_futex_exit(struct pt_regs *ctx) {
u64 pid_tgid = bpf_get_current_pid_tgid();
u32 pid = pid_tgid;
u32 tgid = pid_tgid >> 32;
if (!(THREAD_FILTER))
return 0;
u64 *blocktime = pid_blocktime.lookup(&pid);
u64 *uaddr = pid_lock.lookup(&pid);
u64 timestamp = bpf_ktime_get_ns();
Expand All @@ -160,12 +173,12 @@ def update(self, count, block_time):
return 0; // not FUTEX_WAIT, or (less likely) missed futex_enter
elapsed = timestamp - *blocktime;
update_stats(pid_tgid, *uaddr, elapsed);
update_stats(pid, tgid, *uaddr, elapsed);
pid_lock.delete(&pid);
pid_blocktime.delete(&pid);
if (SHOULD_PRINT) {
bpf_trace_printk("exit sys_futex, uaddr = %u, elapsed = %uns\\n",
bpf_trace_printk("exit sys_futex, uaddr = %x, elapsed = %uns\\n",
uaddr == 0 ? 0 : *uaddr, elapsed);
}
return 0;
Expand All @@ -175,12 +188,19 @@ def update(self, count, block_time):

bpf_source = bpf_source.replace("SHOULD_PRINT", "1" if trace_all else "0")

bpf_program = BPF(text=bpf_source)
thread_filter = '1'
if pid != -1:
print("Tracing pid %d, Ctrl+C to quit." % pid)
# 'tgid' in kernel space is what people thin of as 'pid' in userspace
thread_filter = "tgid == %d" % pid
else:
print("Tracing all processes, Ctrl+C to quit.")

print("Attaching to pid %d, Ctrl+C to quit." % pid)
bpf_source = bpf_source.replace("THREAD_FILTER", thread_filter)

bpf_program.attach_kprobe(event="SyS_futex", fn_name="sys_futex_enter", pid=pid)
bpf_program.attach_kretprobe(event="SyS_futex", fn_name="sys_futex_exit", pid=pid)
bpf_program = BPF(text=bpf_source)
bpf_program.attach_kprobe(event="SyS_futex", fn_name="sys_futex_enter")
bpf_program.attach_kretprobe(event="SyS_futex", fn_name="sys_futex_exit")

def create_tgid_stats():
stats = bpf_program["lock_stats"]
Expand All @@ -204,9 +224,10 @@ def print_comm_stats(stats):
key=lambda x: x[1].elapsed_blocked,
reverse=True)
for addr, stats in sorted_locks:
print(" %x: %dms (%d contentions affected %d threads)" %
print(" %x: %dms (%d contentions involving %d threads, avg %dus)" %
(addr, stats.elapsed_blocked / 1000000,
stats.contention_count, stats.thread_count))
stats.contention_count, stats.thread_count,
stats.elapsed_blocked / stats.contention_count / 1000))

count_so_far = 0
while True:
Expand Down

1 comment on commit 22e7875

@joelagnel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to squash the fixes into the original commit.

Please sign in to comment.