Files
bpf-developer-tutorial/src/features/bpf_iters/task_stack.c
yunwei37 b88ab2ae0e Add BPF Workqueues support and example
- Introduced BPF workqueues to enable asynchronous work from BPF programs, allowing deferred processing, non-blocking operations, and sleepable contexts for long-running tasks.
- Added README.md to document the BPF workqueues, including use cases, technical architecture, and code examples.
- Created bpf_experimental.h header file to define necessary BPF workqueue functions and structures.
- Implemented a simple BPF workqueue example (wq_simple) demonstrating the initialization, scheduling, and execution of work in a separate context.
- Developed a userspace test (wq_simple.c) to verify the functionality of the BPF workqueue by triggering a syscall and checking the execution results.
2025-10-04 22:49:09 -07:00

94 lines
2.1 KiB
C

// SPDX-License-Identifier: GPL-2.0
/* Userspace program for task stack and file iterator */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <bpf/libbpf.h>
#include <bpf/bpf.h>
#include "task_stack.skel.h"
static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args)
{
return vfprintf(stderr, format, args);
}
static void run_iterator(const char *name, struct bpf_program *prog)
{
struct bpf_link *link;
int iter_fd, len;
char buf[8192];
link = bpf_program__attach_iter(prog, NULL);
if (!link) {
fprintf(stderr, "Failed to attach %s iterator\n", name);
return;
}
iter_fd = bpf_iter_create(bpf_link__fd(link));
if (iter_fd < 0) {
fprintf(stderr, "Failed to create %s iterator: %d\n", name, iter_fd);
bpf_link__destroy(link);
return;
}
while ((len = read(iter_fd, buf, sizeof(buf) - 1)) > 0) {
buf[len] = '\0';
printf("%s", buf);
}
close(iter_fd);
bpf_link__destroy(link);
}
int main(int argc, char **argv)
{
struct task_stack_bpf *skel;
int err;
int show_files = 0;
libbpf_set_print(libbpf_print_fn);
/* Parse arguments */
if (argc > 1 && strcmp(argv[1], "--files") == 0) {
show_files = 1;
argc--;
argv++;
}
/* Open BPF application */
skel = task_stack_bpf__open();
if (!skel) {
fprintf(stderr, "Failed to open BPF skeleton\n");
return 1;
}
/* Configure filter before loading */
if (argc > 1) {
strncpy(skel->bss->target_comm, argv[1], sizeof(skel->bss->target_comm) - 1);
printf("Filtering for tasks matching: %s\n\n", argv[1]);
} else {
printf("Usage: %s [--files] [comm]\n", argv[0]);
printf(" --files Show open file descriptors instead of stacks\n");
printf(" comm Filter by process name\n\n");
}
/* Load BPF program */
err = task_stack_bpf__load(skel);
if (err) {
fprintf(stderr, "Failed to load BPF skeleton\n");
goto cleanup;
}
if (show_files) {
printf("=== BPF Task File Descriptor Iterator ===\n\n");
run_iterator("task_file", skel->progs.dump_task_file);
} else {
printf("=== BPF Task Stack Iterator ===\n\n");
run_iterator("task", skel->progs.dump_task_stack);
}
cleanup:
task_stack_bpf__destroy(skel);
return err;
}