Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162129866
D57943.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D57943.id.diff
View Options
Index: sys/conf/files
===================================================================
--- sys/conf/files
+++ sys/conf/files
@@ -1441,6 +1441,7 @@
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
dev/cxgbe/cudbg/fastlz_api.c optional cxgbe \
compile-with "${NORMAL_C} -I$S/dev/cxgbe"
+dev/coreindex/coreindex.c optional coreindex
t4fw_cfg.c optional cxgbe \
compile-with "${AWK} -f $S/tools/fw_stub.awk t4fw_cfg.fw:t4fw_cfg t4fw_cfg_uwire.fw:t4fw_cfg_uwire t4fw.fw:t4fw -mt4fw_cfg -c${.TARGET}" \
no-ctfconvert no-implicit-rule before-depend local \
Index: sys/conf/options
===================================================================
--- sys/conf/options
+++ sys/conf/options
@@ -641,6 +641,9 @@
HMP opt_global.h
NUMA opt_global.h
+# CPU core performance/efficiency/capacity manual setting driver for HMP(4)
+COREINDEX opt_coreindex.h
+
# Size of the kernel message buffer
MSGBUF_SIZE opt_msgbuf.h
Index: sys/dev/coreindex/coreindex.c
===================================================================
--- /dev/null
+++ sys/dev/coreindex/coreindex.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (c) 2026 Koine Yuusuke
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sys/cdefs.h>
+#include "opt_global.h"
+#include "opt_coreindex.h"
+
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/lock.h>
+#include <sys/proc.h>
+#include <sys/smp.h>
+#include <sys/hmp.h>
+#include <sys/sysctl.h>
+
+#define COREINDEX_NAME "coreindex"
+#define COREINDEX_HMP_PRIORITY 10
+
+/* Check kernel build option with SMP */
+#ifndef SMP
+#error "coreindex requires the SMP option in the kernel configuraton."
+#endif
+
+/* Check kernel build option with HMP */
+#ifndef HMP
+#error "coreindex requires the HMP option in the kernel configuraton."
+#endif
+
+/*
+ * Structure defines
+ */
+struct coreindex_instance {
+ uint8_t status;
+
+ uint32_t *capacity;
+
+ struct {
+ uint16_t *performance;
+ uint16_t *efficiency;
+ } score;
+
+ struct {
+ struct sysctl_ctx_list ctx;
+ struct sysctl_oid *parent;
+ struct sysctl_oid **core;
+ } sysctl;
+};
+
+#define COREINDEX_STATUS_LOADED (1 << 0) /* status bit0: coreindex loaded */
+
+static struct coreindex_instance cidx_inst;
+
+/*
+ * Prototype defines
+ */
+static uint32_t coreindex_capacity_get_tunable_value(void);
+static int coreindex_capacity_provider_probe(void);
+static int coreindex_capacity_provider_init(void);
+static uint16_t coreindex_score_get_tunable(char *nodename, uint16_t *valptr);
+static int coreindex_score_provider_probe(void);
+static int coreindex_score_provider_init(void);
+static int coreindex_modevent(module_t mod, int type, void *data);
+static int coreindex_register_sysctl(void);
+static int coreindex_capacity_register_sysctl(void);
+static int coreindex_score_set_sysctl(SYSCTL_HANDLER_ARGS);
+static int coreindex_score_register_sysctl(void);
+
+DPCPU_DECLARE(struct hmp_pcpu, hmp_pcpu);
+
+static MALLOC_DEFINE(M_COREINDEX, COREINDEX_NAME, "Buffers for coreindex driver");
+
+/*
+ * HMP capacity provider
+ */
+static uint32_t
+coreindex_capacity_get_tunable_value(void)
+{
+ char path[128];
+ uint64_t value;
+ uint32_t mincap = HMP_CAPACITY_SCALE;
+ uint32_t maxcap = 0;
+
+ /* Set the capacity value of the core for which tunable parameters are configured. */
+ for (int i=0; i<mp_ncpus; i++) {
+ /* Set temporary (not initialized) value */
+ *(cidx_inst.capacity + i) = 0;
+
+ /* Get tunable capacity value */
+ snprintf(path, sizeof(path), "hw.coreindex.%d.capacity", i);
+ if (TUNABLE_UINT64_FETCH(path, &value)) {
+ if ((value > 0) && (value <= HMP_CAPACITY_SCALE))
+ *(cidx_inst.capacity + i) = (uint32_t)value;
+
+ if (mincap > *(cidx_inst.capacity + i))
+ mincap = *(cidx_inst.capacity + i);
+
+ if (maxcap < *(cidx_inst.capacity + i))
+ maxcap = *(cidx_inst.capacity + i);
+ }
+ }
+
+ /* Calc. default capacity value */
+ if ((mincap == HMP_CAPACITY_SCALE) && (maxcap == 0))
+ value = HMP_CAPACITY_SCALE;
+ else
+ value = (mincap + maxcap) / 2;
+
+ /* Set the capacity value of the core for which tunable parameters are NOT configured. */
+ for (int i=0; i<mp_ncpus; i++) {
+ if (*(cidx_inst.capacity + i) > 0)
+ continue;
+
+ /* Get tunable capacity value */
+ *(cidx_inst.capacity + i) = value;
+ }
+
+ return mincap;
+}
+
+static int
+coreindex_capacity_provider_probe(void)
+{
+ return (0);
+}
+
+static int
+coreindex_capacity_provider_init(void)
+{
+ struct hmp_pcpu *hp;
+ uint32_t mincap;
+ uint32_t *capacity;
+ int cpu;
+
+ /* Alloc CPU core perf. value */
+ capacity = malloc((sizeof(uint32_t) * mp_ncpus), M_COREINDEX, M_NOWAIT | M_ZERO);
+ if (capacity == NULL)
+ return (-1);
+
+ cidx_inst.capacity = capacity;
+
+ /* Get tunable capacity value */
+ mincap = coreindex_capacity_get_tunable_value();
+
+ /* Regist sysctl interfaces */
+ if (coreindex_register_sysctl()) {
+ free(cidx_inst.capacity, M_COREINDEX);
+ return (-2);
+ }
+
+ /* Regist sysctl capacity leaf */
+ coreindex_capacity_register_sysctl();
+
+ /* Set CPU core capacity for HMP */
+ CPU_FOREACH(cpu) {
+ hp = DPCPU_ID_PTR(cpu, hmp_pcpu);
+ hp->capacity = HMP_CAPACITY_NORMAL_FROM(*(cidx_inst.capacity + cpu), mincap);
+ }
+
+ /* Set coreindex loaded flag */
+ cidx_inst.status |= COREINDEX_STATUS_LOADED;
+
+ return (0);
+}
+
+static struct hmp_capacity_provider coreindex_capacity_provider = {
+ .name = COREINDEX_NAME,
+ .priority = COREINDEX_HMP_PRIORITY,
+ .probe = coreindex_capacity_provider_probe,
+ .init = coreindex_capacity_provider_init,
+};
+HMP_CAPACITY_PROVIDER_DECLARE(coreindex, coreindex_capacity_provider);
+
+/*
+ * HMP socre provider
+ */
+static uint16_t
+coreindex_score_get_tunable(char *nodename, uint16_t *valptr)
+{
+ char path[128];
+ uint64_t value;
+ uint16_t maxval = 0;
+
+ for (int i=0; i<mp_ncpus; i++) {
+ /* Get tunable score value */
+ snprintf(path, sizeof(path), "hw.coreindex.%d.%s", i, nodename);
+ if (TUNABLE_UINT64_FETCH(path, &value))
+ *(valptr + i) = (uint16_t)((value > HMP_SCORE_MAX) ? HMP_SCORE_DEFAULT : value);
+ else
+ *(valptr + i) = HMP_SCORE_DEFAULT;
+
+ if (maxval < *(valptr + i))
+ maxval = *(valptr + i);
+ }
+
+ return maxval;
+}
+
+static int
+coreindex_score_provider_probe(void)
+{
+ return (0);
+}
+
+static int
+coreindex_score_provider_init(void)
+{
+ struct hmp_pcpu *hp;
+ uint16_t *performance;
+ uint16_t *efficiency;
+ int cpu;
+
+ /* Check capacity provider regist status */
+ if (!(cidx_inst.status & COREINDEX_STATUS_LOADED))
+ return (-1);
+
+ /* Alloc CPU core perf. value */
+ performance = malloc((sizeof(uint16_t) * mp_ncpus), M_COREINDEX, M_NOWAIT | M_ZERO);
+ if (performance == NULL)
+ return (-2);
+
+ cidx_inst.score.performance = performance;
+
+ /* Alloc CPU core efficiency value */
+ efficiency = malloc((sizeof(uint16_t) * mp_ncpus), M_COREINDEX, M_NOWAIT | M_ZERO);
+ if (efficiency == NULL) {
+ free(cidx_inst.score.performance, M_COREINDEX);
+ return (-3);
+ }
+ cidx_inst.score.efficiency = efficiency;
+
+ /* Get tunable capacity value */
+ coreindex_score_get_tunable("performance", performance);
+ coreindex_score_get_tunable("efficiency", efficiency);
+
+ /* Regist sysctl score leaf */
+ coreindex_score_register_sysctl();
+
+ /* Set CPU core capacity for HMP */
+ CPU_FOREACH(cpu) {
+ hp = DPCPU_ID_PTR(cpu, hmp_pcpu);
+ hmp_set_score(hp, HMP_SCORE_PERF, *(cidx_inst.score.performance + cpu));
+ hmp_set_score(hp, HMP_SCORE_EFF, *(cidx_inst.score.efficiency + cpu));
+ }
+
+ printf("coreindex: CPU core performance/efficiency index setter\n");
+
+ return (0);
+}
+
+static struct hmp_score_provider coreindex_score_provider = {
+ .name = COREINDEX_NAME,
+ .priority = COREINDEX_HMP_PRIORITY,
+ .probe = coreindex_score_provider_probe,
+ .init = coreindex_score_provider_init,
+};
+HMP_SCORE_PROVIDER_DECLARE(coreindex, coreindex_score_provider);
+
+/*
+ * Module Interfaces
+ */
+static int
+coreindex_modevent(module_t mod, int type, void *data)
+{
+ switch (type) {
+ case MOD_LOAD:
+ /*
+ * If this driver is enabled in the /boot/loader.conf file, it will be
+ * initialized as a driver module after initialization by hmp(4).
+ * If an error is returned in this case, an error message will be recorded
+ * in dmesg due to double loading, even though it has been loaded successfully.
+ * Therefore, if it has been initialized by hmp(4), zero is returned, and it will
+ * be treated as having been loaded without errors.
+ */
+ if (cidx_inst.status & COREINDEX_STATUS_LOADED)
+ return (0);
+
+ /*
+ * To allow enabling the driver from the /boot/loader.conf file, it is registered
+ * as a driver module, but loading via the kldload command is not permitted.
+ * Therefore, it returns an error.
+ */
+ return (EOPNOTSUPP);
+
+ default:
+ return (EOPNOTSUPP);
+ }
+}
+
+static moduledata_t coreindex_mod = {
+ COREINDEX_NAME, /* module name */
+ coreindex_modevent, /* event handler */
+ NULL
+};
+DECLARE_MODULE(coreindex, coreindex_mod, SI_SUB_SMP + 2, SI_ORDER_ANY);
+
+/*
+ * Sysctls
+ */
+static int
+coreindex_register_sysctl(void)
+{
+ char id[8];
+ char desc[128];
+ struct sysctl_oid *node;
+
+ sysctl_ctx_init(&(cidx_inst.sysctl.ctx));
+
+ /* Regist "hw.coreindex" parent node */
+ cidx_inst.sysctl.parent = SYSCTL_ADD_NODE( &(cidx_inst.sysctl.ctx),
+ SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO, COREINDEX_NAME,
+ CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
+ "coreindex: CPU core performance/efficiency index setter");
+ if (cidx_inst.sysctl.parent == NULL)
+ return (-1);
+
+ /* Alloc sysctl node memory */
+ cidx_inst.sysctl.core = malloc((sizeof(struct sysctl_oid *) * mp_ncpus),
+ M_COREINDEX, M_NOWAIT | M_ZERO);
+ if (cidx_inst.sysctl.core == NULL) {
+ sysctl_ctx_free(&(cidx_inst.sysctl.ctx));
+ return (-2);
+ }
+
+ /* Regist "hw.coreindex.X" node each CPU core id */
+ for (int i=0; i<mp_ncpus; i++) {
+ snprintf(id, sizeof(id), "%d", i);
+ snprintf(desc, sizeof(desc), "CPU core #%d performance/efficiency index", i);
+
+ node = SYSCTL_ADD_NODE(&(cidx_inst.sysctl.ctx), SYSCTL_CHILDREN(cidx_inst.sysctl.parent),
+ OID_AUTO, id, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, desc);
+ if (node == NULL) {
+ sysctl_ctx_free(&(cidx_inst.sysctl.ctx));
+ free(cidx_inst.sysctl.core, M_COREINDEX);
+ return (-3);
+ }
+
+ *(cidx_inst.sysctl.core + i) = node;
+ }
+
+ return (0);
+}
+
+static int
+coreindex_capacity_register_sysctl(void)
+{
+ char desc[128];
+
+ /* Set sysctl capacity value */
+ for (int i=0; i<mp_ncpus; i++) {
+ snprintf(desc, sizeof(desc), "CPU core #%d capacity index", i);
+ SYSCTL_ADD_U32( &(cidx_inst.sysctl.ctx), SYSCTL_CHILDREN(*(cidx_inst.sysctl.core+i)),
+ OID_AUTO, "capacity", CTLFLAG_RDTUN, (cidx_inst.capacity + i), 0, desc);
+ }
+
+ return (0);
+}
+
+static int
+coreindex_score_set_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct hmp_pcpu *hp;
+ uint16_t *valptr;
+ int cpu = arg2;
+ int err, tmpval;
+
+ valptr = (uint16_t *)arg1 + cpu;
+ tmpval = *valptr;
+
+ err = sysctl_handle_int(oidp, &tmpval, 0, req);
+ if (err || req->newptr == NULL)
+ return (err);
+
+ if ((tmpval<0) || (tmpval>1024))
+ return (EINVAL);
+
+ *valptr = (uint16_t)(tmpval & 0xffff);
+
+ hp = DPCPU_ID_PTR(cpu, hmp_pcpu);
+ if ((uint16_t *)arg1 == cidx_inst.score.performance)
+ hmp_set_score(hp, HMP_SCORE_PERF, tmpval);
+ else if ((uint16_t *)arg1 == cidx_inst.score.efficiency)
+ hmp_set_score(hp, HMP_SCORE_EFF, tmpval);
+
+ return (0);
+}
+
+static int
+coreindex_score_register_sysctl(void)
+{
+ char desc[128];
+
+ /* Set sysctl capacity value */
+ for (int i=0; i<mp_ncpus; i++) {
+ snprintf(desc, sizeof(desc), "CPU core #%d performance score index", i);
+ SYSCTL_ADD_PROC(&(cidx_inst.sysctl.ctx), SYSCTL_CHILDREN(*(cidx_inst.sysctl.core+i)),
+ OID_AUTO, "performance", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+ (void *)(cidx_inst.score.performance), i, coreindex_score_set_sysctl,"I", desc);
+
+ snprintf(desc, sizeof(desc), "CPU core #%d efficiency score index", i);
+ SYSCTL_ADD_PROC(&(cidx_inst.sysctl.ctx), SYSCTL_CHILDREN(*(cidx_inst.sysctl.core+i)),
+ OID_AUTO, "efficiency", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
+ (void *)(cidx_inst.score.efficiency), i, coreindex_score_set_sysctl,"I", desc);
+ }
+
+ return (0);
+}
+
Index: sys/modules/Makefile
===================================================================
--- sys/modules/Makefile
+++ sys/modules/Makefile
@@ -87,6 +87,7 @@
${_cfi} \
${_chromebook_platform} \
${_ciss} \
+ ${_coreindex} \
${_coretemp} \
${_cpsw} \
${_cpuctl} \
@@ -813,6 +814,7 @@
_chvgpio= chvgpio
_ciss= ciss
_chromebook_platform= chromebook_platform
+_coreindex= coreindex
_coretemp= coretemp
.if ${MK_SOURCELESS_HOST} != "no" && empty(KCSAN_ENABLED)
_hpt27xx= hpt27xx
Index: sys/modules/coreindex/Makefile
===================================================================
--- /dev/null
+++ sys/modules/coreindex/Makefile
@@ -0,0 +1,6 @@
+.PATH: ${SRCTOP}/sys/dev/coreindex
+
+KMOD= coreindex
+SRCS= coreindex.c bus_if.h device_if.h opt_coreindex.h
+
+.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jul 11, 2:27 AM (11 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34946991
Default Alt Text
D57943.id.diff (12 KB)
Attached To
Mode
D57943: coreindex(4) - Manual capacity/score configuration driver for hmp(4) - Part1: Add coreindex driver's source-code & Makefile.
Attached
Detach File
Event Timeline
Log In to Comment