Blame SOURCES/0004-Prepare-to-handle-thermal-event.patch

7bf5db
From b66647ab757c580b2532c117bd345d1bad3b2bd5 Mon Sep 17 00:00:00 2001
7bf5db
From: "Chang S. Bae" <chang.seok.bae@intel.com>
7bf5db
Date: Thu, 10 Feb 2022 14:46:01 -0800
7bf5db
Subject: [PATCH 04/14] Prepare to handle thermal event
7bf5db
7bf5db
Intel's new hardware supports Hardware Feedback Interface to provide CPU
7bf5db
performance and energy efficiency information. Every update on this is
7bf5db
delivered via thermal event interrupt. The thermal framework in the Linux
7bf5db
kernel relays these notifications to userspace via a Netlink interface.
7bf5db
7bf5db
When a CPU's performance and efficiency are zero, irqbalance needs to mask
7bf5db
the CPU from interrupts. Introduce a new CPU mask to indicate banned CPUs
7bf5db
for this.
7bf5db
7bf5db
Before supporting this event handling, define functions. Their
7bf5db
implementation will be on the following patches.
7bf5db
7bf5db
This event is available only on x86-64 systems. And it can be subscribed
7bf5db
with help of Netlink libraries. So check them before building it.
7bf5db
7bf5db
Also add a new build option so users may opt out this support. Setting this
7bf5db
option on other systems will result in a build failure.
7bf5db
7bf5db
Signed-off-by: Chang S. Bae <chang.seok.bae@intel.com>
7bf5db
---
7bf5db
 Makefile.am  |  7 +++--
7bf5db
 configure.ac | 22 ++++++++++++++
7bf5db
 cputree.c    |  6 ++++
7bf5db
 irqbalance.c |  4 +++
7bf5db
 thermal.c    | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++
7bf5db
 thermal.h    | 15 ++++++++++
7bf5db
 6 files changed, 135 insertions(+), 2 deletions(-)
7bf5db
 create mode 100644 thermal.c
7bf5db
 create mode 100644 thermal.h
7bf5db
7bf5db
diff --git a/Makefile.am b/Makefile.am
7bf5db
index 84e7d46..9181a34 100644
7bf5db
--- a/Makefile.am
7bf5db
+++ b/Makefile.am
7bf5db
@@ -27,7 +27,7 @@ EXTRA_DIST = COPYING autogen.sh misc/irqbalance.service misc/irqbalance.env
7bf5db
 SUBDIRS = tests
7bf5db
 
7bf5db
 UI_DIR = ui
7bf5db
-AM_CFLAGS = $(LIBCAP_NG_CFLAGS) $(GLIB2_CFLAGS) $(NUMA_CFLAGS)
7bf5db
+AM_CFLAGS = $(LIBCAP_NG_CFLAGS) $(GLIB2_CFLAGS) $(NUMA_CFLAGS) $(LIBNL3_CFLAGS)
7bf5db
 AM_CPPFLAGS = -I${top_srcdir} -W -Wall -Wshadow -Wformat -Wundef -D_GNU_SOURCE
7bf5db
 noinst_HEADERS = bitmap.h constants.h cpumask.h irqbalance.h non-atomic.h \
7bf5db
 	types.h $(UI_DIR)/helpers.h $(UI_DIR)/irqbalance-ui.h $(UI_DIR)/ui.h
7bf5db
@@ -39,7 +39,10 @@ endif
7bf5db
 
7bf5db
 irqbalance_SOURCES = activate.c bitmap.c classify.c cputree.c irqbalance.c \
7bf5db
 	irqlist.c numa.c placement.c procinterrupts.c
7bf5db
-irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS) $(NUMA_LIBS)
7bf5db
+if THERMAL
7bf5db
+irqbalance_SOURCES += thermal.c
7bf5db
+endif
7bf5db
+irqbalance_LDADD = $(LIBCAP_NG_LIBS) $(GLIB2_LIBS) $(NUMA_LIBS) $(LIBNL3_LIBS)
7bf5db
 if IRQBALANCEUI
7bf5db
 irqbalance_ui_SOURCES = $(UI_DIR)/helpers.c $(UI_DIR)/irqbalance-ui.c \
7bf5db
 	$(UI_DIR)/ui.c
7bf5db
diff --git a/configure.ac b/configure.ac
7bf5db
index 32082fc..15532c1 100644
7bf5db
--- a/configure.ac
7bf5db
+++ b/configure.ac
7bf5db
@@ -36,6 +36,28 @@ AS_IF([test "x$has_ncursesw" = "xyes"], [
7bf5db
   AC_SUBST([LIBS])
7bf5db
 ])
7bf5db
 
7bf5db
+AC_CANONICAL_HOST
7bf5db
+
7bf5db
+AC_ARG_ENABLE(thermal,
7bf5db
+  AS_HELP_STRING([--enable-thermal], [enable thermal event support [default=auto]]),,
7bf5db
+  AS_IF([test x"$host_cpu" = x"x86_64"], [enable_thermal=yes], [enable_thermal=no])
7bf5db
+)
7bf5db
+
7bf5db
+AS_IF([test x"$enable_thermal" = x"yes" && test x"$host_cpu" != x"x86_64"],
7bf5db
+  AC_MSG_ERROR([no thermal events support on $host_cpu systems.]),
7bf5db
+)
7bf5db
+
7bf5db
+AS_IF([test x"$enable_thermal" = x"yes"],
7bf5db
+  [PKG_CHECK_MODULES([LIBNL3], [libnl-3.0 libnl-genl-3.0], [have_thermal=yes],
7bf5db
+    AC_MSG_NOTICE([no thermal event support as libnl-3.0 is unavailable.])
7bf5db
+  )]
7bf5db
+)
7bf5db
+
7bf5db
+AS_IF([test "x$have_thermal" = xyes],
7bf5db
+  AC_DEFINE([HAVE_THERMAL], 1, [Build irqbalance to support thermal events])
7bf5db
+)
7bf5db
+AM_CONDITIONAL([THERMAL], [test "x$have_thermal" = xyes])
7bf5db
+
7bf5db
 AC_C_CONST
7bf5db
 AC_C_INLINE
7bf5db
 AM_PROG_CC_C_O
7bf5db
diff --git a/cputree.c b/cputree.c
7bf5db
index b716a8f..c250977 100644
7bf5db
--- a/cputree.c
7bf5db
+++ b/cputree.c
7bf5db
@@ -38,6 +38,7 @@
7bf5db
 #include <glib.h>
7bf5db
 
7bf5db
 #include "irqbalance.h"
7bf5db
+#include "thermal.h"
7bf5db
 
7bf5db
 #ifdef HAVE_IRQBALANCEUI
7bf5db
 extern char *banned_cpumask_from_ui;
7bf5db
@@ -162,6 +163,11 @@ static void setup_banned_cpus(void)
7bf5db
 	cpumask_scnprintf(buffer, 4096, nohz_full);
7bf5db
 	log(TO_CONSOLE, LOG_INFO, "Adaptive-ticks CPUs: %s\n", buffer);
7bf5db
 out:
7bf5db
+#ifdef HAVE_THERMAL
7bf5db
+	cpus_or(banned_cpus, banned_cpus, thermal_banned_cpus);
7bf5db
+	cpumask_scnprintf(buffer, 4096, thermal_banned_cpus);
7bf5db
+	log(TO_CONSOLE, LOG_INFO, "Thermal-banned CPUs: %s\n", buffer);
7bf5db
+#endif
7bf5db
 	cpumask_scnprintf(buffer, 4096, banned_cpus);
7bf5db
 	log(TO_CONSOLE, LOG_INFO, "Banned CPUs: %s\n", buffer);
7bf5db
 }
7bf5db
diff --git a/irqbalance.c b/irqbalance.c
7bf5db
index e8d9ba9..c520c11 100644
7bf5db
--- a/irqbalance.c
7bf5db
+++ b/irqbalance.c
7bf5db
@@ -44,6 +44,7 @@
7bf5db
 #include <sys/socket.h>
7bf5db
 #endif
7bf5db
 #include "irqbalance.h"
7bf5db
+#include "thermal.h"
7bf5db
 
7bf5db
 volatile int keep_going = 1;
7bf5db
 int one_shot_mode;
7bf5db
@@ -703,6 +704,8 @@ int main(int argc, char** argv)
7bf5db
 		goto out;
7bf5db
 	}
7bf5db
 #endif
7bf5db
+	if (init_thermal())
7bf5db
+		log(TO_ALL, LOG_WARNING, "Failed to initialize thermal events.\n");
7bf5db
 	main_loop = g_main_loop_new(NULL, FALSE);
7bf5db
 	last_interval = sleep_interval;
7bf5db
 	g_timeout_add_seconds(sleep_interval, scan, NULL);
7bf5db
@@ -711,6 +714,7 @@ int main(int argc, char** argv)
7bf5db
 	g_main_loop_quit(main_loop);
7bf5db
 
7bf5db
 out:
7bf5db
+	deinit_thermal();
7bf5db
 	free_object_tree();
7bf5db
 	free_cl_opts();
7bf5db
 	free(polscript);
