tools/testing/selftests/sched_ext/dequeue.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/sched_ext/dequeue.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/sched_ext/dequeue.c
Extension
.c
Size
7940 bytes
Lines
276
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

if ((i & 255) == 0) {
			long long elapsed_ms;

			clock_gettime(CLOCK_MONOTONIC, &now);
			elapsed_ms = (now.tv_sec - start.tv_sec) * 1000LL +
				     (now.tv_nsec - start.tv_nsec) / 1000000;
			if (elapsed_ms >= AFFINITY_HAMMER_MS)
				break;
		}
	}
	return NULL;
}

static enum scx_test_status run_scenario(struct dequeue *skel, u32 scenario,
					 const char *scenario_name)
{
	struct bpf_link *link;
	pid_t pids[NUM_WORKERS];
	pthread_t hammer;

	int i, status;
	u64 enq_start, deq_start,
	    dispatch_deq_start, change_deq_start, bpf_queue_full_start;
	u64 enq_delta, deq_delta,
	    dispatch_deq_delta, change_deq_delta, bpf_queue_full_delta;

	/* Set the test scenario */
	skel->bss->test_scenario = scenario;

	/* Record starting counts */
	enq_start = skel->bss->enqueue_cnt;
	deq_start = skel->bss->dequeue_cnt;
	dispatch_deq_start = skel->bss->dispatch_dequeue_cnt;
	change_deq_start = skel->bss->change_dequeue_cnt;
	bpf_queue_full_start = skel->bss->bpf_queue_full;

	link = bpf_map__attach_struct_ops(skel->maps.dequeue_ops);
	SCX_FAIL_IF(!link, "Failed to attach struct_ops for scenario %s", scenario_name);

	/* Fork worker processes to generate enqueue/dequeue events */
	for (i = 0; i < NUM_WORKERS; i++) {
		pids[i] = fork();
		SCX_FAIL_IF(pids[i] < 0, "Failed to fork worker %d", i);

		if (pids[i] == 0) {
			worker_fn(i);
			/* Should not reach here */
			exit(1);
		}
	}

	/*
	 * Run an "affinity hammer" so that some property changes hit tasks
	 * while they are still in BPF custody (e.g., in user DSQ or BPF
	 * queue), triggering SCX_DEQ_SCHED_CHANGE dequeues.
	 */
	SCX_FAIL_IF(pthread_create(&hammer, NULL, affinity_hammer_fn, pids) != 0,
		    "Failed to create affinity hammer thread");
	pthread_join(hammer, NULL);

	/* Wait for all workers to complete */
	for (i = 0; i < NUM_WORKERS; i++) {
		SCX_FAIL_IF(waitpid(pids[i], &status, 0) != pids[i],
			    "Failed to wait for worker %d", i);
		SCX_FAIL_IF(status != 0, "Worker %d exited with status %d", i, status);
	}

	bpf_link__destroy(link);

	SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_UNREG));

	/* Calculate deltas */
	enq_delta = skel->bss->enqueue_cnt - enq_start;
	deq_delta = skel->bss->dequeue_cnt - deq_start;
	dispatch_deq_delta = skel->bss->dispatch_dequeue_cnt - dispatch_deq_start;
	change_deq_delta = skel->bss->change_dequeue_cnt - change_deq_start;
	bpf_queue_full_delta = skel->bss->bpf_queue_full - bpf_queue_full_start;

	printf("%s:\n", scenario_name);
	printf("  enqueues: %lu\n", (unsigned long)enq_delta);
	printf("  dequeues: %lu (dispatch: %lu, property_change: %lu)\n",
	       (unsigned long)deq_delta,
	       (unsigned long)dispatch_deq_delta,
	       (unsigned long)change_deq_delta);
	printf("  BPF queue full: %lu\n", (unsigned long)bpf_queue_full_delta);

	/*
	 * Validate enqueue/dequeue lifecycle tracking.
	 *
	 * For scenarios 0, 1, 3, 4 (local and global DSQs from

Annotation

Implementation Notes