/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2024 Meta Platforms, Inc. and affiliates.
 * Copyright (c) 2024 Tejun Heo <tj@kernel.org>
 * Copyright (c) 2024 David Vernet <dvernet@meta.com>
 */
#ifndef __SCX_COMPAT_H
#define __SCX_COMPAT_H

#include <bpf/btf.h>
#include <bpf/libbpf.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "enums_abi.autogen.h"

struct btf *__COMPAT_vmlinux_btf __attribute__((weak));

static inline void __COMPAT_load_vmlinux_btf(void)
{
	if (!__COMPAT_vmlinux_btf) {
		__COMPAT_vmlinux_btf = btf__load_vmlinux_btf();
		SCX_BUG_ON(!__COMPAT_vmlinux_btf, "btf__load_vmlinux_btf()");
	}
}

/*
 * Recover the true value of a 64-bit enum enumerator whose kernel BTF entry
 * was truncated to its low 32 bits.
 *
 * Kernels whose BTF was generated without BTF_KIND_ENUM64 support encode
 * 64-bit enums as 8-byte BTF_KIND_ENUM entries whose enumerator values only
 * carry the low 32 bits. This happens with pahole < 1.24, which predates
 * ENUM64, and with pahole passing --skip_encoding_btf_enum64 (e.g. Google's
 * Container-Optimized OS / GKE kernels deliberately pass it for backward
 * compatibility with older BTF consumers). The high bits
 * can't be recovered from kernel BTF, so substitute the value from the
 * vmlinux.h this tree was built against, cross-checked against the low 32
 * bits the kernel did provide.
 *
 * Note that this is a best-effort recovery, not a ground truth. The
 * substitution assumes the running kernel agrees with this tree's vmlinux.h
 * on the high 32 bits, but only the low 32 bits can actually be verified.
 * The cross-check is vacuous for enumerators whose value has no low bits
 * set (e.g. SCX_DSQ_FLAG_BUILTIN, __SCX_ENQ_INTERNAL_MASK,
 * SCX_ENQ_CLEAR_OPSS, SCX_ECODE_*): their lo32 is 0 and matches anything,
 * so those substitutions rest entirely on the high bits never moving. An
 * enumerator missing from the table (a kernel newer than this tree's
 * vmlinux.h, or a stale autogen table) can't be recovered at all. If a
 * substitution is ever wrong, the scheduler operates on bogus values (e.g.
 * dispatching to nonexistent DSQ ids or silently dropping flags) and can
 * wildly malfunction, which is why the mismatch and table-miss paths refuse
 * instead of guessing.
 */
static inline bool __COMPAT_recover_truncated_enum64(const char *type,
						     const char *name,
						     u32 lo32, u64 *v)
{
	static bool warned;
	size_t i;

	for (i = 0; i < sizeof(__scx_enum_abi_vals) / sizeof(__scx_enum_abi_vals[0]); i++) {
		const struct __scx_enum_abi_val *e = &__scx_enum_abi_vals[i];

		if (strcmp(e->type, type) || strcmp(e->name, name))
			continue;

		if (e->val <= (u64)UINT32_MAX) {
			*v = lo32;
			return true;
		}

		if ((u32)e->val != lo32) {
			fprintf(stderr, "ERROR: kernel BTF value of %s::%s (0x%x) doesn't match the low 32 bits of the vmlinux.h value (0x%llx); refusing to substitute\n",
				type, name, lo32, (unsigned long long)e->val);
			return false;
		}

		if (!warned) {
			fprintf(stderr,
				"WARNING: kernel BTF lacks BTF_KIND_ENUM64 encoding (generated by\n"
				"WARNING: pahole < 1.24 or with --skip_encoding_btf_enum64), so 64-bit\n"
				"WARNING: scx enum values are truncated to their low 32 bits in kernel\n"
				"WARNING: BTF. Substituting the full 64-bit values from the vmlinux.h\n"
				"WARNING: this binary was built against, cross-checked against the low\n"
				"WARNING: 32 bits the kernel does provide. The high 32 bits cannot be\n"
				"WARNING: verified: if the running kernel's actual values differ from\n"
				"WARNING: the build-time vmlinux.h (e.g. an enum that moved in a newer\n"
				"WARNING: kernel), the scheduler will operate on bogus values, such as\n"
				"WARNING: dispatching to nonexistent DSQ ids, and can wildly malfunction.\n");
			warned = true;
		}
		*v = e->val;
		return true;
	}

	/*
	 * Unknown enumerator (likely a stale autogen table). Fail
	 * pessimistically to avoid returning an invalid value.
	 */
	fprintf(stderr, "ERROR: kernel BTF truncates 64-bit enum %s::%s to 0x%x; 64-bit variant not found in vmlinux.h\n",
		type, name, lo32);
	return false;
}

static inline bool __COMPAT_read_enum(const char *type, const char *name, u64 *v)
{
	const struct btf_type *t;
	const char *n;
	s32 tid;
	__u32 i;

	__COMPAT_load_vmlinux_btf();

	tid = btf__find_by_name(__COMPAT_vmlinux_btf, type);
	if (tid < 0)
		return false;

	t = btf__type_by_id(__COMPAT_vmlinux_btf, tid);
	SCX_BUG_ON(!t, "btf__type_by_id(%d)", tid);

	if (btf_is_enum(t)) {
		struct btf_enum *e = btf_enum(t);

		for (i = 0; i < btf_vlen(t); i++) {
			n = btf__name_by_offset(__COMPAT_vmlinux_btf, e[i].name_off);
			SCX_BUG_ON(!n, "btf__name_by_offset()");
			if (!strcmp(n, name)) {
				/*
				 * Try to recover a 64-bit enum from an 8-byte
				 * BTF_KIND_ENUM that was encoded without ENUM64
				 * support (old pahole or
				 * --skip_encoding_btf_enum64). Only scx_*
				 * types are covered by the substitution table;
				 * non-scx types fall through to the raw value
				 * so this generic utility keeps working for
				 * them.
				 */
				if (t->size == 8 && !strncmp(type, "scx_", 4))
					return __COMPAT_recover_truncated_enum64(type, name,
										 (u32)e[i].val, v);
				*v = e[i].val;
				return true;
			}
		}
	} else if (btf_is_enum64(t)) {
		struct btf_enum64 *e = btf_enum64(t);

		for (i = 0; i < btf_vlen(t); i++) {
			n = btf__name_by_offset(__COMPAT_vmlinux_btf, e[i].name_off);
			SCX_BUG_ON(!n, "btf__name_by_offset()");
			if (!strcmp(n, name)) {
				*v = btf_enum64_value(&e[i]);
				return true;
			}
		}
	}

	return false;
}

#define __COMPAT_ENUM_OR_ZERO(__type, __ent)					\
({										\
	u64 __val = 0;								\
	__COMPAT_read_enum(__type, __ent, &__val);				\
	__val;									\
})

static inline bool __COMPAT_has_ksym(const char *ksym)
{
	__COMPAT_load_vmlinux_btf();
	return btf__find_by_name(__COMPAT_vmlinux_btf, ksym) >= 0;
}

static inline bool __COMPAT_struct_has_field(const char *type, const char *field)
{
	const struct btf_type *t;
	const struct btf_member *m;
	const char *n;
	s32 tid;
	__u32 i;

	__COMPAT_load_vmlinux_btf();
	tid = btf__find_by_name_kind(__COMPAT_vmlinux_btf, type, BTF_KIND_STRUCT);
	if (tid < 0)
		return false;

	t = btf__type_by_id(__COMPAT_vmlinux_btf, tid);
	SCX_BUG_ON(!t, "btf__type_by_id(%d)", tid);

	m = btf_members(t);

	for (i = 0; i < btf_vlen(t); i++) {
		n = btf__name_by_offset(__COMPAT_vmlinux_btf, m[i].name_off);
		SCX_BUG_ON(!n, "btf__name_by_offset()");
			if (!strcmp(n, field))
				return true;
	}

	return false;
}

