Commit 484e5253 authored by 4ast's avatar 4ast Committed by GitHub

Merge pull request #1510 from iovisor/yhs_dev

fix runqlen.py with 4.15 kernel
parents 82ef5a0d ffa47e67
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
from __future__ import print_function from __future__ import print_function
from bcc import BPF, PerfType, PerfSWConfig from bcc import BPF, PerfType, PerfSWConfig
from time import sleep, strftime from time import sleep, strftime
from tempfile import NamedTemporaryFile
from os import open, close, dup, unlink, O_WRONLY
import argparse import argparse
# arguments # arguments
...@@ -51,6 +53,66 @@ countdown = int(args.count) ...@@ -51,6 +53,66 @@ countdown = int(args.count)
debug = 0 debug = 0
frequency = 99 frequency = 99
# Linux 4.15 introduced a new field runnable_weight
# in linux_src:kernel/sched/sched.h as
# struct cfs_rq {
# struct load_weight load;
# unsigned long runnable_weight;
# unsigned int nr_running, h_nr_running;
# ......
# }
# and this tool requires to access nr_running to get
# runqueue len information.
#
# The commit which introduces cfs_rq->runnable_weight
# field also introduces the field sched_entity->runnable_weight
# where sched_entity is defined in linux_src:include/linux/sched.h.
#
# To cope with pre-4.15 and 4.15/post-4.15 releases,
# we run a simple BPF program to detect whether
# field sched_entity->runnable_weight exists. The existence of
# this field should infer the existence of cfs_rq->runnable_weight.
#
# This will need maintenance as the relationship between these
# two fields may change in the future.
#
def check_runnable_weight_field():
# Define the bpf program for checking purpose
bpf_check_text = """
#include <linux/sched.h>
unsigned long dummy(struct sched_entity *entity)
{
return entity->runnable_weight;
}
"""
# Get a temporary file name
tmp_file = NamedTemporaryFile(delete=False)
tmp_file.close();
# Duplicate and close stderr (fd = 2)
old_stderr = dup(2)
close(2)
# Open a new file, should get fd number 2
# This will avoid printing llvm errors on the screen
fd = open(tmp_file.name, O_WRONLY)
try:
t = BPF(text=bpf_check_text)
success_compile = True
except:
success_compile = False
# Release the fd 2, and next dup should restore old stderr
close(fd)
dup(old_stderr)
close(old_stderr)
# remove the temporary file and return
unlink(tmp_file.name)
return success_compile
# define BPF program # define BPF program
bpf_text = """ bpf_text = """
#include <uapi/linux/ptrace.h> #include <uapi/linux/ptrace.h>
...@@ -60,6 +122,7 @@ bpf_text = """ ...@@ -60,6 +122,7 @@ bpf_text = """
// header. This will need maintenance. It is from kernel/sched/sched.h: // header. This will need maintenance. It is from kernel/sched/sched.h:
struct cfs_rq_partial { struct cfs_rq_partial {
struct load_weight load; struct load_weight load;
RUNNABLE_WEIGHT_FIELD
unsigned int nr_running, h_nr_running; unsigned int nr_running, h_nr_running;
}; };
...@@ -106,6 +169,11 @@ else: ...@@ -106,6 +169,11 @@ else:
'BPF_HISTOGRAM(dist, unsigned int);') 'BPF_HISTOGRAM(dist, unsigned int);')
bpf_text = bpf_text.replace('STORE', 'dist.increment(len);') bpf_text = bpf_text.replace('STORE', 'dist.increment(len);')
if check_runnable_weight_field():
bpf_text = bpf_text.replace('RUNNABLE_WEIGHT_FIELD', 'unsigned long runnable_weight;')
else:
bpf_text = bpf_text.replace('RUNNABLE_WEIGHT_FIELD', '')
# code substitutions # code substitutions
if debug: if debug:
print(bpf_text) print(bpf_text)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment