brintos

brintos / linux-shallow public Read only

0
0
Text · 3.6 KiB · 87bf220 Raw
169 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * Copyright (c) 2024 Meta Platforms, Inc. and affiliates.4 * Copyright (c) 2024 David Vernet <dvernet@meta.com>5 */6#include <bpf/bpf.h>7#include <sched.h>8#include <scx/common.h>9#include <sched.h>10#include <sys/wait.h>11#include <unistd.h>12 13#include "hotplug_test.h"14#include "hotplug.bpf.skel.h"15#include "scx_test.h"16#include "util.h"17 18const char *online_path = "/sys/devices/system/cpu/cpu1/online";19 20static bool is_cpu_online(void)21{22	return file_read_long(online_path) > 0;23}24 25static void toggle_online_status(bool online)26{27	long val = online ? 1 : 0;28	int ret;29 30	ret = file_write_long(online_path, val);31	if (ret != 0)32		fprintf(stderr, "Failed to bring CPU %s (%s)",33			online ? "online" : "offline", strerror(errno));34}35 36static enum scx_test_status setup(void **ctx)37{38	if (!is_cpu_online())39		return SCX_TEST_SKIP;40 41	return SCX_TEST_PASS;42}43 44static enum scx_test_status test_hotplug(bool onlining, bool cbs_defined)45{46	struct hotplug *skel;47	struct bpf_link *link;48	long kind, code;49 50	SCX_ASSERT(is_cpu_online());51 52	skel = hotplug__open_and_load();53	SCX_ASSERT(skel);54 55	/* Testing the offline -> online path, so go offline before starting */56	if (onlining)57		toggle_online_status(0);58 59	if (cbs_defined) {60		kind = SCX_KIND_VAL(SCX_EXIT_UNREG_BPF);61		code = SCX_ECODE_VAL(SCX_ECODE_ACT_RESTART) | HOTPLUG_EXIT_RSN;62		if (onlining)63			code |= HOTPLUG_ONLINING;64	} else {65		kind = SCX_KIND_VAL(SCX_EXIT_UNREG_KERN);66		code = SCX_ECODE_VAL(SCX_ECODE_ACT_RESTART) |67		       SCX_ECODE_VAL(SCX_ECODE_RSN_HOTPLUG);68	}69 70	if (cbs_defined)71		link = bpf_map__attach_struct_ops(skel->maps.hotplug_cb_ops);72	else73		link = bpf_map__attach_struct_ops(skel->maps.hotplug_nocb_ops);74 75	if (!link) {76		SCX_ERR("Failed to attach scheduler");77		hotplug__destroy(skel);78		return SCX_TEST_FAIL;79	}80 81	toggle_online_status(onlining ? 1 : 0);82 83	while (!UEI_EXITED(skel, uei))84		sched_yield();85 86	SCX_EQ(skel->data->uei.kind, kind);87	SCX_EQ(UEI_REPORT(skel, uei), code);88 89	if (!onlining)90		toggle_online_status(1);91 92	bpf_link__destroy(link);93	hotplug__destroy(skel);94 95	return SCX_TEST_PASS;96}97 98static enum scx_test_status test_hotplug_attach(void)99{100	struct hotplug *skel;101	struct bpf_link *link;102	enum scx_test_status status = SCX_TEST_PASS;103	long kind, code;104 105	SCX_ASSERT(is_cpu_online());106	SCX_ASSERT(scx_hotplug_seq() > 0);107 108	skel = SCX_OPS_OPEN(hotplug_nocb_ops, hotplug);109	SCX_ASSERT(skel);110 111	SCX_OPS_LOAD(skel, hotplug_nocb_ops, hotplug, uei);112 113	/*114	 * Take the CPU offline to increment the global hotplug seq, which115	 * should cause attach to fail due to us setting the hotplug seq above116	 */117	toggle_online_status(0);118	link = bpf_map__attach_struct_ops(skel->maps.hotplug_nocb_ops);119 120	toggle_online_status(1);121 122	SCX_ASSERT(link);123	while (!UEI_EXITED(skel, uei))124		sched_yield();125 126	kind = SCX_KIND_VAL(SCX_EXIT_UNREG_KERN);127	code = SCX_ECODE_VAL(SCX_ECODE_ACT_RESTART) |128	       SCX_ECODE_VAL(SCX_ECODE_RSN_HOTPLUG);129	SCX_EQ(skel->data->uei.kind, kind);130	SCX_EQ(UEI_REPORT(skel, uei), code);131 132	bpf_link__destroy(link);133	hotplug__destroy(skel);134 135	return status;136}137 138static enum scx_test_status run(void *ctx)139{140 141#define HP_TEST(__onlining, __cbs_defined) ({				\142	if (test_hotplug(__onlining, __cbs_defined) != SCX_TEST_PASS)	\143		return SCX_TEST_FAIL;					\144})145 146	HP_TEST(true, true);147	HP_TEST(false, true);148	HP_TEST(true, false);149	HP_TEST(false, false);150 151#undef HP_TEST152 153	return test_hotplug_attach();154}155 156static void cleanup(void *ctx)157{158	toggle_online_status(1);159}160 161struct scx_test hotplug_test = {162	.name = "hotplug",163	.description = "Verify hotplug behavior",164	.setup = setup,165	.run = run,166	.cleanup = cleanup,167};168REGISTER_SCX_TEST(&hotplug_test)169