tools/testing/selftests/bpf/usdt.h

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/usdt.h

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/usdt.h
Extension
.h
Size
25152 bytes
Lines
548
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct usdt_sema { volatile unsigned short active; };

/*
 * Check if USDT with `group`:`name` identifier is "active" (i.e., whether it
 * is attached to by external tracing tooling and is actively observed).
 *
 * This macro can be used to decide whether any additional and potentially
 * expensive data collection or processing should be done to pass extra
 * information into the given USDT. It is assumed that USDT is triggered with
 * USDT_WITH_SEMA() macro which will implicitly define associated USDT
 * semaphore. (If one needs more control over USDT semaphore, see
 * USDT_DEFINE_SEMA() and USDT_WITH_EXPLICIT_SEMA() macros below.)
 *
 * N.B. Such checks are necessarily racy and speculative. Between checking
 * whether USDT is active and triggering the USDT itself, tracer can be
 * detached with no notification. This race should be extremely rare and worst
 * case should result in one-time wasted extra data collection and processing.
 */
#define USDT_IS_ACTIVE(group, name) ({						\
	extern struct usdt_sema __usdt_sema_name(group, name)			\
		__usdt_asm_name(__usdt_sema_name(group, name));			\
	__usdt_sema_implicit(__usdt_sema_name(group, name));			\
	__usdt_sema_name(group, name).active > 0;				\
})

/*
 * APIs for working with user-defined explicit USDT semaphores.
 *
 * This is a less commonly used advanced API for use cases in which user needs
 * an explicit control over (potentially shared across multiple USDTs) USDT
 * semaphore instance. This can be used when there is a group of logically
 * related USDTs that all need extra data collection and processing whenever
 * any of a family of related USDTs are "activated" (i.e., traced). In such
 * a case, all such related USDTs will be associated with the same shared USDT
 * semaphore defined with USDT_DEFINE_SEMA() and the USDTs themselves will be
 * triggered with USDT_WITH_EXPLICIT_SEMA() macros, taking an explicit extra
 * USDT semaphore identifier as an extra parameter.
 */

/**
 * Underlying C global variable name for user-defined USDT semaphore with
 * `sema` identifier. Could be useful for debugging, but normally shouldn't be
 * used explicitly.
 */
#define USDT_SEMA(sema) __usdt_sema_##sema

/*
 * Define storage for user-defined USDT semaphore `sema`.
 *
 * Should be used only once in non-header source file to let compiler allocate
 * space for the semaphore variable. Just like with any other global variable.
 *
 * This macro can be used anywhere where global variable declaration is
 * allowed. Just like with global variable definitions, there should be only
 * one definition of user-defined USDT semaphore with given `sema` identifier,
 * otherwise compiler or linker will complain about duplicate variable
 * definition.
 *
 * For C++, it is allowed to use USDT_DEFINE_SEMA() both in global namespace
 * and inside namespaces (including nested namespaces). Just make sure that
 * USDT_DECLARE_SEMA() is placed within the namespace where this semaphore is
 * referenced, or any of its parent namespaces, so the C++ language-level
 * identifier is visible to the code that needs to reference the semaphore.
 * At the lowest layer, USDT semaphores have global naming and visibility
 * (they have a corresponding `__usdt_sema_<name>` symbol, which can be linked
 * against from C or C++ code, if necessary). To keep it simple, putting
 * USDT_DECLARE_SEMA() declarations into global namespaces is the simplest
 * no-brainer solution. All these aspects are irrelevant for plain C, because
 * C doesn't have namespaces and everything is always in the global namespace.
 *
 * N.B. Due to USDT metadata being recorded in non-allocatable ELF note
 * section, it has limitations when it comes to relocations, which, in
 * practice, means that it's not possible to correctly share USDT semaphores
 * between main executable and shared libraries, or even between multiple
 * shared libraries. USDT semaphore has to be contained to individual shared
 * library or executable to avoid unpleasant surprises with half-working USDT
 * semaphores. We enforce this by marking semaphore ELF symbols as having
 * a hidden visibility. This is quite an advanced use case and consideration
 * and for most users this should have no consequences whatsoever.
 */
#define USDT_DEFINE_SEMA(sema)							\
	struct usdt_sema __usdt_sema_sec USDT_SEMA(sema)			\
		__usdt_asm_name(USDT_SEMA(sema))				\
		__attribute__((visibility("hidden"))) = { 0 }

/*
 * Declare extern reference to user-defined USDT semaphore `sema`.
 *
 * Refers to a variable defined in another compilation unit by
 * USDT_DEFINE_SEMA() and allows to use the same USDT semaphore across

Annotation

Implementation Notes