Alice Zhang [Tue, 10 Nov 2020 18:11:13 +0000 (13:11 -0500)]
PR13838: Add float32 support and corresponding test cases
runtime/softfloat.* & runtime/softfloat/: add f32 support and f32 to f64
conversion
tapset/floatingpoint.stp: fixed some documentation typos & add f32_tp_f64
tapset function
testsuite/buildok/floatingpoint.stp: add f32 related test cases
main.cxx: add float parameter to sdt_benchmark_thread function for test purpose
runtime/softfloat.c & tapset/floatingpoint.stp : delete unnecessary functions
to keep the code concise
In utrace_report_syscall_entry and _exit, there is a possibility of
dereferencing a NULL pointer, in case __stp_utrace_alloc_task_work
exhausts UTRACE_TASK_WORK_POOL_SIZE live elements. While OOM is
still a possibility, this patch handles it more gracefully.
Frank Ch. Eigler [Tue, 10 Nov 2020 00:18:19 +0000 (19:18 -0500)]
PR26665: relayfs-on-procfs megapatch
On platforms/configurations where debugfs is inaccessible (I'm
side-eyeing at you, secureboot + kernel_lockdown), the stap runtime
needs another way to hook up the relayfs / .cmd files to talk to
staprun/stapio in userspace. kernel relayfs users all rely on
debugfs (tied closely to struct dentry*), and filesystems where
dentry*'s are not immediately available are SOL.
Until now. This gigapatch forks pieces of runtime/transport/transport.c
into debugfs and procfs alternatives. The debugfs fork is just like
before. The procfs fork is new, and uses a proc_dir_entry <-> struct
path look-up table to map between procfs objects and the dentry*'s
that relayfs so loves.
The debugfs alternative is default, except when lockdown mode is
detected; then the runtime chooses procfs_p at the strategic moment.
stap -DSTAP_TRANS_PROCFS or -DSTAP_TRANS_DEBUGFS lets the user
override this heuristic. (Going to a procfs default is worth
considering at some point.)
The staprun/stapio userspace is updated to search both
/sys/kernel/debug/systemtap and /proc/systemtap for the relay/.cmd
file endpoints.
Most of this gigapatch is moving code around in runtime/transport/ so
relay_v2 is agnostic to its enclosing filesystem, going through hooks
in transport.c to either procfs.c or debugfs.c. The old
runtime/procfs.c file is stripped down to move common bits around a
little.
William Cohen [Mon, 9 Nov 2020 18:01:06 +0000 (13:01 -0500)]
Initialize variable in runtime/softfloat.c to avoid RHEL8 -Werror issue
Make sure that the variable is initialized to something to avoid the
following error when running the testsuite on RHEL8:
attempting command stap -p4 floatingpoint.stp -c "stap --benchmark-sdt"
OUT In file included from /tmp/stapBRN9va/stap_825f154f474bfd5b2080a28426f65178_4743_src.c:37:
/usr/share/systemtap/runtime/softfloat.c: In function 'softfloat_shiftRightJamM':
/usr/share/systemtap/runtime/softfloat.c:132:34: error: 'ptr' may be used uninitialized in this function [-Werror=maybe-uninitialized]
uint32_t wordJam, wordDist, *ptr;
^~~
cc1: all warnings being treated as errors
make[3]: *** [scripts/Makefile.build:315: /tmp/stapBRN9va/stap_825f154f474bfd5b2080a28426f65178_4743_src.o] Error 1
make[2]: *** [Makefile:1544: _module_/tmp/stapBRN9va] Error 2
WARNING: kbuild exited with status: 2
Pass 4: compilation failed. [man error::pass4]
child process exited abnormally
RC 1
FAIL: systemtap.examples/general/floatingpoint build
Sultan Alsawaf [Thu, 5 Nov 2020 21:39:30 +0000 (13:39 -0800)]
PR26144: task_finder2: execute task workers in order
The task finder's task workers need to be executed in the order that
they are added, but the kernel's task_work API doesn't make any ordering
guarantees, so task workers end up getting executed out of order. This
becomes a problem when the mmap callback worker runs after the other two
workers the task finder uses, even though it gets queued beforehand.
We can make the task finder's task workers run in order by wrapping the
task worker API with our own routines to dequeue task workers from a
global list and run them in the correct order. A lot of the scaffolding
needed to achieve this is already present, so this change is not too
invasive.
Aaron Merey [Thu, 5 Nov 2020 17:46:31 +0000 (12:46 -0500)]
Makefile.am: Install runtime/softfloat/
Previously the runtime/softfloat directory was not installed when
building systemtap. This lead to errors when trying to use systemtap's
floating point facilities.
Modify Makefile.am so that this directory is installed during a build.
Sultan Alsawaf [Mon, 2 Nov 2020 23:53:09 +0000 (15:53 -0800)]
PR26846: task_finder2: fix kernel panics by eliminating in_atomic() usage
With non-PREEMPT kernels (i.e., kernels with CONFIG_PREEMPT=n),
in_atomic() cannot detect when the current context is within a spin lock
or RCU read-side critical section. Since the syscall tracepoints are
executed from within an RCU read-side critical section (see
__DO_TRACE()), this means that in_atomic() won't know that the current
context doesn't allow sleeping. When this happens, we see kernel panics
occurring in stap's registered tracepoints, like this one:
Panics like this occur in all of stap's registered tracepoints. To fix
them, just defer the mmap callbacks to a task worker all the time. That
way, we never need to worry about handling them in a safe context.
If routine runtime errors occur during execution, the c->last_stmt
variable is printed to the user as to best suspected script location
of the failure. As an optimization, this variable is not set at every
little point during statement/expression evaluation that are not
likely to cause errors. But we overlooked one spot where it's
absolutely needed: around function calls, especially into synthetic
embedded-c functions that process $context variables. That meant that
error messages could misidentify some other recent but nonspecific
point for an error.
Now we add a c->last_stmt set immediately before each function call,
after its actual arguments are executed. This placement also covers
the case where the arguments themselves might fail during evaluation.
Serhei Makarov [Wed, 4 Nov 2020 20:50:49 +0000 (15:50 -0500)]
PR26811 WIP: adapt to set_fs() removal in linux 5.10+
WIP since there are still a few faults in evidence e.g. on check.exp whythefail
Introduce STAPCONF_SET_FS to identify if set_fs is present.
After kernel 5.10 on arches removing set_fs(), kernel
addresses should be read/written with get_kernel_nofault and
copy_to_kernel_nofault while user addresses are still read/written
with __get_user and __put_user. So we have wrapper macros
__stp_{get,put}_either which do the right thing on all kernel
versions.
Also, since KERNEL_DS and USER_DS are no longer available, introduce
STP_KERNEL_DS and STP_USER_DS. These map to KERNEL_DS and USER_DS on
older kernels.
Also, modify loc2c-runtime.h dereferencing functions and lookup_bad_addr
to take STP_KERNEL_DS/STP_USER_DS parameters specifying the address space
to dereference in.
Sultan Alsawaf [Sat, 31 Oct 2020 07:02:12 +0000 (00:02 -0700)]
stp_task_work: don't busy poll in stp_task_work_exit()
Instead of doing a busy poll and forcefully sleeping for one jiffy every
time stp_task_work_exit() checks to see if all the task workers are
finished, just use a wait event and have the last task worker wake up
stp_task_work_exit() when it's finished. This is faster and more
efficient, since there's no uninterruptible sleeping for exactly one
jiffy at a time, and there's no polling involved.
Alice Zhang [Fri, 30 Oct 2020 06:33:01 +0000 (02:33 -0400)]
PR13838: Added basic floating point support to systemtap
runtime/softfloat.*: including floating point type definition
runtime/softfloat/*: all other required auxiliary functions
These are from https://github.com/ucb-bar/berkeley-softfloat-3
by John R. Hauser, thanks!
tapset/floatingpoing.stp: including fp conversion, fp arithmetic and
comparison functions testsuite/buildok/floatingpoint.stp: including testcase
for corresponding floatingpoing tapset main.cxx: changed sdt_benchmark part
of code for a demo of extracting floating point
Systemtap support 64 bit floating pounint (double type) under ieee754.
Conversions(fp <-> long, fp <-> string), arithmetic(add, sub, div, mul, sqrt)
and comparison between fp(less than, less than or equal to, equal) are
supported, corresponding tapset functions and test case are provided as well.
amerey [Fri, 7 Aug 2020 22:58:33 +0000 (18:58 -0400)]
PR26015: Make syscall arguments writable again
Make syscall arguments writable again in non-DWARF probes on kernels
that use syscall wrappers to pass arguments via pt_regs (currently
x86_64 4.17+ and aarch64 4.19+).
For non-DWARF syscall probes also add an additional probe variable
for each syscall string parameter that holds an unquoted version
of the string parameter. Modifying this variable within the probe
will cause the string it holds to be written to the userspace string
buffer that was passed to the syscall.
Sagar Patel [Thu, 29 Oct 2020 23:34:41 +0000 (19:34 -0400)]
PR26015: Add @probewrite predicate.
The @probewrite predicate checks whether an identifier has been
written to in the probe handler body. The identifier can be either
a script variable or target variable. @probewrite(var) returns 1
if var has been written to in the probe handler body, else 0.
For example,
probe foo = begin { var = 0 }, { if (@probewrite(var)) println(var) }
probe foo { var = 1 }
The @probewrite predicate would resolve to 1 in this case and the
new value of var would be printed.
1) Added probewrite_op.
2) Designed probewrite_evaluator to resolve @probewrite checks.
3) Designed symuse_collecting_visitor (similar to varuse_collecting_visitor).
3) Updated several other visitors accordingly.
4) Added test cases.
5) Updated NEWS.
Sultan Alsawaf [Thu, 29 Oct 2020 18:25:53 +0000 (11:25 -0700)]
task_finder2: change the default engine action to UTRACE_INTERRUPT
There is a race condition where, right after an engine is attached, a
reporting pass will occur before the engine can actually request what it
wants from the target process. In this case, the action that the engine
used when it was first attached will be carried out during the reporting
pass. When the default action is UTRACE_STOP, this means that the
reporting pass will think the newly-attached engine wants to stop the
target process, at which point the target process will be moved into the
TASK_TRACED state (visible via `ps aux | grep ' t '`) and will be
halted forever (until it receives a SIGKILL) because the engine will
never send a UTRACE_RESUME request to bring the target process back to
life. This seems to be an issue with the UTRACE_STOP machinery; it's not
clear how *any* process entering the UTRACE_STOP state can exit that
state naturally. It's also dubious whether the UTRACE_STOP state is even
needed, since tracing is done from within task workers that run inside
the context of the process we're trying to analyze, which allows us to
to safely analyze the process without needing to stop it.
Regardless, it's clear that a newly-attached engine would definitely not
want to stop the process it's trying to analyze; after all, there's
nothing interesting to see if the process is just halted. The common
engine action seems to be UTRACE_INTERRUPT, so let's set that to be the
default instead of UTRACE_STOP.
task_finder2: don't attach to forked children when the target PID is specified
When we have a PID specified for tracing and a fork occurs from our
target PID, the forked child will have the same exe as our target and
will subsequently get matched and attached to by
__stp_utrace_attach_match_filename(). Attaching to these children is not
productive though, since we are only interested in a specific process.
Therefore, as an optimization, only bother trying to attach to forked
children when the target PID is *not* specified. When the target PID is
specified (via -x PID) and match_tsk != path_tsk, we know that a fork
just occurred and match_tsk is the child of path_tsk, in which case
we should just skip attaching to match_tsk.
Sultan Alsawaf [Thu, 29 Oct 2020 08:24:43 +0000 (01:24 -0700)]
task_finder: error out when we cannot attach to _stp_target
In order to avoid sleeping, stap_find_exe_file() does a trylock attempt
on an mm's mmap semaphore and returns NULL when the lock is contented.
When this happens, it can cause the task finder to not attach to a
desired target process. This is especially noticeable when a target PID
is specified, in which case the target PID itself can get skipped over
by the task finder.
Therefore, we should treat failures to get the exe file for a specific
target PID as fatal, since that means the target PID will never get
attached. Note that we must return a negative value from
stap_start_task_finder() in order for the fatal error to be honored, so
we shouldn't negate PTR_ERR(mmpath).
Frank Ch. Eigler [Wed, 28 Oct 2020 00:02:18 +0000 (20:02 -0400)]
testsuite: current.stp module("*") defang
Like for server_concurrency*, the current.stp test case has excessive
debuginfo requirements. We still want -some- decent workload, so
chose usb* as the module wildcard. Far smaller than the "*" there
formerly.
Sultan Alsawaf [Tue, 27 Oct 2020 22:00:49 +0000 (15:00 -0700)]
stp_utrace: replace task_utrace_lock with non-blocking RCU read locks
The global task_utrace_lock is highly contented and results in a lot of
CPU time wasted spinning on it, especially since it's not a r/w lock.
It turns out we can replace all of the task_utrace_lock usage with
non-blocking RCU read locks instead to improve performance. Now, reads
to any of the hash list buckets containing the utrace entries do not
block and can occur concurrently with other readers, and writes to any
hash list won't block readers thanks to the magic of RCU. The only
locking needed is between concurrent writes to a single hash list, and
a per-bucket spin lock is used to achieve this instead of a sprawling
global lock.
Stan Cox [Tue, 27 Oct 2020 15:23:06 +0000 (11:23 -0400)]
Merge branch 'scox/tls': Add tls support.
This merges support for accessing implicit tls variables.
Given a DW_OP_GNU_push_tls_address dwarf entry,
tls.stp::__push_tls_address handles navigating the tls data
structures. stp_tls.h contains minimal versions of a few essential
tls data structures.
Frank Ch. Eigler [Tue, 27 Oct 2020 02:01:24 +0000 (22:01 -0400)]
step-prep: check for debuginfod capability
Test /usr/bin/debuginfod-find for a vdso*so in the kernel. If
successful, avoid downloading big kernel debuginfo files now,
assuming that the debuginfo server(s) will remain available.
fs/kernel_file_read: Add "offset" arg for partial reads
To perform partial reads, callers of kernel_read_file*() must have a
non-NULL file_size argument and a preallocated buffer. The new "offset"
argument can then be used to seek to specific locations in the file to
fill the buffer to, at most, "buf_size" per call.
Where possible, the LSM hooks can report whether a full file has been
read or not so that the contents can be reasoned about.
This and the preceding commits changed the function signature from:
To fight the oobleck of giant test log files (ok to store with Bunsen
but hard to display in a browser without pagination tricks), reduce
the most verbose testcases.
unprivileged_embedded_C.exp bombards us with pass2 output.
(Always printed even without -v flag.)
Options:
1) suppress stap stdout but not stderr with sh -c wrapper + redirection
2) separate and drop stdout in the expect script (not feasible)
3) add a secret --silent-p2 option to stap which drops pass2 output
Sultan Alsawaf [Thu, 22 Oct 2020 04:50:16 +0000 (21:50 -0700)]
task_finder_vma: add autoconf check for atomic_fetch_add_unless()
Some kernels have atomic_fetch_add_unless() backported, such as
4.18.0-240.5.el8.aarch64 and 4.18.0-193.28.1.el8_2.x86_64 on rhel8,
so we cannot rely on the kernel version to determine whether or not
the function is present. Add an autoconf stub to check for it.
Optimize: increase the default size of the vma map hash table
Hash conflicts is severe when the vma tracker keeps track of many
processes given the current hash table size of mere 16 buckets.
Increased it to 256 buckets by default and also make it tunable
via the macro __STP_TF_HASH_BITS.
In our test, this significantly reduces hash conflicts when
stap/staprun's -x PID option is not specified.
Sultan Alsawaf [Wed, 21 Oct 2020 19:27:24 +0000 (12:27 -0700)]
task_finder_vma: rewrite using RCU to fix performance issues
The use of a single global rwlock to protect this file's hash table
results in significantly degraded performance when there are many
processes using the vma tracker in flight. A lot of time is spent
spinning on the rwlock when this happens. For exmaple, it is using
most of the CPU time in the following kernel-space CPU flame graph:
There are other code paths which would invoke the same spinlock, as in
_stp_umodule_relocate().
To remedy this, make the hash table RCU safe so we'll never block upon
reading a hash list.
We now use the hash_ptr() function to generate the hashes, and the task
pointers themselves are hashed now instead of their PID for reliability,
since PIDs are not a stable anchor point to a task struct.
While we're at it, clean up the rest of this file to bring it up to
current Linux kernel coding standards as well.
This leads to dramatic CPU time reduction when
1. the current system has a lot of running processes, or
2. some processes have a lot of DSO dependencies, and
3. also -x PID is not used for stap or staprun, and
4. there are quite a few CPU cores.
For a typical test run, we have the following CPU utilization changes:
Serhei Makarov [Wed, 21 Oct 2020 20:06:48 +0000 (16:06 -0400)]
PR26755 temporary kprobes_onthefly.exp: also disable m* on ppc
XXX Need to investigate which of the tracepoints under m* is failing. XXX
For now, blacklist these in kprobes_onthefly.exp to allow the buildbot
testsuite to finish running.
An onthefly testcase started freezing the kernel on the 'hardcore'
case which grabs lock:lock_{acquire,acquired,release,contended} tracepoints.
I'm still tracking down which kernel change caused this
since the tracepoints exist on older codebases (probably lockdep kernels),
but for now it seems that we should avoid probing these in onthefly testing.
Stan Cox [Fri, 9 Oct 2020 20:51:57 +0000 (16:51 -0400)]
Support tls on ppcle
Support tls on ppcle as described in "OpenPOWER ABI for Linux Supplement
Power Architecture 64-Bit ELF V2 ABI." Use glibc debuginfo instead of constant
offset to access link_map->l_tls_modid. Remove set_tls_module_by_addr.
Sultan Alsawaf [Thu, 1 Oct 2020 22:19:47 +0000 (15:19 -0700)]
PR26697: fix NULL pointer deref in get_utrace_lock()
task_utrace_struct() can return NULL via __task_utrace_struct(). This fixes
the following crash:
BUG: unable to handle kernel NULL pointer dereference at (null)
#9 [ffff8843e56ffd20] get_utrace_lock at ffffffffc08258c6 [stap_X_40544]
The reason why it can return NULL is because engine->ops is protected by
utrace->lock, but we don't have the utrace pointer, and the purpose of
get_utrace_lock() is to get the utrace pointer. Therefore, there's no way
to ensure engine->ops remains unchanged inside get_utrace_lock(), so
get_utrace_lock()'s checks on engine->ops can be incorrect/stale, which
leads to the NULL pointer dereference.
Previous logic for detecting whether module-signing was required
was broken by the presence of non-systemtap MOK keys. This led
the client to find no matching stap-servers, leading to no
compilation attempt or MOK assignment. New code filters local
MOK keys for Systemtap ones only, and even in an absence,
communicates the need for a signature via a "missing" marker.
The server eagerly passes back (new or old) MOK keys to such a
client now.
Tested on a rhel8 uefi/secureboot kvm vm. Transport /sys/debug
dependencies are still blocking full function due to kernel_lockdown,
but that's coming next.
tentative fix: update hand-written Makefiles to use KBUILD_EXTMOD=
kernel 5.3+ deprecated and then removed the SUBDIRS=
flag for building an external module. In conjunction with KDIR=,
this led to unpredictable results (i.e. a build failure which
would delete the system kernel-devel package's config files (!)).
Commit 0126be38d9 counsels to use M= or KBUILD_EXTMOD= instead.
No harm in specifying both since newer kernels should ignore SUBDIRS=
The rhel4 era (<2.6.15) relayfs transport hasn't been tested for stap
releases in many years, and appears to have no compelling reason to
keep the code around. Let's remove the code.
The non-default ring_buffer transport hasn't even compiled in some
time, and appears to have no compelling reason to keep the code
around. Let's remove the code.
Frank Ch. Eigler [Thu, 27 Aug 2020 17:05:43 +0000 (13:05 -0400)]
man stap.1: belatedly mention type auto-casting
Way back in 2014, starting with 0fb0cac98ad48, an auto-casting
facility was added. This allows context-variable derived pointers to
retain their type information as the pointers are moved around inside
systemtap integer variables & expressions. This was only documented
in the 2.6 release NEWS. Now it's in the man page too.
1) In semantic_pass_optimize1, preserve synthetic probes even with
empty bodies, which would normally be elided. This allows
probe-conditions to be more properly initialized, and
initially-false probes to be disarmed early.
2) In c_unparser::emit_probe(), call emit_lock() based on the
needs_global_locks() lockworthiness of the proper probe (the
derived_probe being translated, rather than the other derived_probe
whose conditions are being evaluated)
This lets the new lock-pushdown.* tests work with or without -u (now
tested).
Frank Ch. Eigler [Mon, 17 Aug 2020 19:49:35 +0000 (15:49 -0400)]
PR26296: lock pushdown optimization
Implements an algorithm to push lock/unlock operations downward in the
syntax tree, to just enclose the smallest possible region that deals
with global variables. This means two common patterns run with much more
concurrency than before:
global a
probe foo {
if (condition)
{ a++ }
else
{ something_else() }
}
will only lock globals -if- the condition is true, so something_else()
would run unlocked. Also:
global a
probe foo {
if (a)
{ long_twisty_operation(); }
}
will unlock globals right after the condition is evaluated, so
long_twisty runs unlocked. Previous behaviour is avilable with
--compatible=4.3. New test case lock-pushdown.stp asserts locking
conditions throughout various relevant constructs.
PR26392: removed the "stable" flag from unwunding tapset functions
By design, stable function calls should be lightweight ones like pid()
and target(). unwinding functions like ubacktrace() are kinda expensive.
And marking them as stable calls would make them get always evaluated no
matter what.
William Cohen [Wed, 5 Aug 2020 13:43:17 +0000 (09:43 -0400)]
Make dtrace generated code work with LTO (take 2)
LTO needs to know which variables might be accessed by code. In sdt.h
there is a fair amount of assembly code which LTO cannot analyze. As
a result LTO would assume that the semaphores variables for various
userspace probes were not accessed by the generated code. The linking
would fail because LTO would optimize away the semphore variables
causing undefined references.
The fix adds the semaphore variables as input operands to the assembly
statements. This gives the LTO analyzer information that the
variables are used within the assembly statements and should not be
removed.
PR26307: adapt to kernel module_sect_attr changes in 5.8+
Linux v5.8 rc5ish, commit ed66f991bb19, introduced a change to the
internal module_sect_attr types. It caused a kernel BUG: with
pr14546.exp. This showed it's futile to keep chasing it this
particular way in runtime/transport/symbols.c, so for new enough
kernels (4.7+), a method based on
kernel_read_file_from_path("/sys/module/$MODULE/sections/$SECTION") is
used to extract module section base-addresses.
This is done by a new paper-thin abstraction. Tested on RHEL7, F32,
rawhide.
PR26249: "%p" -> "0x%lx" pointer formatting in *conversions.stp error messages
function::user_string() and function::user_string_warn() in uconversions.stp
were passing an "unsigned long" to the "%p" format-specifier, which upset gcc10.
Switch to 0x%lx. In the process, change other uses of %p to use 0x%lx instead,
changing casts from (void*) to (unsigned long) where necessary.
Fixes the following error on gcc10 (Fedora 32):
In function ‘function___global_user_string_n_warn__overload_1’:
/tmp/stapXXXXXX/stap_[...]_src.c: error: format ‘%lx’ expects
argument of type ‘long unsigned int’, but argument 5 has type
‘void *’ [-Werror=format=]