tools/testing/selftests/bpf/bpf_experimental.h

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/bpf_experimental.h
Extension
.h
Size
16581 bytes
Lines
516
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 pcpu_hot___local {
	int preempt_count;
} __attribute__((preserve_access_index));

extern struct pcpu_hot___local pcpu_hot __ksym __weak;
#endif

struct task_struct___preempt_rt {
	int softirq_disable_cnt;
} __attribute__((preserve_access_index));

#ifdef bpf_target_s390
extern struct lowcore *bpf_get_lowcore(void) __weak __ksym;
#endif

static inline int get_preempt_count(void)
{
#if defined(bpf_target_x86)
	/* By default, read the per-CPU __preempt_count. */
	if (bpf_ksym_exists(&__preempt_count))
		return *(int *) bpf_this_cpu_ptr(&__preempt_count);

	/*
	 * If __preempt_count does not exist, try to read preempt_count under
	 * struct pcpu_hot. Between v6.1 and v6.14 -- more specifically,
	 * [64701838bf057, 46e8fff6d45fe), preempt_count had been managed
	 * under struct pcpu_hot.
	 */
	if (bpf_core_field_exists(pcpu_hot.preempt_count))
		return ((struct pcpu_hot___local *)
			bpf_this_cpu_ptr(&pcpu_hot))->preempt_count;
#elif defined(bpf_target_arm64)
	return bpf_get_current_task_btf()->thread_info.preempt.count;
#elif defined(bpf_target_powerpc)
	return bpf_get_current_task_btf()->thread_info.preempt_count;
#elif defined(bpf_target_s390)
	return bpf_get_lowcore()->preempt_count;
#endif
	return 0;
}

/* Description
 *	Report whether it is in interrupt context. Only works on the following archs:
 *	* x86
 *	* arm64
 *	* powerpc64
 *	* s390x
 */
static inline int bpf_in_interrupt(void)
{
	struct task_struct___preempt_rt *tsk;
	int pcnt;

	pcnt = get_preempt_count();
	if (!CONFIG_PREEMPT_RT)
		return pcnt & (NMI_MASK | HARDIRQ_MASK | SOFTIRQ_MASK);

	tsk = (void *) bpf_get_current_task_btf();
	return (pcnt & (NMI_MASK | HARDIRQ_MASK)) |
	       (tsk->softirq_disable_cnt & SOFTIRQ_MASK);
}

/* Description
 *	Report whether it is in NMI context. Only works on the following archs:
 *	* x86
 *	* arm64
 *	* powerpc64
 *	* s390x
 */
static inline int bpf_in_nmi(void)
{
	return get_preempt_count() & NMI_MASK;
}

/* Description
 *	Report whether it is in hard IRQ context. Only works on the following archs:
 *	* x86
 *	* arm64
 *	* powerpc64
 *	* s390x
 */
static inline int bpf_in_hardirq(void)
{
	return get_preempt_count() & HARDIRQ_MASK;
}

/* Description
 *	Report whether it is in softirq context. Only works on the following archs:
 *	* x86
 *	* arm64

Annotation

Implementation Notes