#define SCX_OPS_FLAG(name) __COMPAT_ENUM_OR_ZERO("scx_ops_flags", #name)

#define SCX_OPS_KEEP_BUILTIN_IDLE SCX_OPS_FLAG(SCX_OPS_KEEP_BUILTIN_IDLE)
#define SCX_OPS_ENQ_LAST SCX_OPS_FLAG(SCX_OPS_ENQ_LAST)
#define SCX_OPS_ENQ_EXITING  SCX_OPS_FLAG(SCX_OPS_ENQ_EXITING)
#define SCX_OPS_SWITCH_PARTIAL SCX_OPS_FLAG(SCX_OPS_SWITCH_PARTIAL)
#define SCX_OPS_ENQ_MIGRATION_DISABLED SCX_OPS_FLAG(SCX_OPS_ENQ_MIGRATION_DISABLED)
#define SCX_OPS_ALLOW_QUEUED_WAKEUP SCX_OPS_FLAG(SCX_OPS_ALLOW_QUEUED_WAKEUP)
#define SCX_OPS_BUILTIN_IDLE_PER_NODE SCX_OPS_FLAG(SCX_OPS_BUILTIN_IDLE_PER_NODE)
#define SCX_OPS_ALWAYS_ENQ_IMMED SCX_OPS_FLAG(SCX_OPS_ALWAYS_ENQ_IMMED)

#define SCX_PICK_IDLE_FLAG(name) __COMPAT_ENUM_OR_ZERO("scx_pick_idle_cpu_flags", #name)

#define SCX_PICK_IDLE_CORE SCX_PICK_IDLE_FLAG(SCX_PICK_IDLE_CORE)
#define SCX_PICK_IDLE_IN_NODE SCX_PICK_IDLE_FLAG(SCX_PICK_IDLE_IN_NODE)

static inline long scx_hotplug_seq(void)
{
	int fd;
	char buf[32];
	char *endptr;
	ssize_t len;
	long val;

	fd = open("/sys/kernel/sched_ext/hotplug_seq", O_RDONLY);
	if (fd < 0)
		return -ENOENT;

	len = read(fd, buf, sizeof(buf) - 1);
	SCX_BUG_ON(len <= 0, "read failed (%ld)", len);
	buf[len] = 0;
	close(fd);

	errno = 0;
	val = strtoul(buf, &endptr, 10);
	SCX_BUG_ON(errno == ERANGE || endptr == buf ||
		   (*endptr != '\n' && *endptr != '\0'), "invalid num hotplug events: %ld", val);

	return val;
}

/*
 * Open the sched_ext_ops skeleton.
 *
 * struct sched_ext_ops can change over time. Two complementary mechanisms
 * keep BPF schedulers built against newer headers running on older kernels:
 *
 * 1. Load-time fix-up (SCX_OPS_OPEN()). For each optional ops callback or field
 *    added to struct sched_ext_ops, an explicit stanza below probes the
 *    running kernel's BTF via __COMPAT_struct_has_field() and, if the field
 *    is missing, clears it in the in-memory struct_ops (with a warning to
 *    stderr) before load. Handles additive changes - a new stanza must be
 *    added here for each new optional field.
 *
 * 2. Multi-variant struct_ops via compat.bpf.h::SCX_OPS_DEFINE(). That
 *    macro can be expanded to emit several variants of struct sched_ext_ops,
 *    and SCX_OPS_LOAD()/ATTACH() can pick the right one based on what the
 *    kernel supports. Needed when an existing operation has to change
 *    incompatibly (e.g. a callback signature changes); the load-time
 *    fix-up above only handles purely additive changes.
 *
 * ec7e3b0463e1 ("implement-ops") in https://github.com/sched-ext/sched_ext is
 * the current minimum required kernel version.
 *
 * COMPAT:
 * - v6.17: ops.cgroup_set_bandwidth()
 * - v6.19: ops.cgroup_set_idle()
 * - v7.1:  ops.sub_attach(), ops.sub_detach(), ops.sub_cgroup_id
 * - v7.3:  ops.rescue_bandwidth_ppt, ops.rescue_quantum_us
 */
