From b0b38824dadc3e8d0130f53fafdc689363f1ac97 Mon Sep 17 00:00:00 2001 From: Martin Cermak Date: Tue, 9 Jun 2015 09:47:01 +0200 Subject: [PATCH] PR18492: Add tapset support and test coverage for sched_{get,set}attr * tapset/linux/aux_syscalls.stp: New function _struct_sched_attr_u() * tapset/linux/nd_syscalls2.stp: New probes nd_syscall.sched_{g,s}etattr * tapset/linux/syscalls2.stp: New probes syscall.sched_{g,s}etattr * testsuite/buildok/aux_syscalls-embedded.stp: New subtest * testsuite/buildok/nd_syscalls2-detailed.stp: Ditto * testsuite/buildok/syscalls2-detailed.stp: Ditto * testsuite/systemtap.syscall/sched_attr.c: New testcase --- tapset/linux/aux_syscalls.stp | 27 ++++++++ tapset/linux/nd_syscalls2.stp | 45 +++++++++++++ tapset/linux/syscalls2.stp | 44 +++++++++++++ testsuite/buildok/aux_syscalls-embedded.stp | 3 + testsuite/buildok/nd_syscalls2-detailed.stp | 20 ++++++ testsuite/buildok/syscalls2-detailed.stp | 20 ++++++ testsuite/systemtap.syscall/sched_attr.c | 73 +++++++++++++++++++++ 7 files changed, 232 insertions(+) create mode 100644 testsuite/systemtap.syscall/sched_attr.c diff --git a/tapset/linux/aux_syscalls.stp b/tapset/linux/aux_syscalls.stp index 4f3fc33a5..6604cb76a 100644 --- a/tapset/linux/aux_syscalls.stp +++ b/tapset/linux/aux_syscalls.stp @@ -5886,3 +5886,30 @@ function _kcmp_type_str:string(type:long) STAP_RETVALUE, MAXSTRINGLEN); %} +function _struct_sched_attr_u:string(uaddr:long) +%{ /* pure */ + struct sched_attr sa; + char *ptr = (char *)(unsigned long)STAP_ARG_uaddr; + if (ptr == NULL) + strlcpy(STAP_RETVALUE, "NULL", MAXSTRINGLEN); + else + { + if (_stp_copy_from_user((char*)&sa, ptr, + sizeof(struct sched_attr)) == 0) + { + snprintf(STAP_RETVALUE, MAXSTRINGLEN, + "{size=%u, sched_policy=%u, sched_flags=%llu, " + "sched_nice=%d, sched_priority=%u, sched_runtime=%llu, " + "sched_deadline=%llu, sched_period=%llu}", + sa.size, sa.sched_policy, sa.sched_flags, sa.sched_nice, + sa.sched_priority, sa.sched_runtime, sa.sched_deadline, + sa.sched_period); + } + else + { + snprintf(STAP_RETVALUE, MAXSTRINGLEN, "0x%lx", + (unsigned long)ptr); + } + } +%} + diff --git a/tapset/linux/nd_syscalls2.stp b/tapset/linux/nd_syscalls2.stp index 4be81c8a1..dd45cf14f 100644 --- a/tapset/linux/nd_syscalls2.stp +++ b/tapset/linux/nd_syscalls2.stp @@ -2055,6 +2055,29 @@ probe nd_syscall.sched_getaffinity.return = retstr = returnstr(1) } +# sched_getattr ______________________________________________ +# +# SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, +# unsigned int, size, unsigned int, flags) +# +probe nd_syscall.sched_getattr = kprobe.function("sys_sched_getattr") ? +{ + name = "sched_getattr" + asmlinkage() + pid = int_arg(1) + sched_attr_uaddr = pointer_arg(2) + sched_attr_str = _struct_sched_attr_u(sched_attr_uaddr) + size = uint_arg(3) + flags = uint_arg(4) + argstr = sprintf("%d, %s, %u, %u", pid, sched_attr_str, size, flags) +} +probe nd_syscall.sched_getattr.return = + kprobe.function("sys_sched_getattr").return ? +{ + name = "sched_getattr" + retstr = returnstr(1) +} + # sched_getparam _____________________________________________ # # asmlinkage long @@ -2161,6 +2184,28 @@ probe __nd_syscall.sched_rr_get_interval.return = @__syscall_gate(%{ __NR_sched_rr_get_interval %}) } +# sched_setattr ______________________________________________ +# +# SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, +# unsigned int, flags) +# +probe nd_syscall.sched_setattr = kprobe.function("sys_sched_setattr") ? +{ + name = "sched_setattr" + asmlinkage() + pid = int_arg(1) + sched_attr_uaddr = pointer_arg(2) + sched_attr_str = _struct_sched_attr_u(sched_attr_uaddr) + flags = uint_arg(3) + argstr = sprintf("%d, %s, %u", pid, sched_attr_str, flags) +} +probe nd_syscall.sched_setattr.return = + kprobe.function("sys_sched_setattr").return ? +{ + name = "sched_setattr" + retstr = returnstr(1) +} + # sched_setaffinity __________________________________________ # long sys_sched_setaffinity(pid_t pid, # unsigned int len, diff --git a/tapset/linux/syscalls2.stp b/tapset/linux/syscalls2.stp index 5f0f4f65b..01e10d4dc 100644 --- a/tapset/linux/syscalls2.stp +++ b/tapset/linux/syscalls2.stp @@ -1992,6 +1992,29 @@ probe syscall.sched_getaffinity.return = name = "sched_getaffinity" retstr = return_str(1, $return) } + +# sched_getattr ______________________________________________ +# +# SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr, +# unsigned int, size, unsigned int, flags) +# +probe syscall.sched_getattr = kernel.function("sys_sched_getattr") ? +{ + name = "sched_getattr" + pid = __int32($pid) + sched_attr_uaddr = $uattr + sched_attr_str = _struct_sched_attr_u(sched_attr_uaddr) + size = __uint32($size) + flags = __uint32($flags) + argstr = sprintf("%d, %s, %u, %u", pid, sched_attr_str, size, flags) +} +probe syscall.sched_getattr.return = + kernel.function("sys_sched_getattr").return ? +{ + name = "sched_getattr" + retstr = return_str(1, $return) +} + # sched_getparam _____________________________________________ # # asmlinkage long @@ -2090,6 +2113,27 @@ probe __syscall.sched_rr_get_interval.return = @__syscall_gate(%{ __NR_sched_rr_get_interval %}) } +# sched_setattr ______________________________________________ +# +# SYSCALL_DEFINE3(sched_setattr, pid_t, pid, struct sched_attr __user *, uattr, +# unsigned int, flags) +# +probe syscall.sched_setattr = kernel.function("sys_sched_setattr") ? +{ + name = "sched_setattr" + pid = __int32($pid) + sched_attr_uaddr = $uattr + sched_attr_str = _struct_sched_attr_u(sched_attr_uaddr) + flags = __uint32($flags) + argstr = sprintf("%d, %s, %u", pid, sched_attr_str, flags) +} +probe syscall.sched_setattr.return = + kernel.function("sys_sched_setattr").return ? +{ + name = "sched_setattr" + retstr = return_str(1, $return) +} + # sched_setaffinity __________________________________________ # long sys_sched_setaffinity(pid_t pid, # unsigned int len, diff --git a/testsuite/buildok/aux_syscalls-embedded.stp b/testsuite/buildok/aux_syscalls-embedded.stp index 9f1c10437..ab5b00b69 100755 --- a/testsuite/buildok/aux_syscalls-embedded.stp +++ b/testsuite/buildok/aux_syscalls-embedded.stp @@ -208,4 +208,7 @@ probe begin { print (_fanotify_mark_mask_str(0)) print (_perf_event_open_flags_str(0)) print (_kcmp_type_str(0)) +%( kernel_v >= "3.14" %? + print (_struct_sched_attr_u(0)) +%) } diff --git a/testsuite/buildok/nd_syscalls2-detailed.stp b/testsuite/buildok/nd_syscalls2-detailed.stp index e50e8ae56..2d880912b 100755 --- a/testsuite/buildok/nd_syscalls2-detailed.stp +++ b/testsuite/buildok/nd_syscalls2-detailed.stp @@ -565,6 +565,16 @@ probe nd_syscall.sched_getaffinity.return printf("%s %s\n", name, retstr) } +probe nd_syscall.sched_getattr ? +{ + printf("%s(%s)\n", name, argstr) + printf("%d, %s, %u, %u", pid, sched_attr_str, size, flags) +} +probe nd_syscall.sched_getattr.return ? +{ + printf("%s %s\n", name, retstr) +} + probe nd_syscall.sched_getparam { printf("%s(%s)\n", name, argstr) @@ -606,6 +616,16 @@ probe nd_syscall.sched_rr_get_interval.return printf("%s %s\n", name, retstr) } +probe nd_syscall.sched_setattr ? +{ + printf("%s(%s)\n", name, argstr) + printf("%d, %s, %u", pid, sched_attr_str, flags) +} +probe nd_syscall.sched_setattr.return ? +{ + printf("%s %s\n", name, retstr) +} + probe nd_syscall.sched_setaffinity { printf("%s(%s)\n", name, argstr) diff --git a/testsuite/buildok/syscalls2-detailed.stp b/testsuite/buildok/syscalls2-detailed.stp index 857c37133..9eef475ce 100755 --- a/testsuite/buildok/syscalls2-detailed.stp +++ b/testsuite/buildok/syscalls2-detailed.stp @@ -561,6 +561,16 @@ probe syscall.sched_getaffinity.return printf("%s %s\n", name, retstr) } +probe syscall.sched_getattr ? +{ + printf("%s(%s)\n", name, argstr) + printf("%d, %s, %u, %u", pid, sched_attr_str, size, flags) +} +probe syscall.sched_getattr.return ? +{ + printf("%s %s\n", name, retstr) +} + probe syscall.sched_getparam { printf("%s(%s)\n", name, argstr) @@ -602,6 +612,16 @@ probe syscall.sched_rr_get_interval.return printf("%s %s\n", name, retstr) } +probe syscall.sched_setattr ? +{ + printf("%s(%s)\n", name, argstr) + printf("%d, %s, %u", pid, sched_attr_str, flags) +} +probe syscall.sched_setattr.return ? +{ + printf("%s %s\n", name, retstr) +} + probe syscall.sched_setaffinity { printf("%s(%s)\n", name, argstr) diff --git a/testsuite/systemtap.syscall/sched_attr.c b/testsuite/systemtap.syscall/sched_attr.c new file mode 100644 index 000000000..c9432ced5 --- /dev/null +++ b/testsuite/systemtap.syscall/sched_attr.c @@ -0,0 +1,73 @@ +/* COVERAGE: sched_getattr sched_setattr */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +#if defined __NR_sched_getattr && defined __NR_sched_setattr + +static inline int __sched_getattr(pid_t pid, void *attr, unsigned int size, + unsigned int flags) +{ + return syscall(__NR_sched_getattr, pid, attr, size, flags); +} + +static inline int __sched_setattr(pid_t pid, void *attr, unsigned int flags) +{ + return syscall(__NR_sched_setattr, pid, attr, flags); +} + +int main() +{ + int mypid = getpid(); + + // Declaration of struct sched_attr not in available in 4.1.0-0 kernel headers. + // Following avoids declaring the structure within this test program. + int sas = 1024; + int sal = 8; /* __alignof__ (struct sched_attr) */ + void *sa = memalign(sal, sas); + + __sched_getattr(mypid, sa, sas, 0); + //staptest// sched_getattr (NNNN, {size=NNNN, sched_policy=NNNN, sched_flags=NNNN, sched_nice=NNNN, sched_priority=NNNN, sched_runtime=NNNN, sched_deadline=NNNN, sched_period=NNNN}, NNNN, NNNN) = 0 + + __sched_setattr(mypid, sa, 0); + //staptest// sched_setattr (NNNN, {size=NNNN, sched_policy=NNNN, sched_flags=NNNN, sched_nice=NNNN, sched_priority=NNNN, sched_runtime=NNNN, sched_deadline=NNNN, sched_period=NNNN}, NNNN) = 0 + + // Limit testing + + __sched_getattr(-1, 0, 0, 0); + //staptest// sched_getattr (-1, NULL, 0, 0) = -NNNN + + __sched_getattr(0, (void *)-1, 0, 0); + //staptest// sched_getattr (0, 0x[f]+, 0, 0) = -NNNN + + __sched_getattr(0, 0, -1, 0); + //staptest// sched_getattr (0, NULL, 4294967295, 0) = -NNNN + + __sched_getattr(0, 0, 0, -1); + //staptest// sched_getattr (0, NULL, 0, 4294967295) = -NNNN + + __sched_setattr(-1, NULL, 0); + //staptest// sched_setattr (-1, NULL, 0) = -NNNN + + __sched_setattr(0, (void *)-1, 0); + //staptest// sched_setattr (0, 0x[f]+, 0) = -NNNN + + __sched_setattr(0, NULL, -1); + //staptest// sched_setattr (0, NULL, 4294967295) = -NNNN + + free(sa); + + return 0; +} +#else +int main() +{ + return 0; +} +#endif -- 2.43.5