Commit e3d9eac9 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Alexei Starovoitov
Browse files

selftests/bpf: wq: add bpf_wq_init() checks

parent eb48f6cd
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -470,4 +470,5 @@ extern int bpf_iter_css_new(struct bpf_iter_css *it,
extern struct cgroup_subsys_state *bpf_iter_css_next(struct bpf_iter_css *it) __weak __ksym;
extern void bpf_iter_css_destroy(struct bpf_iter_css *it) __weak __ksym;

extern int bpf_wq_init(struct bpf_wq *wq, void *p__map, unsigned int flags) __weak __ksym;
#endif
+8 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
/* Copyright (c) 2024 Benjamin Tissoires */
#include <test_progs.h>
#include "wq.skel.h"
#include "wq_failures.skel.h"

void serial_test_wq(void)
{
@@ -9,3 +10,10 @@ void serial_test_wq(void)

	RUN_TESTS(wq);
}

void serial_test_failures_wq(void)
{
	LIBBPF_OPTS(bpf_test_run_opts, topts);

	RUN_TESTS(wq_failures);
}
+10 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ struct {
static int test_elem_callback(void *map, int *key)
{
	struct elem init = {}, *val;
	struct bpf_wq *wq;

	if (map == &lru &&
	    bpf_map_update_elem(map, key, &init, 0))
@@ -61,12 +62,17 @@ static int test_elem_callback(void *map, int *key)
	if (!val)
		return -2;

	wq = &val->w;
	if (bpf_wq_init(wq, map, 0) != 0)
		return -3;

	return 0;
}

static int test_hmap_elem_callback(void *map, int *key)
{
	struct hmap_elem init = {}, *val;
	struct bpf_wq *wq;

	if (bpf_map_update_elem(map, key, &init, 0))
		return -1;
@@ -75,6 +81,10 @@ static int test_hmap_elem_callback(void *map, int *key)
	if (!val)
		return -2;

	wq = &val->work;
	if (bpf_wq_init(wq, map, 0) != 0)
		return -3;

	return 0;
}

+78 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2024 Benjamin Tissoires
 */

#include "bpf_experimental.h"
#include <bpf/bpf_helpers.h>
#include "bpf_misc.h"
#include "../bpf_testmod/bpf_testmod_kfunc.h"

char _license[] SEC("license") = "GPL";

struct elem {
	struct bpf_wq w;
};

struct {
	__uint(type, BPF_MAP_TYPE_ARRAY);
	__uint(max_entries, 2);
	__type(key, int);
	__type(value, struct elem);
} array SEC(".maps");

struct {
	__uint(type, BPF_MAP_TYPE_LRU_HASH);
	__uint(max_entries, 4);
	__type(key, int);
	__type(value, struct elem);
} lru SEC(".maps");

SEC("tc")
/* test that bpf_wq_init takes a map as a second argument
 */
__log_level(2)
__flag(BPF_F_TEST_STATE_FREQ)
__failure
__msg(": (85) call bpf_wq_init#") /* anchor message */
__msg("pointer in R2 isn't map pointer")
long test_wq_init_nomap(void *ctx)
{
	struct bpf_wq *wq;
	struct elem *val;
	int key = 0;

	val = bpf_map_lookup_elem(&array, &key);
	if (!val)
		return -1;

	wq = &val->w;
	if (bpf_wq_init(wq, &key, 0) != 0)
		return -3;

	return 0;
}

SEC("tc")
/* test that the workqueue is part of the map in bpf_wq_init
 */
__log_level(2)
__flag(BPF_F_TEST_STATE_FREQ)
__failure
__msg(": (85) call bpf_wq_init#") /* anchor message */
__msg("workqueue pointer in R1 map_uid=0 doesn't match map pointer in R2 map_uid=0")
long test_wq_init_wrong_map(void *ctx)
{
	struct bpf_wq *wq;
	struct elem *val;
	int key = 0;

	val = bpf_map_lookup_elem(&array, &key);
	if (!val)
		return -1;

	wq = &val->w;
	if (bpf_wq_init(wq, &lru, 0) != 0)
		return -3;

	return 0;
}