7bf5db
diff --git a/thermal.c b/thermal.c
7bf5db
new file mode 100644
7bf5db
index 0000000..308bc48
7bf5db
--- /dev/null
7bf5db
+++ b/thermal.c
7bf5db
@@ -0,0 +1,83 @@
7bf5db
+/*
7bf5db
+ * This program is free software; you can redistribute it and/or modify
7bf5db
+ * it under the terms of the GNU General Public License version 2 as
7bf5db
+ * published by the Free Software Foundation.
7bf5db
+ */
7bf5db
+
7bf5db
+#include <stdio.h>
7bf5db
+
7bf5db
+#include <netlink/genl/genl.h>
7bf5db
+#include <netlink/genl/family.h>
7bf5db
+#include <netlink/genl/ctrl.h>
7bf5db
+
7bf5db
+#include "irqbalance.h"
7bf5db
+
7bf5db
+cpumask_t thermal_banned_cpus;
7bf5db
+
7bf5db
+static gboolean prepare_netlink(void)
7bf5db
+{
7bf5db
+	gboolean error = TRUE;
7bf5db
+
7bf5db
+	log(TO_ALL, LOG_ERR, "thermal: not yet implement to alloc memory for netlink.\n");
7bf5db
+	return error;
7bf5db
+}
7bf5db
+
7bf5db
+#define NL_FAMILY_NAME	"nlctrl"
7bf5db
+
7bf5db
+static gboolean establish_netlink(void)
7bf5db
+{
7bf5db
+	gboolean error = TRUE;
7bf5db
+
7bf5db
+	log(TO_ALL, LOG_ERR, "thermal: not yet implemented to establish netlink.\n");
7bf5db
+	return error;
7bf5db
+}
7bf5db
+
7bf5db
+static gboolean register_netlink_handler(nl_recvmsg_msg_cb_t handler __attribute__((unused)))
7bf5db
+{
7bf5db
+	gboolean error = TRUE;
7bf5db
+
7bf5db
+	log(TO_ALL, LOG_ERR, "thermal: not yet implemented to register thermal handler.\n");
7bf5db
+	return error;
7bf5db
+}
7bf5db
+
7bf5db
+static gboolean set_netlink_nonblocking(void)
7bf5db
+{
7bf5db
+	gboolean error = TRUE;
7bf5db
+
7bf5db
+	log(TO_ALL, LOG_ERR, "thermal: not yet implemented to set nonblocking socket.\n");
7bf5db
+	return error;
7bf5db
+}
7bf5db
+
7bf5db
+void deinit_thermal(void)
7bf5db
+{
7bf5db
+	return;
7bf5db
+}
7bf5db
+
7bf5db
+/*
7bf5db
+ * return value: TRUE with an error; otherwise, FALSE
7bf5db
+ */
7bf5db
+gboolean init_thermal(void)
7bf5db
+{
7bf5db
+	gboolean error;
7bf5db
+
7bf5db
+	error = prepare_netlink();
7bf5db
+	if (error)
7bf5db
+		goto err_out;
7bf5db
+
7bf5db
+	error = establish_netlink();
7bf5db
+	if (error)
7bf5db
+		goto err_out;
7bf5db
+
7bf5db
+	error = register_netlink_handler(NULL);
7bf5db
+	if (error)
7bf5db
+		goto err_out;
7bf5db
+
7bf5db
+	error = set_netlink_nonblocking();
7bf5db
+	if (error)
7bf5db
+		goto err_out;
7bf5db
+
7bf5db
+	return FALSE;
7bf5db
+err_out:
7bf5db
+	deinit_thermal();
7bf5db
+	return TRUE;
7bf5db
+}
7bf5db
diff --git a/thermal.h b/thermal.h
7bf5db
new file mode 100644
7bf5db
index 0000000..657d54e
7bf5db
--- /dev/null
7bf5db
+++ b/thermal.h
7bf5db
@@ -0,0 +1,15 @@
7bf5db
+#ifndef __LINUX_THERMAL_H_
7bf5db
+#define __LINUX_THERMAL_H_
7bf5db
+
7bf5db
+#include <glib.h>
7bf5db
+
7bf5db
+#ifdef HAVE_THERMAL
7bf5db
+gboolean init_thermal(void);
7bf5db
+void deinit_thermal(void);
7bf5db
+extern cpumask_t thermal_banned_cpus;
7bf5db
+#else
7bf5db
+static inline gboolean init_thermal(void) { return FALSE; }
7bf5db
+#define deinit_thermal() do { } while (0)
7bf5db
+#endif
7bf5db
+
7bf5db
+#endif /* __LINUX_THERMAL_H_ */
7bf5db
-- 
7bf5db
2.33.1
7bf5db