#define __SCX_OPS_OPEN(__ops_name, __scx_name, __ops_struct) ({			\
	struct __scx_name *__oskel;						\
										\
	SCX_BUG_ON(!__COMPAT_struct_has_field(__ops_struct, "dump"),		\
		   __ops_struct ".dump() missing, kernel too old?");		\
										\
	__oskel = __scx_name##__open();						\
	SCX_BUG_ON(!__oskel, "Could not open " #__scx_name);			\
	__oskel->struct_ops.__ops_name->hotplug_seq = scx_hotplug_seq();	\
	SCX_ENUM_INIT(__oskel);							\
	__oskel;								\
})

#define SCX_OPS_OPEN(__ops_name, __scx_name) ({					\
	struct __scx_name *__skel;						\
										\
	__skel = __SCX_OPS_OPEN(__ops_name, __scx_name, "sched_ext_ops");	\
	if (__skel->struct_ops.__ops_name->cgroup_set_bandwidth &&		\
	    !__COMPAT_struct_has_field("sched_ext_ops", "cgroup_set_bandwidth")) { \
		fprintf(stderr, "WARNING: kernel doesn't support ops.cgroup_set_bandwidth()\n"); \
		__skel->struct_ops.__ops_name->cgroup_set_bandwidth = NULL;	\
	}									\
	if (__skel->struct_ops.__ops_name->cgroup_set_idle &&			\
	    !__COMPAT_struct_has_field("sched_ext_ops", "cgroup_set_idle")) { \
		fprintf(stderr, "WARNING: kernel doesn't support ops.cgroup_set_idle()\n"); \
		__skel->struct_ops.__ops_name->cgroup_set_idle = NULL;	\
	}									\
	if (__skel->struct_ops.__ops_name->sub_attach &&			\
	    !__COMPAT_struct_has_field("sched_ext_ops", "sub_attach")) {	\
		fprintf(stderr, "WARNING: kernel doesn't support ops.sub_attach()\n"); \
		__skel->struct_ops.__ops_name->sub_attach = NULL;		\
	}									\
	if (__skel->struct_ops.__ops_name->sub_detach &&			\
	    !__COMPAT_struct_has_field("sched_ext_ops", "sub_detach")) {	\
		fprintf(stderr, "WARNING: kernel doesn't support ops.sub_detach()\n"); \
		__skel->struct_ops.__ops_name->sub_detach = NULL;		\
	}									\
	if (__skel->struct_ops.__ops_name->sub_cgroup_id > 0 &&		\
	    !__COMPAT_struct_has_field("sched_ext_ops", "sub_cgroup_id")) { \
		fprintf(stderr, "WARNING: kernel doesn't support ops.sub_cgroup_id\n"); \
		__skel->struct_ops.__ops_name->sub_cgroup_id = 0;		\
	}									\
	if (__skel->struct_ops.__ops_name->rescue_bandwidth_ppt > 0 &&		\
	    !__COMPAT_struct_has_field("sched_ext_ops", "rescue_bandwidth_ppt")) { \
		fprintf(stderr, "WARNING: kernel doesn't support ops.rescue_bandwidth_ppt\n"); \
		__skel->struct_ops.__ops_name->rescue_bandwidth_ppt = 0;	\
	}									\
	if (__skel->struct_ops.__ops_name->rescue_quantum_us > 0 &&		\
	    !__COMPAT_struct_has_field("sched_ext_ops", "rescue_quantum_us")) { \
		fprintf(stderr, "WARNING: kernel doesn't support ops.rescue_quantum_us\n"); \
		__skel->struct_ops.__ops_name->rescue_quantum_us = 0;		\
	}									\
	__skel; 								\
})

/*
 * Open a cid-form (struct sched_ext_ops_cid) skeleton. The cid form postdates
 * every op the load-time fix-ups above handle, so none of them apply.
 */
#define SCX_OPS_CID_OPEN(__ops_name, __scx_name)				\
	__SCX_OPS_OPEN(__ops_name, __scx_name, "sched_ext_ops_cid")

/*
 * Associate non-struct_ops BPF programs with the scheduler's struct_ops map so
 * that scx_prog_sched() can determine which scheduler a BPF program belongs
 * to. Requires libbpf >= 1.7.
 */
#if LIBBPF_MAJOR_VERSION > 1 ||							\
	(LIBBPF_MAJOR_VERSION == 1 && LIBBPF_MINOR_VERSION >= 7)
static inline void __scx_ops_assoc_prog(struct bpf_program *prog,
					struct bpf_map *map,
					const char *ops_name)
{
	s32 err = bpf_program__assoc_struct_ops(prog, map, NULL);
	if (err)
		fprintf(stderr,
			"ERROR: Failed to associate %s with %s: %d\n",
			bpf_program__name(prog), ops_name, err);
}
#else
static inline void __scx_ops_assoc_prog(struct bpf_program *prog,
					struct bpf_map *map,
					const char *ops_name)
{
}
#endif

/* See SCX_OPS_OPEN() above for backward-compatibility handling. */
#define SCX_OPS_LOAD(__skel, __ops_name, __scx_name, __uei_name) ({		\
	struct bpf_program *__prog;						\
	UEI_SET_SIZE(__skel, __ops_name, __uei_name);				\
	SCX_BUG_ON(__scx_name##__load((__skel)), "Failed to load skel");	\
	bpf_object__for_each_program(__prog, (__skel)->obj) {			\
		if (bpf_program__type(__prog) == BPF_PROG_TYPE_STRUCT_OPS)	\
			continue;						\
		__scx_ops_assoc_prog(__prog, (__skel)->maps.__ops_name,		\
				     #__ops_name);				\
	}									\
})

/*
 * New versions of bpftool now emit additional link placeholders for BPF maps,
 * and set up BPF skeleton in such a way that libbpf will auto-attach BPF maps
 * automatically, assuming libbpf is recent enough (v1.5+). Old libbpf will do
 * nothing with those links and won't attempt to auto-attach maps.
 *
 * To maintain compatibility with older libbpf while avoiding trying to attach
 * twice, disable the autoattach feature on newer libbpf.
 */
#if LIBBPF_MAJOR_VERSION > 1 ||							\
	(LIBBPF_MAJOR_VERSION == 1 && LIBBPF_MINOR_VERSION >= 5)
#define __SCX_OPS_DISABLE_AUTOATTACH(__skel, __ops_name)			\
	bpf_map__set_autoattach((__skel)->maps.__ops_name, false)
#else
#define __SCX_OPS_DISABLE_AUTOATTACH(__skel, __ops_name) do {} while (0)
#endif

#define SCX_OPS_ATTACH(__skel, __ops_name, __scx_name) ({			\
	struct bpf_link *__link;						\
	__SCX_OPS_DISABLE_AUTOATTACH(__skel, __ops_name);			\
	SCX_BUG_ON(__scx_name##__attach((__skel)), "Failed to attach skel");	\
	__link = bpf_map__attach_struct_ops((__skel)->maps.__ops_name);		\
	SCX_BUG_ON(!__link, "Failed to attach struct_ops");			\
	__link;									\
})

#endif	/* __SCX_COMPAT_H */
