All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] tools/thermal: thermal library and tools
@ 2022-03-30 10:04 Daniel Lezcano
  2022-03-30 10:04 ` [PATCH v2 1/4] tools/lib/thermal: Add a thermal library Daniel Lezcano
                   ` (4 more replies)
  0 siblings, 5 replies; 19+ messages in thread
From: Daniel Lezcano @ 2022-03-30 10:04 UTC (permalink / raw)
  To: daniel.lezcano, rafael; +Cc: srinivas.pandruvada, linux-kernel, linux-pm

These changes are providing the following tools and library:

 - A thermal library doing the netlink abstraction from the kernel in
   order to make the userspace thermal implementation easier. Having
   the library integrated with the kernel tree is also a guarantee to
   keep the message format and their encoding/decoding aligned
                                                                                                                                                                                                                                                                               
 - A thermal tools library providing a set of functions to deal with
   usual features like the log, the mainloop and the time. This
   library is used by the provided tools below

 - An data acquisition program to capture the temperature of the
   different thermal zone during an amount of time or during the
   execution of an application. The output is formated to be easily
   parsed by gnuplot, a spreadsheet program or a statistical command
   line utility. The timestamp is based on the system uptime, thus
   giving an indication of when a thermal event happened, that can
   help to spot or reproduce thermal issue in the long run

 - A thermal monitoring program based on the thermal library. It gives
   a skeleton to build any logic on top of it and shows how to use the
   thermal library. It does nothing except discovering the thermal
   zones, their trip points and listening for events like cooling
   devices state changes or trip point crossed

 Changelog:

 v1: Initial post after a RFC

 v2:

  - Fixed all trailing whitespaces and some other checkpatch
    warnings. Some warnings remain but they can be considered as false
    positive

  - Added in the thermometer tool:
    - Usage/help option as well as a man page
    - The ability to execute a program
    - The capture duration
    - Create the output directory if it does not exist

  - Add in the thermal-engine tool:
    - A usage/help option
    - A message telling the userspace it is waiting for events
    - A daemonize option

  - Minor bug fixes here and there, as well as typos

Daniel Lezcano (4):
  tools/lib/thermal: Add a thermal library
  tools/thermal: Add util library
  tools/thermal: A temperature capture tool
  tools/thermal: Add thermal daemon skeleton

 MAINTAINERS                                   |   1 +
 tools/Makefile                                |  36 +-
 tools/lib/thermal/.gitignore                  |   2 +
 tools/lib/thermal/Build                       |   5 +
 tools/lib/thermal/Makefile                    | 165 ++++++
 tools/lib/thermal/commands.c                  | 349 +++++++++++
 tools/lib/thermal/events.c                    | 164 +++++
 tools/lib/thermal/include/thermal.h           | 142 +++++
 tools/lib/thermal/libthermal.map              |  25 +
 tools/lib/thermal/libthermal.pc.template      |  12 +
 tools/lib/thermal/sampling.c                  |  75 +++
 tools/lib/thermal/thermal.c                   | 126 ++++
 tools/lib/thermal/thermal_nl.c                | 215 +++++++
 tools/lib/thermal/thermal_nl.h                |  46 ++
 tools/thermal/lib/Build                       |   3 +
 tools/thermal/lib/Makefile                    | 158 +++++
 .../thermal/lib/libthermal_tools.pc.template  |  12 +
 tools/thermal/lib/log.c                       |  77 +++
 tools/thermal/lib/log.h                       |  31 +
 tools/thermal/lib/mainloop.c                  | 120 ++++
 tools/thermal/lib/mainloop.h                  |  15 +
 tools/thermal/lib/thermal-tools.h             |  10 +
 tools/thermal/lib/uptimeofday.c               |  40 ++
 tools/thermal/lib/uptimeofday.h               |  12 +
 tools/thermal/thermal-engine/Build            |   2 +
 tools/thermal/thermal-engine/Makefile         |  28 +
 tools/thermal/thermal-engine/thermal-engine.c | 326 ++++++++++
 tools/thermal/thermometer/Build               |   2 +
 tools/thermal/thermometer/Makefile            |  26 +
 tools/thermal/thermometer/thermometer.8       |  93 +++
 tools/thermal/thermometer/thermometer.c       | 558 ++++++++++++++++++
 tools/thermal/thermometer/thermometer.conf    |   5 +
 32 files changed, 2878 insertions(+), 3 deletions(-)
 create mode 100644 tools/lib/thermal/.gitignore
 create mode 100644 tools/lib/thermal/Build
 create mode 100644 tools/lib/thermal/Makefile
 create mode 100644 tools/lib/thermal/commands.c
 create mode 100644 tools/lib/thermal/events.c
 create mode 100644 tools/lib/thermal/include/thermal.h
 create mode 100644 tools/lib/thermal/libthermal.map
 create mode 100644 tools/lib/thermal/libthermal.pc.template
 create mode 100644 tools/lib/thermal/sampling.c
 create mode 100644 tools/lib/thermal/thermal.c
 create mode 100644 tools/lib/thermal/thermal_nl.c
 create mode 100644 tools/lib/thermal/thermal_nl.h
 create mode 100644 tools/thermal/lib/Build
 create mode 100644 tools/thermal/lib/Makefile
 create mode 100644 tools/thermal/lib/libthermal_tools.pc.template
 create mode 100644 tools/thermal/lib/log.c
 create mode 100644 tools/thermal/lib/log.h
 create mode 100644 tools/thermal/lib/mainloop.c
 create mode 100644 tools/thermal/lib/mainloop.h
 create mode 100644 tools/thermal/lib/thermal-tools.h
 create mode 100644 tools/thermal/lib/uptimeofday.c
 create mode 100644 tools/thermal/lib/uptimeofday.h
 create mode 100644 tools/thermal/thermal-engine/Build
 create mode 100644 tools/thermal/thermal-engine/Makefile
 create mode 100644 tools/thermal/thermal-engine/thermal-engine.c
 create mode 100644 tools/thermal/thermometer/Build
 create mode 100644 tools/thermal/thermometer/Makefile
 create mode 100644 tools/thermal/thermometer/thermometer.8
 create mode 100644 tools/thermal/thermometer/thermometer.c
 create mode 100644 tools/thermal/thermometer/thermometer.conf

-- 
2.25.1


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v2 1/4] tools/lib/thermal: Add a thermal library
  2022-03-30 10:04 [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
@ 2022-03-30 10:04 ` Daniel Lezcano
  2022-03-30 10:04 ` [PATCH v2 2/4] tools/thermal: Add util library Daniel Lezcano
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: Daniel Lezcano @ 2022-03-30 10:04 UTC (permalink / raw)
  To: daniel.lezcano, rafael
  Cc: srinivas.pandruvada, linux-kernel, linux-pm, Amit Kucheria,
	Zhang Rui, Mauro Carvalho Chehab, Rob Herring, Hans de Goede,
	David S. Miller, Krzysztof Kozlowski, Lukas Bulwahn,
	Jonathan Cameron, William Breathitt Gray, Sasha Levin

The thermal framework implements a netlink notification mechanism to
be used by the userspace to have a thermal configuration discovery,
trip point changes or violation, cooling device changes notifications,
etc...

This library provides a level of abstraction for the thermal netlink
notification allowing the userspace to connect to the notification
mechanism more easily. The library is callback oriented.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 MAINTAINERS                              |   1 +
 tools/Makefile                           |  14 +-
 tools/lib/thermal/.gitignore             |   2 +
 tools/lib/thermal/Build                  |   5 +
 tools/lib/thermal/Makefile               | 165 +++++++++++
 tools/lib/thermal/commands.c             | 349 +++++++++++++++++++++++
 tools/lib/thermal/events.c               | 164 +++++++++++
 tools/lib/thermal/include/thermal.h      | 142 +++++++++
 tools/lib/thermal/libthermal.map         |  25 ++
 tools/lib/thermal/libthermal.pc.template |  12 +
 tools/lib/thermal/sampling.c             |  75 +++++
 tools/lib/thermal/thermal.c              | 126 ++++++++
 tools/lib/thermal/thermal_nl.c           | 215 ++++++++++++++
 tools/lib/thermal/thermal_nl.h           |  46 +++
 14 files changed, 1339 insertions(+), 2 deletions(-)
 create mode 100644 tools/lib/thermal/.gitignore
 create mode 100644 tools/lib/thermal/Build
 create mode 100644 tools/lib/thermal/Makefile
 create mode 100644 tools/lib/thermal/commands.c
 create mode 100644 tools/lib/thermal/events.c
 create mode 100644 tools/lib/thermal/include/thermal.h
 create mode 100644 tools/lib/thermal/libthermal.map
 create mode 100644 tools/lib/thermal/libthermal.pc.template
 create mode 100644 tools/lib/thermal/sampling.c
 create mode 100644 tools/lib/thermal/thermal.c
 create mode 100644 tools/lib/thermal/thermal_nl.c
 create mode 100644 tools/lib/thermal/thermal_nl.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 3bcb6f13617f..07fb2d6e2810 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19129,6 +19129,7 @@ F:	drivers/thermal/
 F:	include/linux/cpu_cooling.h
 F:	include/linux/thermal.h
 F:	include/uapi/linux/thermal.h
+F:	tools/lib/thermal/
 F:	tools/thermal/
 
 THERMAL DRIVER FOR AMLOGIC SOCS
diff --git a/tools/Makefile b/tools/Makefile
index db2f7b8ebed5..c253cbd27c06 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -31,6 +31,7 @@ help:
 	@echo '  bootconfig             - boot config tool'
 	@echo '  spi                    - spi tools'
 	@echo '  tmon                   - thermal monitoring and tuning tool'
+	@echo '  thermal                - thermal library'
 	@echo '  tracing                - misc tracing tools'
 	@echo '  turbostat              - Intel CPU idle stats and freq reporting tool'
 	@echo '  usb                    - USB testing tools'
@@ -85,6 +86,9 @@ perf: FORCE
 selftests: FORCE
 	$(call descend,testing/$@)
 
+thermal: FORCE
+	$(call descend,lib/$@)
+
 turbostat x86_energy_perf_policy intel-speed-select: FORCE
 	$(call descend,power/x86/$@)
 
@@ -101,7 +105,7 @@ all: acpi cgroup counter cpupower gpio hv firewire \
 		perf selftests bootconfig spi turbostat usb \
 		virtio vm bpf x86_energy_perf_policy \
 		tmon freefall iio objtool kvm_stat wmi \
-		pci debugging tracing
+		pci debugging tracing thermal
 
 acpi_install:
 	$(call descend,power/$(@:_install=),install)
@@ -115,6 +119,9 @@ cgroup_install counter_install firewire_install gpio_install hv_install iio_inst
 selftests_install:
 	$(call descend,testing/$(@:_install=),install)
 
+thermal_install:
+	$(call descend,lib/$(@:_install=),install)
+
 turbostat_install x86_energy_perf_policy_install intel-speed-select_install:
 	$(call descend,power/x86/$(@:_install=),install)
 
@@ -160,6 +167,9 @@ perf_clean:
 selftests_clean:
 	$(call descend,testing/$(@:_clean=),clean)
 
+thermal_clean:
+	$(call descend,lib/thermal,clean)
+
 turbostat_clean x86_energy_perf_policy_clean intel-speed-select_clean:
 	$(call descend,power/x86/$(@:_clean=),clean)
 
@@ -177,6 +187,6 @@ clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_cl
 		vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
 		freefall_clean build_clean libbpf_clean libsubcmd_clean \
 		gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \
-		intel-speed-select_clean tracing_clean
+		intel-speed-select_clean tracing_clean thermal_clean
 
 .PHONY: FORCE
diff --git a/tools/lib/thermal/.gitignore b/tools/lib/thermal/.gitignore
new file mode 100644
index 000000000000..5d2aeda80fea
--- /dev/null
+++ b/tools/lib/thermal/.gitignore
@@ -0,0 +1,2 @@
+libthermal.so*
+libthermal.pc
diff --git a/tools/lib/thermal/Build b/tools/lib/thermal/Build
new file mode 100644
index 000000000000..4a892d9e24f9
--- /dev/null
+++ b/tools/lib/thermal/Build
@@ -0,0 +1,5 @@
+libthermal-y += commands.o
+libthermal-y += events.o
+libthermal-y += thermal_nl.o
+libthermal-y += sampling.o
+libthermal-y += thermal.o
diff --git a/tools/lib/thermal/Makefile b/tools/lib/thermal/Makefile
new file mode 100644
index 000000000000..2d0d255fd0e1
--- /dev/null
+++ b/tools/lib/thermal/Makefile
@@ -0,0 +1,165 @@
+# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
+# Most of this file is copied from tools/lib/perf/Makefile
+
+LIBTHERMAL_VERSION = 0
+LIBTHERMAL_PATCHLEVEL = 0
+LIBTHERMAL_EXTRAVERSION = 1
+
+MAKEFLAGS += --no-print-directory
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+# $(info Determined 'srctree' to be $(srctree))
+endif
+
+INSTALL = install
+
+# Use DESTDIR for installing into a different root directory.
+# This is useful for building a package. The program will be
+# installed in this directory as if it was the root directory.
+# Then the build tool can move it later.
+DESTDIR ?=
+DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
+
+include $(srctree)/tools/scripts/Makefile.include
+include $(srctree)/tools/scripts/Makefile.arch
+
+ifeq ($(LP64), 1)
+  libdir_relative = lib64
+else
+  libdir_relative = lib
+endif
+
+prefix ?=
+libdir = $(prefix)/$(libdir_relative)
+
+# Shell quotes
+libdir_SQ = $(subst ','\'',$(libdir))
+libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
+
+ifeq ("$(origin V)", "command line")
+  VERBOSE = $(V)
+endif
+ifndef VERBOSE
+  VERBOSE = 0
+endif
+
+ifeq ($(VERBOSE),1)
+  Q =
+else
+  Q = @
+endif
+
+# Set compile option CFLAGS
+ifdef EXTRA_CFLAGS
+  CFLAGS := $(EXTRA_CFLAGS)
+else
+  CFLAGS := -g -Wall
+endif
+
+INCLUDES = \
+-I/usr/include/libnl3 \
+-I$(srctree)/tools/lib/thermal/include \
+-I$(srctree)/tools/lib/ \
+-I$(srctree)/tools/include \
+-I$(srctree)/tools/arch/$(SRCARCH)/include/ \
+-I$(srctree)/tools/arch/$(SRCARCH)/include/uapi \
+-I$(srctree)/tools/include/uapi
+
+# Append required CFLAGS
+override CFLAGS += $(EXTRA_WARNINGS)
+override CFLAGS += -Werror -Wall
+override CFLAGS += -fPIC
+override CFLAGS += $(INCLUDES)
+override CFLAGS += -fvisibility=hidden
+override CFGLAS += -Wl,-L.
+override CFGLAS += -Wl,-lthermal
+
+all:
+
+export srctree OUTPUT CC LD CFLAGS V
+export DESTDIR DESTDIR_SQ
+
+include $(srctree)/tools/build/Makefile.include
+
+VERSION_SCRIPT := libthermal.map
+
+PATCHLEVEL    = $(LIBTHERMAL_PATCHLEVEL)
+EXTRAVERSION  = $(LIBTHERMAL_EXTRAVERSION)
+VERSION       = $(LIBTHERMAL_VERSION).$(LIBTHERMAL_PATCHLEVEL).$(LIBTHERMAL_EXTRAVERSION)
+
+LIBTHERMAL_SO := $(OUTPUT)libthermal.so.$(VERSION)
+LIBTHERMAL_A  := $(OUTPUT)libthermal.a
+LIBTHERMAL_IN := $(OUTPUT)libthermal-in.o
+LIBTHERMAL_PC := $(OUTPUT)libthermal.pc
+LIBTHERMAL_ALL := $(LIBTHERMAL_A) $(OUTPUT)libthermal.so*
+
+THERMAL_UAPI := include/uapi/linux/thermal.h
+
+$(THERMAL_UAPI): FORCE
+	ln -sf $(srctree)/$@ $(srctree)/tools/$@
+
+$(LIBTHERMAL_IN): FORCE
+	$(Q)$(MAKE) $(build)=libthermal
+
+$(LIBTHERMAL_A): $(LIBTHERMAL_IN)
+	$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBTHERMAL_IN)
+
+$(LIBTHERMAL_SO): $(LIBTHERMAL_IN)
+	$(QUIET_LINK)$(CC) --shared -Wl,-soname,libthermal.so \
+                                    -Wl,--version-script=$(VERSION_SCRIPT) $^ -o $@
+	@ln -sf $(@F) $(OUTPUT)libthermal.so
+	@ln -sf $(@F) $(OUTPUT)libthermal.so.$(LIBTHERMAL_VERSION)
+
+
+libs: $(THERMAL_UAPI) $(LIBTHERMAL_A) $(LIBTHERMAL_SO) $(LIBTHERMAL_PC)
+
+all: fixdep
+	$(Q)$(MAKE) libs
+
+clean:
+	$(call QUIET_CLEAN, libthermal) $(RM) $(LIBTHERMAL_A) \
+                *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBTHERMAL_VERSION) .*.d .*.cmd LIBTHERMAL-CFLAGS $(LIBTHERMAL_PC)
+
+$(LIBTHERMAL_PC):
+	$(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \
+		-e "s|@LIBDIR@|$(libdir_SQ)|" \
+		-e "s|@VERSION@|$(VERSION)|" \
+		< libthermal.pc.template > $@
+
+define do_install_mkdir
+	if [ ! -d '$(DESTDIR_SQ)$1' ]; then             \
+		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \
+	fi
+endef
+
+define do_install
+	if [ ! -d '$(DESTDIR_SQ)$2' ]; then             \
+		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \
+	fi;                                             \
+	$(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2'
+endef
+
+install_lib: libs
+	$(call QUIET_INSTALL, $(LIBTHERMAL_ALL)) \
+		$(call do_install_mkdir,$(libdir_SQ)); \
+		cp -fpR $(LIBTHERMAL_ALL) $(DESTDIR)$(libdir_SQ)
+
+install_headers:
+	$(call QUIET_INSTALL, headers) \
+		$(call do_install,include/thermal.h,$(prefix)/include/thermal,644); \
+
+install_pkgconfig: $(LIBTHERMAL_PC)
+	$(call QUIET_INSTALL, $(LIBTHERMAL_PC)) \
+		$(call do_install,$(LIBTHERMAL_PC),$(libdir_SQ)/pkgconfig,644)
+
+install_doc:
+	$(Q)$(MAKE) -C Documentation install-man install-html install-examples
+
+install: install_lib install_headers install_pkgconfig
+
+FORCE:
+
+.PHONY: all install clean FORCE
diff --git a/tools/lib/thermal/commands.c b/tools/lib/thermal/commands.c
new file mode 100644
index 000000000000..539083780107
--- /dev/null
+++ b/tools/lib/thermal/commands.c
@@ -0,0 +1,349 @@
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#define _GNU_SOURCE
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <thermal.h>
+#include "thermal_nl.h"
+
+static struct nla_policy thermal_genl_policy[THERMAL_GENL_ATTR_MAX + 1] = {
+	/* Thermal zone */
+	[THERMAL_GENL_ATTR_TZ]                  = { .type = NLA_NESTED },
+	[THERMAL_GENL_ATTR_TZ_ID]               = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_TZ_TEMP]             = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_TZ_TRIP]             = { .type = NLA_NESTED },
+	[THERMAL_GENL_ATTR_TZ_TRIP_ID]          = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_TZ_TRIP_TEMP]        = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_TZ_TRIP_TYPE]        = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_TZ_TRIP_HYST]        = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_TZ_MODE]             = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_TZ_CDEV_WEIGHT]      = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_TZ_NAME]             = { .type = NLA_STRING },
+
+	/* Governor(s) */
+	[THERMAL_GENL_ATTR_TZ_GOV]              = { .type = NLA_NESTED },
+	[THERMAL_GENL_ATTR_TZ_GOV_NAME]         = { .type = NLA_STRING },
+
+	/* Cooling devices */
+	[THERMAL_GENL_ATTR_CDEV]                = { .type = NLA_NESTED },
+	[THERMAL_GENL_ATTR_CDEV_ID]             = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_CDEV_CUR_STATE]      = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_CDEV_MAX_STATE]      = { .type = NLA_U32 },
+	[THERMAL_GENL_ATTR_CDEV_NAME]           = { .type = NLA_STRING },
+};
+
+static int parse_tz_get(struct genl_info *info, struct thermal_zone **tz)
+{
+	struct nlattr *attr;
+	struct thermal_zone *__tz = NULL;
+	size_t size = 0;
+	int rem;
+
+	nla_for_each_nested(attr, info->attrs[THERMAL_GENL_ATTR_TZ], rem) {
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_TZ_ID) {
+
+			size++;
+
+			__tz = realloc(__tz, sizeof(*__tz) * (size + 2));
+			if (!__tz)
+				return THERMAL_ERROR;
+
+			__tz[size - 1].id = nla_get_u32(attr);
+		}
+
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_TZ_NAME)
+			nla_strlcpy(__tz[size - 1].name, attr,
+				    THERMAL_NAME_LENGTH);
+	}
+
+	/*
+	 * We end the array of thermal zones
+	 */
+	__tz[size].id = -1;
+
+	*tz = __tz;
+
+	return THERMAL_SUCCESS;
+}
+
+static int parse_cdev_get(struct genl_info *info, struct thermal_cdev **cdev)
+{
+	struct nlattr *attr;
+	struct thermal_cdev *__cdev = NULL;
+	size_t size = 0;
+	int rem;
+
+	nla_for_each_nested(attr, info->attrs[THERMAL_GENL_ATTR_CDEV], rem) {
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_CDEV_ID) {
+
+			size++;
+
+			__cdev = realloc(__cdev, sizeof(*__cdev) * (size + 2));
+			if (!__cdev)
+				return THERMAL_ERROR;
+
+			__cdev[size - 1].id = nla_get_u32(attr);
+		}
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_CDEV_NAME) {
+			nla_strlcpy(__cdev[size - 1].name, attr,
+				    THERMAL_NAME_LENGTH);
+		}
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_CDEV_CUR_STATE)
+			__cdev[size - 1].cur_state = nla_get_u32(attr);
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_CDEV_MAX_STATE)
+			__cdev[size - 1].max_state = nla_get_u32(attr);
+	}
+
+	__cdev[size].id = -1;
+
+	*cdev = __cdev;
+
+	return THERMAL_SUCCESS;
+}
+
+static int parse_tz_get_trip(struct genl_info *info, struct thermal_zone *tz)
+{
+	struct nlattr *attr;
+	struct thermal_trip *__tt = NULL;
+	size_t size = 0;
+	int rem;
+
+	nla_for_each_nested(attr, info->attrs[THERMAL_GENL_ATTR_TZ_TRIP], rem) {
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_TZ_TRIP_ID) {
+
+			size++;
+
+			__tt = realloc(__tt, sizeof(*__tt) * (size + 2));
+			if (!__tt)
+				return THERMAL_ERROR;
+
+			__tt[size - 1].id = nla_get_u32(attr);
+		}
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_TZ_TRIP_TYPE)
+			__tt[size - 1].type = nla_get_u32(attr);
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_TZ_TRIP_TEMP)
+			__tt[size - 1].temp = nla_get_u32(attr);
+
+		if (nla_type(attr) == THERMAL_GENL_ATTR_TZ_TRIP_HYST)
+			__tt[size - 1].hyst = nla_get_u32(attr);
+	}
+
+	__tt[size].id = -1;
+
+	tz->trip = __tt;
+
+	return THERMAL_SUCCESS;
+}
+
+static int parse_tz_get_temp(struct genl_info *info, struct thermal_zone *tz)
+{
+	int id = -1;
+
+	if (info->attrs[THERMAL_GENL_ATTR_TZ_ID])
+		id = nla_get_u32(info->attrs[THERMAL_GENL_ATTR_TZ_ID]);
+
+	if (tz->id != id)
+		return THERMAL_ERROR;
+
+	if (info->attrs[THERMAL_GENL_ATTR_TZ_TEMP])
+		tz->temp = nla_get_u32(info->attrs[THERMAL_GENL_ATTR_TZ_TEMP]);
+
+	return THERMAL_SUCCESS;
+}
+
+static int parse_tz_get_gov(struct genl_info *info, struct thermal_zone *tz)
+{
+	int id = -1;
+
+	if (info->attrs[THERMAL_GENL_ATTR_TZ_ID])
+		id = nla_get_u32(info->attrs[THERMAL_GENL_ATTR_TZ_ID]);
+
+	if (tz->id != id)
+		return THERMAL_ERROR;
+
+	if (info->attrs[THERMAL_GENL_ATTR_TZ_GOV_NAME]) {
+		nla_strlcpy(tz->governor,
+			    info->attrs[THERMAL_GENL_ATTR_TZ_GOV_NAME],
+			    THERMAL_NAME_LENGTH);
+	}
+
+	return THERMAL_SUCCESS;
+}
+
+static int handle_netlink(struct nl_cache_ops *unused,
+			  struct genl_cmd *cmd,
+			  struct genl_info *info, void *arg)
+{
+	int ret;
+
+	switch (cmd->c_id) {
+
+	case THERMAL_GENL_CMD_TZ_GET_ID:
+		ret = parse_tz_get(info, arg);
+		break;
+
+	case THERMAL_GENL_CMD_CDEV_GET:
+		ret = parse_cdev_get(info, arg);
+		break;
+
+	case THERMAL_GENL_CMD_TZ_GET_TEMP:
+		ret = parse_tz_get_temp(info, arg);
+		break;
+
+	case THERMAL_GENL_CMD_TZ_GET_TRIP:
+		ret = parse_tz_get_trip(info, arg);
+		break;
+
+	case THERMAL_GENL_CMD_TZ_GET_GOV:
+		ret = parse_tz_get_gov(info, arg);
+		break;
+
+	default:
+		return THERMAL_ERROR;
+	};
+
+	return ret;
+}
+
+static struct genl_cmd thermal_cmds[] = {
+	{
+		.c_id		= THERMAL_GENL_CMD_TZ_GET_ID,
+		.c_name		= (char *)"List thermal zones",
+		.c_msg_parser	= handle_netlink,
+		.c_maxattr	= THERMAL_GENL_ATTR_MAX,
+		.c_attr_policy	= thermal_genl_policy,
+	},
+	{
+		.c_id		= THERMAL_GENL_CMD_TZ_GET_GOV,
+		.c_name		= (char *)"Get governor",
+		.c_msg_parser	= handle_netlink,
+		.c_maxattr	= THERMAL_GENL_ATTR_MAX,
+		.c_attr_policy	= thermal_genl_policy,
+	},
+	{
+		.c_id		= THERMAL_GENL_CMD_TZ_GET_TEMP,
+		.c_name		= (char *)"Get thermal zone temperature",
+		.c_msg_parser	= handle_netlink,
+		.c_maxattr	= THERMAL_GENL_ATTR_MAX,
+		.c_attr_policy	= thermal_genl_policy,
+	},
+	{
+		.c_id		= THERMAL_GENL_CMD_TZ_GET_TRIP,
+		.c_name		= (char *)"Get thermal zone trip points",
+		.c_msg_parser	= handle_netlink,
+		.c_maxattr	= THERMAL_GENL_ATTR_MAX,
+		.c_attr_policy	= thermal_genl_policy,
+	},
+	{
+		.c_id		= THERMAL_GENL_CMD_CDEV_GET,
+		.c_name		= (char *)"Get cooling devices",
+		.c_msg_parser	= handle_netlink,
+		.c_maxattr	= THERMAL_GENL_ATTR_MAX,
+		.c_attr_policy	= thermal_genl_policy,
+	},
+};
+
+static struct genl_ops thermal_cmd_ops = {
+	.o_name		= (char *)"thermal",
+	.o_cmds		= thermal_cmds,
+	.o_ncmds	= ARRAY_SIZE(thermal_cmds),
+};
+
+static thermal_error_t thermal_genl_auto(struct thermal_handler *th, int id, int cmd,
+					 int flags, void *arg)
+{
+	struct nl_msg *msg;
+	void *hdr;
+
+	msg = nlmsg_alloc();
+	if (!msg)
+		return THERMAL_ERROR;
+
+	hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, thermal_cmd_ops.o_id,
+			  0, flags, cmd, THERMAL_GENL_VERSION);
+	if (!hdr)
+		return THERMAL_ERROR;
+
+	if (id >= 0 && nla_put_u32(msg, THERMAL_GENL_ATTR_TZ_ID, id))
+		return THERMAL_ERROR;
+
+	if (nl_send_msg(th->sk_cmd, th->cb_cmd, msg, genl_handle_msg, arg))
+		return THERMAL_ERROR;
+
+	nlmsg_free(msg);
+
+	return THERMAL_SUCCESS;
+}
+
+thermal_error_t thermal_cmd_get_tz(struct thermal_handler *th, struct thermal_zone **tz)
+{
+	return thermal_genl_auto(th, -1, THERMAL_GENL_CMD_TZ_GET_ID,
+				 NLM_F_DUMP | NLM_F_ACK, tz);
+}
+
+thermal_error_t thermal_cmd_get_cdev(struct thermal_handler *th, struct thermal_cdev **tc)
+{
+	return thermal_genl_auto(th, -1, THERMAL_GENL_CMD_CDEV_GET,
+				 NLM_F_DUMP | NLM_F_ACK, tc);
+}
+
+thermal_error_t thermal_cmd_get_trip(struct thermal_handler *th, struct thermal_zone *tz)
+{
+	return thermal_genl_auto(th, tz->id, THERMAL_GENL_CMD_TZ_GET_TRIP,
+				 0, tz);
+}
+
+thermal_error_t thermal_cmd_get_governor(struct thermal_handler *th, struct thermal_zone *tz)
+{
+	return thermal_genl_auto(th, tz->id, THERMAL_GENL_CMD_TZ_GET_GOV, 0, tz);
+}
+
+thermal_error_t thermal_cmd_get_temp(struct thermal_handler *th, struct thermal_zone *tz)
+{
+	return thermal_genl_auto(th, tz->id, THERMAL_GENL_CMD_TZ_GET_TEMP, 0, tz);
+}
+
+thermal_error_t thermal_cmd_exit(struct thermal_handler *th)
+{
+	if (genl_unregister_family(&thermal_cmd_ops))
+		return THERMAL_ERROR;
+
+	nl_thermal_disconnect(th->sk_cmd, th->cb_cmd);
+
+	return THERMAL_SUCCESS;
+}
+
+thermal_error_t thermal_cmd_init(struct thermal_handler *th)
+{
+	int ret;
+	int family;
+
+	if (nl_thermal_connect(&th->sk_cmd, &th->cb_cmd))
+		return THERMAL_ERROR;
+
+	ret = genl_register_family(&thermal_cmd_ops);
+	if (ret)
+		return THERMAL_ERROR;
+
+	ret = genl_ops_resolve(th->sk_cmd, &thermal_cmd_ops);
+	if (ret)
+		return THERMAL_ERROR;
+
+	family = genl_ctrl_resolve(th->sk_cmd, "nlctrl");
+	if (family != GENL_ID_CTRL)
+		return THERMAL_ERROR;
+
+	return THERMAL_SUCCESS;
+}
diff --git a/tools/lib/thermal/events.c b/tools/lib/thermal/events.c
new file mode 100644
index 000000000000..a7a55d1a0c4c
--- /dev/null
+++ b/tools/lib/thermal/events.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#include <linux/netlink.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+#include <thermal.h>
+#include "thermal_nl.h"
+
+/*
+ * Optimization: fill this array to tell which event we do want to pay
+ * attention to. That happens at init time with the ops
+ * structure. Each ops will enable the event and the general handler
+ * will be able to discard the event if there is not ops associated
+ * with it.
+ */
+static int enabled_ops[__THERMAL_GENL_EVENT_MAX];
+
+static int handle_thermal_event(struct nl_msg *n, void *arg)
+{
+	struct nlmsghdr *nlh = nlmsg_hdr(n);
+	struct genlmsghdr *genlhdr = genlmsg_hdr(nlh);
+	struct nlattr *attrs[THERMAL_GENL_ATTR_MAX + 1];
+	struct thermal_handler_param *thp = arg;
+	struct thermal_events_ops *ops = &thp->th->ops->events;
+
+	genlmsg_parse(nlh, 0, attrs, THERMAL_GENL_ATTR_MAX, NULL);
+
+	arg = thp->arg;
+
+	/*
+	 * This is an event we don't care of, bail out.
+	 */
+	if (!enabled_ops[genlhdr->cmd])
+		return THERMAL_SUCCESS;
+
+	switch (genlhdr->cmd) {
+
+	case THERMAL_GENL_EVENT_TZ_CREATE:
+		return ops->tz_create(nla_get_string(attrs[THERMAL_GENL_ATTR_TZ_NAME]),
+				      nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]), arg);
+
+	case THERMAL_GENL_EVENT_TZ_DELETE:
+		return ops->tz_delete(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]), arg);
+
+	case THERMAL_GENL_EVENT_TZ_ENABLE:
+		return ops->tz_enable(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]), arg);
+
+	case THERMAL_GENL_EVENT_TZ_DISABLE:
+		return ops->tz_disable(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]), arg);
+
+	case THERMAL_GENL_EVENT_TZ_TRIP_CHANGE:
+		return ops->trip_change(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
+					nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]),
+					nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE]),
+					nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP]),
+					nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST]), arg);
+
+	case THERMAL_GENL_EVENT_TZ_TRIP_ADD:
+		return ops->trip_add(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
+				     nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]),
+				     nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TYPE]),
+				     nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_TEMP]),
+				     nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_HYST]), arg);
+
+	case THERMAL_GENL_EVENT_TZ_TRIP_DELETE:
+		return ops->trip_delete(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
+					nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]), arg);
+
+	case THERMAL_GENL_EVENT_TZ_TRIP_UP:
+		return ops->trip_high(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
+				      nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]),
+				      nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]), arg);
+
+	case THERMAL_GENL_EVENT_TZ_TRIP_DOWN:
+		return ops->trip_low(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
+				     nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TRIP_ID]),
+				     nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]), arg);
+
+	case THERMAL_GENL_EVENT_CDEV_ADD:
+		return ops->cdev_add(nla_get_string(attrs[THERMAL_GENL_ATTR_CDEV_NAME]),
+				     nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]),
+				     nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_MAX_STATE]), arg);
+
+	case THERMAL_GENL_EVENT_CDEV_DELETE:
+		return ops->cdev_delete(nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]), arg);
+
+	case THERMAL_GENL_EVENT_CDEV_STATE_UPDATE:
+		return ops->cdev_update(nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_ID]),
+					nla_get_u32(attrs[THERMAL_GENL_ATTR_CDEV_CUR_STATE]), arg);
+
+	case THERMAL_GENL_EVENT_TZ_GOV_CHANGE:
+		return ops->gov_change(nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
+				       nla_get_string(attrs[THERMAL_GENL_ATTR_GOV_NAME]), arg);
+	default:
+		return -1;
+	}
+}
+
+static void thermal_events_ops_init(struct thermal_events_ops *ops)
+{
+	enabled_ops[THERMAL_GENL_EVENT_TZ_CREATE]	= !!ops->tz_create;
+	enabled_ops[THERMAL_GENL_EVENT_TZ_DELETE]	= !!ops->tz_delete;
+	enabled_ops[THERMAL_GENL_EVENT_TZ_DISABLE]	= !!ops->tz_disable;
+	enabled_ops[THERMAL_GENL_EVENT_TZ_ENABLE]	= !!ops->tz_enable;
+	enabled_ops[THERMAL_GENL_EVENT_TZ_TRIP_UP]	= !!ops->trip_high;
+	enabled_ops[THERMAL_GENL_EVENT_TZ_TRIP_DOWN]	= !!ops->trip_low;
+	enabled_ops[THERMAL_GENL_EVENT_TZ_TRIP_CHANGE]	= !!ops->trip_change;
+	enabled_ops[THERMAL_GENL_EVENT_TZ_TRIP_ADD]	= !!ops->trip_add;
+	enabled_ops[THERMAL_GENL_EVENT_TZ_TRIP_DELETE]	= !!ops->trip_delete;
+	enabled_ops[THERMAL_GENL_EVENT_CDEV_ADD]	= !!ops->cdev_add;
+	enabled_ops[THERMAL_GENL_EVENT_CDEV_DELETE]	= !!ops->cdev_delete;
+	enabled_ops[THERMAL_GENL_EVENT_CDEV_STATE_UPDATE] = !!ops->cdev_update;
+	enabled_ops[THERMAL_GENL_EVENT_TZ_GOV_CHANGE]	= !!ops->gov_change;
+}
+
+thermal_error_t thermal_events_handle(struct thermal_handler *th, void *arg)
+{
+	struct thermal_handler_param thp = { .th = th, .arg = arg };
+
+	if (!th)
+		return THERMAL_ERROR;
+
+	if (nl_cb_set(th->cb_event, NL_CB_VALID, NL_CB_CUSTOM,
+		      handle_thermal_event, &thp))
+		return THERMAL_ERROR;
+
+	return nl_recvmsgs(th->sk_event, th->cb_event);
+}
+
+int thermal_events_fd(struct thermal_handler *th)
+{
+	if (!th)
+		return -1;
+
+	return nl_socket_get_fd(th->sk_event);
+}
+
+thermal_error_t thermal_events_exit(struct thermal_handler *th)
+{
+	if (nl_unsubscribe_thermal(th->sk_event, th->cb_event,
+				   THERMAL_GENL_EVENT_GROUP_NAME))
+		return THERMAL_ERROR;
+
+	nl_thermal_disconnect(th->sk_event, th->cb_event);
+
+	return THERMAL_SUCCESS;
+}
+
+thermal_error_t thermal_events_init(struct thermal_handler *th)
+{
+	thermal_events_ops_init(&th->ops->events);
+
+	if (nl_thermal_connect(&th->sk_event, &th->cb_event))
+		return THERMAL_ERROR;
+
+	if (nl_subscribe_thermal(th->sk_event, th->cb_event,
+				 THERMAL_GENL_EVENT_GROUP_NAME))
+		return THERMAL_ERROR;
+
+	return THERMAL_SUCCESS;
+}
diff --git a/tools/lib/thermal/include/thermal.h b/tools/lib/thermal/include/thermal.h
new file mode 100644
index 000000000000..1abc560602cf
--- /dev/null
+++ b/tools/lib/thermal/include/thermal.h
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/* Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> */
+#ifndef __LIBTHERMAL_H
+#define __LIBTHERMAL_H
+
+#include <linux/thermal.h>
+
+#ifndef LIBTHERMAL_API
+#define LIBTHERMAL_API __attribute__((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct thermal_sampling_ops {
+	int (*tz_temp)(int tz_id, int temp, void *arg);
+};
+
+struct thermal_events_ops {
+	int (*tz_create)(const char *name, int tz_id, void *arg);
+	int (*tz_delete)(int tz_id, void *arg);
+	int (*tz_enable)(int tz_id, void *arg);
+	int (*tz_disable)(int tz_id, void *arg);
+	int (*trip_high)(int tz_id, int trip_id, int temp, void *arg);
+	int (*trip_low)(int tz_id, int trip_id, int temp, void *arg);
+	int (*trip_add)(int tz_id, int trip_id, int type, int temp, int hyst, void *arg);
+	int (*trip_change)(int tz_id, int trip_id, int type, int temp, int hyst, void *arg);
+	int (*trip_delete)(int tz_id, int trip_id, void *arg);
+	int (*cdev_add)(const char *name, int cdev_id, int max_state, void *arg);
+	int (*cdev_delete)(int cdev_id, void *arg);
+	int (*cdev_update)(int cdev_id, int cur_state, void *arg);
+	int (*gov_change)(int tz_id, const char *gov_name, void *arg);
+};
+
+struct thermal_ops {
+	struct thermal_sampling_ops sampling;
+	struct thermal_events_ops events;
+};
+
+struct thermal_trip {
+	int id;
+	int type;
+	int temp;
+	int hyst;
+};
+
+struct thermal_zone {
+	int id;
+	int temp;
+	char name[THERMAL_NAME_LENGTH];
+	char governor[THERMAL_NAME_LENGTH];
+	struct thermal_trip *trip;
+};
+
+struct thermal_cdev {
+	int id;
+	char name[THERMAL_NAME_LENGTH];
+	int max_state;
+	int min_state;
+	int cur_state;
+};
+
+typedef enum {
+	THERMAL_ERROR = -1,
+	THERMAL_SUCCESS = 0,
+} thermal_error_t;
+
+struct thermal_handler;
+
+typedef int (*cb_tz_t)(struct thermal_zone *, void *);
+
+typedef int (*cb_tt_t)(struct thermal_trip *, void *);
+
+typedef int (*cb_tc_t)(struct thermal_cdev *, void *);
+
+LIBTHERMAL_API int for_each_thermal_zone(struct thermal_zone *tz, cb_tz_t cb, void *arg);
+
+LIBTHERMAL_API int for_each_thermal_trip(struct thermal_trip *tt, cb_tt_t cb, void *arg);
+
+LIBTHERMAL_API int for_each_thermal_cdev(struct thermal_cdev *cdev, cb_tc_t cb, void *arg);
+
+LIBTHERMAL_API struct thermal_zone *thermal_zone_find_by_name(struct thermal_zone *tz,
+							      const char *name);
+
+LIBTHERMAL_API struct thermal_zone *thermal_zone_find_by_id(struct thermal_zone *tz, int id);
+
+LIBTHERMAL_API struct thermal_zone *thermal_zone_discover(struct thermal_handler *th);
+
+LIBTHERMAL_API struct thermal_handler *thermal_init(struct thermal_ops *ops);
+
+LIBTHERMAL_API void thermal_exit(struct thermal_handler *th);
+
+/*
+ * Netlink thermal events
+ */
+LIBTHERMAL_API thermal_error_t thermal_events_exit(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_events_init(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_events_handle(struct thermal_handler *th, void *arg);
+
+LIBTHERMAL_API int thermal_events_fd(struct thermal_handler *th);
+
+/*
+ * Netlink thermal commands
+ */
+LIBTHERMAL_API thermal_error_t thermal_cmd_exit(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_init(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_tz(struct thermal_handler *th,
+						  struct thermal_zone **tz);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_cdev(struct thermal_handler *th,
+						    struct thermal_cdev **tc);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_trip(struct thermal_handler *th,
+						    struct thermal_zone *tz);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_governor(struct thermal_handler *th,
+							struct thermal_zone *tz);
+
+LIBTHERMAL_API thermal_error_t thermal_cmd_get_temp(struct thermal_handler *th,
+						    struct thermal_zone *tz);
+
+/*
+ * Netlink thermal samples
+ */
+LIBTHERMAL_API thermal_error_t thermal_sampling_exit(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_sampling_init(struct thermal_handler *th);
+
+LIBTHERMAL_API thermal_error_t thermal_sampling_handle(struct thermal_handler *th, void *arg);
+
+LIBTHERMAL_API int thermal_sampling_fd(struct thermal_handler *th);
+
+#endif /* __LIBTHERMAL_H */
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/tools/lib/thermal/libthermal.map b/tools/lib/thermal/libthermal.map
new file mode 100644
index 000000000000..d5e77738c7a4
--- /dev/null
+++ b/tools/lib/thermal/libthermal.map
@@ -0,0 +1,25 @@
+LIBTHERMAL_0.0.1 {
+	global:
+		thermal_init;
+		for_each_thermal_zone;
+		for_each_thermal_trip;
+		for_each_thermal_cdev;
+		thermal_zone_find_by_name;
+		thermal_zone_find_by_id;
+		thermal_zone_discover;
+		thermal_init;
+		thermal_events_init;
+		thermal_events_handle;
+		thermal_events_fd;
+		thermal_cmd_init;
+		thermal_cmd_get_tz;
+		thermal_cmd_get_cdev;
+		thermal_cmd_get_trip;
+		thermal_cmd_get_governor;
+		thermal_cmd_get_temp;
+		thermal_sampling_init;
+		thermal_sampling_handle;
+		thermal_sampling_fd;
+local:
+		*;
+};
diff --git a/tools/lib/thermal/libthermal.pc.template b/tools/lib/thermal/libthermal.pc.template
new file mode 100644
index 000000000000..6f3769731b59
--- /dev/null
+++ b/tools/lib/thermal/libthermal.pc.template
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
+
+prefix=@PREFIX@
+libdir=@LIBDIR@
+includedir=${prefix}/include
+
+Name: libthermal
+Description: thermal library
+Requires: libnl-3.0 libnl-genl-3.0
+Version: @VERSION@
+Libs: -L${libdir} -lnl-genl-3 -lnl-3
+Cflags: -I${includedir} -I{include}/libnl3
diff --git a/tools/lib/thermal/sampling.c b/tools/lib/thermal/sampling.c
new file mode 100644
index 000000000000..ee818f4e9654
--- /dev/null
+++ b/tools/lib/thermal/sampling.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <thermal.h>
+#include "thermal_nl.h"
+
+static int handle_thermal_sample(struct nl_msg *n, void *arg)
+{
+	struct nlmsghdr *nlh = nlmsg_hdr(n);
+	struct genlmsghdr *genlhdr = genlmsg_hdr(nlh);
+	struct nlattr *attrs[THERMAL_GENL_ATTR_MAX + 1];
+	struct thermal_handler_param *thp = arg;
+	struct thermal_handler *th = thp->th;
+
+	genlmsg_parse(nlh, 0, attrs, THERMAL_GENL_ATTR_MAX, NULL);
+
+	switch (genlhdr->cmd) {
+
+	case THERMAL_GENL_SAMPLING_TEMP:
+		return th->ops->sampling.tz_temp(
+			nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_ID]),
+			nla_get_u32(attrs[THERMAL_GENL_ATTR_TZ_TEMP]), arg);
+	default:
+		return THERMAL_ERROR;
+	}
+}
+
+thermal_error_t thermal_sampling_handle(struct thermal_handler *th, void *arg)
+{
+	struct thermal_handler_param thp = { .th = th, .arg = arg };
+
+	if (!th)
+		return THERMAL_ERROR;
+
+	if (nl_cb_set(th->cb_sampling, NL_CB_VALID, NL_CB_CUSTOM,
+		      handle_thermal_sample, &thp))
+		return THERMAL_ERROR;
+
+	return nl_recvmsgs(th->sk_sampling, th->cb_sampling);
+}
+
+int thermal_sampling_fd(struct thermal_handler *th)
+{
+	if (!th)
+		return -1;
+
+	return nl_socket_get_fd(th->sk_sampling);
+}
+
+thermal_error_t thermal_sampling_exit(struct thermal_handler *th)
+{
+	if (nl_unsubscribe_thermal(th->sk_sampling, th->cb_sampling,
+				   THERMAL_GENL_EVENT_GROUP_NAME))
+		return THERMAL_ERROR;
+
+	nl_thermal_disconnect(th->sk_sampling, th->cb_sampling);
+
+	return THERMAL_SUCCESS;
+}
+
+thermal_error_t thermal_sampling_init(struct thermal_handler *th)
+{
+	if (nl_thermal_connect(&th->sk_sampling, &th->cb_sampling))
+		return THERMAL_ERROR;
+
+	if (nl_subscribe_thermal(th->sk_sampling, th->cb_sampling,
+				 THERMAL_GENL_SAMPLING_GROUP_NAME))
+		return THERMAL_ERROR;
+
+	return THERMAL_SUCCESS;
+}
diff --git a/tools/lib/thermal/thermal.c b/tools/lib/thermal/thermal.c
new file mode 100644
index 000000000000..a80b967ce334
--- /dev/null
+++ b/tools/lib/thermal/thermal.c
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#include <stdio.h>
+#include <thermal.h>
+
+#include "thermal_nl.h"
+
+int for_each_thermal_cdev(struct thermal_cdev *cdev, cb_tc_t cb, void *arg)
+{
+	int i, ret = 0;
+
+	for (i = 0; cdev[i].id != -1; i++)
+		ret |= cb(&cdev[i], arg);
+
+	return ret;
+}
+
+int for_each_thermal_trip(struct thermal_trip *tt, cb_tt_t cb, void *arg)
+{
+	int i, ret = 0;
+
+	for (i = 0; tt[i].id != -1; i++)
+		ret |= cb(&tt[i], arg);
+
+	return ret;
+}
+
+int for_each_thermal_zone(struct thermal_zone *tz, cb_tz_t cb, void *arg)
+{
+	int i, ret = 0;
+
+	for (i = 0; tz[i].id != -1; i++)
+		ret |= cb(&tz[i], arg);
+
+	return ret;
+}
+
+struct thermal_zone *thermal_zone_find_by_name(struct thermal_zone *tz,
+					       const char *name)
+{
+	int i;
+
+	if (!name)
+		return NULL;
+
+	for (i = 0; tz[i].id != -1; i++) {
+		if (!strcmp(tz[i].name, name))
+			return &tz[i];
+	}
+
+	return NULL;
+}
+
+struct thermal_zone *thermal_zone_find_by_id(struct thermal_zone *tz, int id)
+{
+	int i;
+
+	if (id < 0)
+		return NULL;
+
+	for (i = 0; tz[i].id != -1; i++) {
+		if (tz[i].id == id)
+			return &tz[i];
+	}
+
+	return NULL;
+}
+
+static int __thermal_zone_discover(struct thermal_zone *tz, void *th)
+{
+	if (thermal_cmd_get_trip(th, tz) < 0)
+		return -1;
+
+	if (thermal_cmd_get_governor(th, tz))
+		return -1;
+
+	return 0;
+}
+
+struct thermal_zone *thermal_zone_discover(struct thermal_handler *th)
+{
+	struct thermal_zone *tz;
+
+	if (thermal_cmd_get_tz(th, &tz) < 0)
+		return NULL;
+
+	if (for_each_thermal_zone(tz, __thermal_zone_discover, th))
+		return NULL;
+
+	return tz;
+}
+
+void thermal_exit(struct thermal_handler *th)
+{
+	thermal_cmd_exit(th);
+	thermal_events_exit(th);
+	thermal_sampling_exit(th);
+
+	free(th);
+}
+
+struct thermal_handler *thermal_init(struct thermal_ops *ops)
+{
+	struct thermal_handler *th;
+
+	th = malloc(sizeof(*th));
+	if (!th)
+		return NULL;
+	th->ops = ops;
+
+	if (thermal_events_init(th))
+		goto out_free;
+
+	if (thermal_sampling_init(th))
+		goto out_free;
+
+	if (thermal_cmd_init(th))
+		goto out_free;
+
+	return th;
+
+out_free:
+	free(th);
+
+	return NULL;
+}
diff --git a/tools/lib/thermal/thermal_nl.c b/tools/lib/thermal/thermal_nl.c
new file mode 100644
index 000000000000..b05cf9569858
--- /dev/null
+++ b/tools/lib/thermal/thermal_nl.c
@@ -0,0 +1,215 @@
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <thermal.h>
+#include "thermal_nl.h"
+
+struct handler_args {
+	const char *group;
+	int id;
+};
+
+static __thread int err;
+static __thread int done;
+
+static int nl_seq_check_handler(struct nl_msg *msg, void *arg)
+{
+	return NL_OK;
+}
+
+static int nl_error_handler(struct sockaddr_nl *nla, struct nlmsgerr *nl_err,
+			    void *arg)
+{
+	int *ret = arg;
+
+	if (ret)
+		*ret = nl_err->error;
+
+	return NL_STOP;
+}
+
+static int nl_finish_handler(struct nl_msg *msg, void *arg)
+{
+	int *ret = arg;
+
+	if (ret)
+		*ret = 1;
+
+	return NL_OK;
+}
+
+static int nl_ack_handler(struct nl_msg *msg, void *arg)
+{
+	int *ret = arg;
+
+	if (ret)
+		*ret = 1;
+
+	return NL_OK;
+}
+
+int nl_send_msg(struct nl_sock *sock, struct nl_cb *cb, struct nl_msg *msg,
+		int (*rx_handler)(struct nl_msg *, void *), void *data)
+{
+	if (!rx_handler)
+		return THERMAL_ERROR;
+
+	err = nl_send_auto_complete(sock, msg);
+	if (err < 0)
+		return err;
+
+	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, rx_handler, data);
+
+	err = done = 0;
+
+	while (err == 0 && done == 0)
+		nl_recvmsgs(sock, cb);
+
+	return err;
+}
+
+static int nl_family_handler(struct nl_msg *msg, void *arg)
+{
+	struct handler_args *grp = arg;
+	struct nlattr *tb[CTRL_ATTR_MAX + 1];
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	struct nlattr *mcgrp;
+	int rem_mcgrp;
+
+	nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+
+	if (!tb[CTRL_ATTR_MCAST_GROUPS])
+		return THERMAL_ERROR;
+
+	nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp) {
+
+		struct nlattr *tb_mcgrp[CTRL_ATTR_MCAST_GRP_MAX + 1];
+
+		nla_parse(tb_mcgrp, CTRL_ATTR_MCAST_GRP_MAX,
+			  nla_data(mcgrp), nla_len(mcgrp), NULL);
+
+		if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME] ||
+		    !tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID])
+			continue;
+
+		if (strncmp(nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]),
+			    grp->group,
+			    nla_len(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME])))
+			continue;
+
+		grp->id = nla_get_u32(tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]);
+
+		break;
+	}
+
+	return THERMAL_SUCCESS;
+}
+
+static int nl_get_multicast_id(struct nl_sock *sock, struct nl_cb *cb,
+			       const char *family, const char *group)
+{
+	struct nl_msg *msg;
+	int ret = 0, ctrlid;
+	struct handler_args grp = {
+		.group = group,
+		.id = -ENOENT,
+	};
+
+	msg = nlmsg_alloc();
+	if (!msg)
+		return THERMAL_ERROR;
+
+	ctrlid = genl_ctrl_resolve(sock, "nlctrl");
+
+	genlmsg_put(msg, 0, 0, ctrlid, 0, 0, CTRL_CMD_GETFAMILY, 0);
+
+	nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, family);
+
+	ret = nl_send_msg(sock, cb, msg, nl_family_handler, &grp);
+	if (ret)
+		goto nla_put_failure;
+
+	ret = grp.id;
+
+nla_put_failure:
+	nlmsg_free(msg);
+	return ret;
+}
+
+int nl_thermal_connect(struct nl_sock **nl_sock, struct nl_cb **nl_cb)
+{
+	struct nl_cb *cb;
+	struct nl_sock *sock;
+
+	cb = nl_cb_alloc(NL_CB_DEFAULT);
+	if (!cb)
+		return THERMAL_ERROR;
+
+	sock = nl_socket_alloc();
+	if (!sock)
+		goto out_cb_free;
+
+	if (genl_connect(sock))
+		goto out_socket_free;
+
+	if (nl_cb_err(cb, NL_CB_CUSTOM, nl_error_handler, &err) ||
+	    nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nl_finish_handler, &done) ||
+	    nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl_ack_handler, &done) ||
+	    nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, nl_seq_check_handler, &done))
+		return THERMAL_ERROR;
+
+	*nl_sock = sock;
+	*nl_cb = cb;
+
+	return THERMAL_SUCCESS;
+
+out_socket_free:
+	nl_socket_free(sock);
+out_cb_free:
+	nl_cb_put(cb);
+	return THERMAL_ERROR;
+}
+
+void nl_thermal_disconnect(struct nl_sock *nl_sock, struct nl_cb *nl_cb)
+{
+	nl_close(nl_sock);
+	nl_socket_free(nl_sock);
+	nl_cb_put(nl_cb);
+}
+
+int nl_unsubscribe_thermal(struct nl_sock *nl_sock, struct nl_cb *nl_cb,
+			   const char *group)
+{
+	int mcid;
+
+	mcid = nl_get_multicast_id(nl_sock, nl_cb, THERMAL_GENL_FAMILY_NAME,
+				   group);
+	if (mcid < 0)
+		return THERMAL_ERROR;
+
+	if (nl_socket_drop_membership(nl_sock, mcid))
+		return THERMAL_ERROR;
+
+	return THERMAL_SUCCESS;
+}
+
+int nl_subscribe_thermal(struct nl_sock *nl_sock, struct nl_cb *nl_cb,
+			 const char *group)
+{
+	int mcid;
+
+	mcid = nl_get_multicast_id(nl_sock, nl_cb, THERMAL_GENL_FAMILY_NAME,
+				   group);
+	if (mcid < 0)
+		return THERMAL_ERROR;
+
+	if (nl_socket_add_membership(nl_sock, mcid))
+		return THERMAL_ERROR;
+
+	return THERMAL_SUCCESS;
+}
diff --git a/tools/lib/thermal/thermal_nl.h b/tools/lib/thermal/thermal_nl.h
new file mode 100644
index 000000000000..ddf635642f07
--- /dev/null
+++ b/tools/lib/thermal/thermal_nl.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/* Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> */
+#ifndef __THERMAL_H
+#define __THERMAL_H
+
+#include <netlink/netlink.h>
+#include <netlink/genl/genl.h>
+#include <netlink/genl/mngt.h>
+#include <netlink/genl/ctrl.h>
+
+struct thermal_handler {
+	int done;
+	int error;
+	struct thermal_ops *ops;
+	struct nl_msg *msg;
+	struct nl_sock *sk_event;
+	struct nl_sock *sk_sampling;
+	struct nl_sock *sk_cmd;
+	struct nl_cb *cb_cmd;
+	struct nl_cb *cb_event;
+	struct nl_cb *cb_sampling;
+};
+
+struct thermal_handler_param {
+	struct thermal_handler *th;
+	void *arg;
+};
+
+/*
+ * Low level netlink
+ */
+extern int nl_subscribe_thermal(struct nl_sock *nl_sock, struct nl_cb *nl_cb,
+				const char *group);
+
+extern int nl_unsubscribe_thermal(struct nl_sock *nl_sock, struct nl_cb *nl_cb,
+				  const char *group);
+
+extern int nl_thermal_connect(struct nl_sock **nl_sock, struct nl_cb **nl_cb);
+
+extern void nl_thermal_disconnect(struct nl_sock *nl_sock, struct nl_cb *nl_cb);
+
+extern int nl_send_msg(struct nl_sock *sock, struct nl_cb *nl_cb, struct nl_msg *msg,
+		       int (*rx_handler)(struct nl_msg *, void *),
+		       void *data);
+
+#endif /* __THERMAL_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 2/4] tools/thermal: Add util library
  2022-03-30 10:04 [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
  2022-03-30 10:04 ` [PATCH v2 1/4] tools/lib/thermal: Add a thermal library Daniel Lezcano
@ 2022-03-30 10:04 ` Daniel Lezcano
  2022-03-30 10:04 ` [PATCH v2 3/4] tools/thermal: A temperature capture tool Daniel Lezcano
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 19+ messages in thread
From: Daniel Lezcano @ 2022-03-30 10:04 UTC (permalink / raw)
  To: daniel.lezcano, rafael
  Cc: srinivas.pandruvada, linux-kernel, linux-pm, Amit Kucheria, Zhang Rui

The next changes will provide a couple of tools using some common
functions provided by this library.

It provides basic wrappers for:

 - mainloop
 - logging
 - timestamp

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 tools/thermal/lib/Build                       |   3 +
 tools/thermal/lib/Makefile                    | 158 ++++++++++++++++++
 .../thermal/lib/libthermal_tools.pc.template  |  12 ++
 tools/thermal/lib/log.c                       |  77 +++++++++
 tools/thermal/lib/log.h                       |  31 ++++
 tools/thermal/lib/mainloop.c                  | 120 +++++++++++++
 tools/thermal/lib/mainloop.h                  |  15 ++
 tools/thermal/lib/thermal-tools.h             |  10 ++
 tools/thermal/lib/uptimeofday.c               |  40 +++++
 tools/thermal/lib/uptimeofday.h               |  12 ++
 10 files changed, 478 insertions(+)
 create mode 100644 tools/thermal/lib/Build
 create mode 100644 tools/thermal/lib/Makefile
 create mode 100644 tools/thermal/lib/libthermal_tools.pc.template
 create mode 100644 tools/thermal/lib/log.c
 create mode 100644 tools/thermal/lib/log.h
 create mode 100644 tools/thermal/lib/mainloop.c
 create mode 100644 tools/thermal/lib/mainloop.h
 create mode 100644 tools/thermal/lib/thermal-tools.h
 create mode 100644 tools/thermal/lib/uptimeofday.c
 create mode 100644 tools/thermal/lib/uptimeofday.h

diff --git a/tools/thermal/lib/Build b/tools/thermal/lib/Build
new file mode 100644
index 000000000000..06f22760a272
--- /dev/null
+++ b/tools/thermal/lib/Build
@@ -0,0 +1,3 @@
+libthermal_tools-y += mainloop.o
+libthermal_tools-y += log.o
+libthermal_tools-y += uptimeofday.o
diff --git a/tools/thermal/lib/Makefile b/tools/thermal/lib/Makefile
new file mode 100644
index 000000000000..82db451935c5
--- /dev/null
+++ b/tools/thermal/lib/Makefile
@@ -0,0 +1,158 @@
+# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
+# Most of this file is copied from tools/lib/perf/Makefile
+
+LIBTHERMAL_TOOLS_VERSION = 0
+LIBTHERMAL_TOOLS_PATCHLEVEL = 0
+LIBTHERMAL_TOOLS_EXTRAVERSION = 1
+
+MAKEFLAGS += --no-print-directory
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+# $(info Determined 'srctree' to be $(srctree))
+endif
+
+INSTALL = install
+
+# Use DESTDIR for installing into a different root directory.
+# This is useful for building a package. The program will be
+# installed in this directory as if it was the root directory.
+# Then the build tool can move it later.
+DESTDIR ?=
+DESTDIR_SQ = '$(subst ','\'',$(DESTDIR))'
+
+include $(srctree)/tools/scripts/Makefile.include
+include $(srctree)/tools/scripts/Makefile.arch
+
+ifeq ($(LP64), 1)
+  libdir_relative = lib64
+else
+  libdir_relative = lib
+endif
+
+prefix ?=
+libdir = $(prefix)/$(libdir_relative)
+
+# Shell quotes
+libdir_SQ = $(subst ','\'',$(libdir))
+libdir_relative_SQ = $(subst ','\'',$(libdir_relative))
+
+ifeq ("$(origin V)", "command line")
+  VERBOSE = $(V)
+endif
+ifndef VERBOSE
+  VERBOSE = 0
+endif
+
+ifeq ($(VERBOSE),1)
+  Q =
+else
+  Q = @
+endif
+
+# Set compile option CFLAGS
+ifdef EXTRA_CFLAGS
+  CFLAGS := $(EXTRA_CFLAGS)
+else
+  CFLAGS := -g -Wall
+endif
+
+INCLUDES = \
+-I/usr/include/libnl3 \
+-I$(srctree)/tools/lib/thermal/include \
+-I$(srctree)/tools/lib/ \
+-I$(srctree)/tools/include \
+-I$(srctree)/tools/arch/$(SRCARCH)/include/ \
+-I$(srctree)/tools/arch/$(SRCARCH)/include/uapi \
+-I$(srctree)/tools/include/uapi
+
+# Append required CFLAGS
+override CFLAGS += $(EXTRA_WARNINGS)
+override CFLAGS += -Werror -Wall
+override CFLAGS += -fPIC
+override CFLAGS += $(INCLUDES)
+override CFGLAS += -Wl,-L.
+override CFGLAS += -Wl,-lthermal
+
+all:
+
+export srctree OUTPUT CC LD CFLAGS V
+export DESTDIR DESTDIR_SQ
+
+include $(srctree)/tools/build/Makefile.include
+
+PATCHLEVEL    = $(LIBTHERMAL_TOOLS_PATCHLEVEL)
+EXTRAVERSION  = $(LIBTHERMAL_TOOLS_EXTRAVERSION)
+VERSION       = $(LIBTHERMAL_TOOLS_VERSION).$(LIBTHERMAL_TOOLS_PATCHLEVEL).$(LIBTHERMAL_TOOLS_EXTRAVERSION)
+
+LIBTHERMAL_TOOLS_SO := $(OUTPUT)libthermal_tools.so.$(VERSION)
+LIBTHERMAL_TOOLS_A  := $(OUTPUT)libthermal_tools.a
+LIBTHERMAL_TOOLS_IN := $(OUTPUT)libthermal_tools-in.o
+LIBTHERMAL_TOOLS_PC := $(OUTPUT)libthermal_tools.pc
+
+LIBTHERMAL_TOOLS_ALL := $(LIBTHERMAL_TOOLS_A) $(OUTPUT)libthermal_tools.so*
+
+$(LIBTHERMAL_TOOLS_IN): FORCE
+	$(Q)$(MAKE) $(build)=libthermal_tools
+
+$(LIBTHERMAL_TOOLS_A): $(LIBTHERMAL_TOOLS_IN)
+	$(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBTHERMAL_TOOLS_IN)
+
+$(LIBTHERMAL_TOOLS_SO): $(LIBTHERMAL_TOOLS_IN)
+	$(QUIET_LINK)$(CC) --shared -Wl,-soname,libthermal_tools.so $^ -o $@
+	@ln -sf $(@F) $(OUTPUT)libthermal_tools.so
+	@ln -sf $(@F) $(OUTPUT)libthermal_tools.so.$(LIBTHERMAL_TOOLS_VERSION)
+
+
+libs: $(LIBTHERMAL_TOOLS_A) $(LIBTHERMAL_TOOLS_SO) $(LIBTHERMAL_TOOLS_PC)
+
+all: fixdep
+	$(Q)$(MAKE) libs
+
+clean:
+	$(call QUIET_CLEAN, libthermal_tools) $(RM) $(LIBTHERMAL_TOOLS_A) \
+                *.o *~ *.a *.so *.so.$(VERSION) *.so.$(LIBTHERMAL_TOOLS_VERSION) .*.d .*.cmd LIBTHERMAL_TOOLS-CFLAGS $(LIBTHERMAL_TOOLS_PC)
+
+$(LIBTHERMAL_TOOLS_PC):
+	$(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \
+		-e "s|@LIBDIR@|$(libdir_SQ)|" \
+		-e "s|@VERSION@|$(VERSION)|" \
+		< libthermal_tools.pc.template > $@
+
+define do_install_mkdir
+	if [ ! -d '$(DESTDIR_SQ)$1' ]; then             \
+		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$1'; \
+	fi
+endef
+
+define do_install
+	if [ ! -d '$(DESTDIR_SQ)$2' ]; then             \
+		$(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \
+	fi;                                             \
+	$(INSTALL) $1 $(if $3,-m $3,) '$(DESTDIR_SQ)$2'
+endef
+
+install_lib: libs
+	$(call QUIET_INSTALL, $(LIBTHERMAL_TOOLS_ALL)) \
+		$(call do_install_mkdir,$(libdir_SQ)); \
+		cp -fpR $(LIBTHERMAL_TOOLS_ALL) $(DESTDIR)$(libdir_SQ)
+
+install_headers:
+	$(call QUIET_INSTALL, headers) \
+		$(call do_install,include/thermal.h,$(prefix)/include/thermal,644); \
+
+install_pkgconfig: $(LIBTHERMAL_TOOLS_PC)
+	$(call QUIET_INSTALL, $(LIBTHERMAL_TOOLS_PC)) \
+		$(call do_install,$(LIBTHERMAL_TOOLS_PC),$(libdir_SQ)/pkgconfig,644)
+
+install_doc:
+	$(Q)$(MAKE) -C Documentation install-man install-html install-examples
+
+#install: install_lib install_headers install_pkgconfig install_doc
+install: install_lib install_headers install_pkgconfig
+
+FORCE:
+
+.PHONY: all install clean FORCE
diff --git a/tools/thermal/lib/libthermal_tools.pc.template b/tools/thermal/lib/libthermal_tools.pc.template
new file mode 100644
index 000000000000..6f3769731b59
--- /dev/null
+++ b/tools/thermal/lib/libthermal_tools.pc.template
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
+
+prefix=@PREFIX@
+libdir=@LIBDIR@
+includedir=${prefix}/include
+
+Name: libthermal
+Description: thermal library
+Requires: libnl-3.0 libnl-genl-3.0
+Version: @VERSION@
+Libs: -L${libdir} -lnl-genl-3 -lnl-3
+Cflags: -I${includedir} -I{include}/libnl3
diff --git a/tools/thermal/lib/log.c b/tools/thermal/lib/log.c
new file mode 100644
index 000000000000..597d6e7f7858
--- /dev/null
+++ b/tools/thermal/lib/log.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include "log.h"
+
+static const char *__ident = "unknown";
+static int __options;
+
+static const char * const loglvl[] = {
+	[LOG_DEBUG]	= "DEBUG",
+	[LOG_INFO]	= "INFO",
+	[LOG_NOTICE]	= "NOTICE",
+	[LOG_WARNING]	= "WARN",
+	[LOG_ERR]	= "ERROR",
+	[LOG_CRIT]	= "CRITICAL",
+	[LOG_ALERT]	= "ALERT",
+	[LOG_EMERG]	= "EMERG",
+};
+
+int log_str2level(const char *lvl)
+{
+	int i;
+
+	for (i = 0; i < sizeof(loglvl) / sizeof(loglvl[LOG_DEBUG]); i++)
+		if (!strcmp(lvl, loglvl[i]))
+			return i;
+
+	return LOG_DEBUG;
+}
+
+extern void logit(int level, const char *format, ...)
+{
+	va_list args;
+
+	va_start(args, format);
+
+	if (__options & TO_SYSLOG)
+		vsyslog(level, format, args);
+
+	if (__options & TO_STDERR)
+		vfprintf(stderr, format, args);
+
+	if (__options & TO_STDOUT)
+		vfprintf(stdout, format, args);
+
+	va_end(args);
+}
+
+int log_init(int level, const char *ident, int options)
+{
+	if (!options)
+		return -1;
+
+	if (level > LOG_DEBUG)
+		return -1;
+
+	if (!ident)
+		return -1;
+
+	__ident = ident;
+	__options = options;
+
+	if (options & TO_SYSLOG) {
+		openlog(__ident, options | LOG_NDELAY, LOG_USER);
+		setlogmask(LOG_UPTO(level));
+	}
+
+	return 0;
+}
+
+void log_exit(void)
+{
+	closelog();
+}
diff --git a/tools/thermal/lib/log.h b/tools/thermal/lib/log.h
new file mode 100644
index 000000000000..be8ab5144938
--- /dev/null
+++ b/tools/thermal/lib/log.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/* Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> */
+#ifndef __THERMAL_TOOLS_LOG_H
+#define __THERMAL_TOOLS_LOG_H
+
+#include <syslog.h>
+
+#ifndef __maybe_unused
+#define __maybe_unused		__attribute__((__unused__))
+#endif
+
+#define TO_SYSLOG 0x1
+#define TO_STDOUT 0x2
+#define TO_STDERR 0x4
+
+extern void logit(int level, const char *format, ...);
+
+#define DEBUG(fmt, ...)		logit(LOG_DEBUG, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+#define INFO(fmt, ...)		logit(LOG_INFO, fmt, ##__VA_ARGS__)
+#define NOTICE(fmt, ...)	logit(LOG_NOTICE, fmt, ##__VA_ARGS__)
+#define WARN(fmt, ...)		logit(LOG_WARNING, fmt, ##__VA_ARGS__)
+#define ERROR(fmt, ...)		logit(LOG_ERR, fmt, ##__VA_ARGS__)
+#define CRITICAL(fmt, ...)	logit(LOG_CRIT, fmt, ##__VA_ARGS__)
+#define ALERT(fmt, ...)		logit(LOG_ALERT, fmt, ##__VA_ARGS__)
+#define EMERG(fmt, ...)		logit(LOG_EMERG, fmt, ##__VA_ARGS__)
+
+int log_init(int level, const char *ident, int options);
+int log_str2level(const char *lvl);
+void log_exit(void);
+
+#endif
diff --git a/tools/thermal/lib/mainloop.c b/tools/thermal/lib/mainloop.c
new file mode 100644
index 000000000000..94cbbcbd1c14
--- /dev/null
+++ b/tools/thermal/lib/mainloop.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/epoll.h>
+#include "mainloop.h"
+#include "log.h"
+
+static int epfd = -1;
+static unsigned short nrhandler;
+static sig_atomic_t exit_mainloop;
+
+struct mainloop_data {
+	mainloop_callback_t cb;
+	void *data;
+	int fd;
+};
+
+static struct mainloop_data **mds;
+
+#define MAX_EVENTS 10
+
+int mainloop(unsigned int timeout)
+{
+	int i, nfds;
+	struct epoll_event events[MAX_EVENTS];
+	struct mainloop_data *md;
+
+	if (epfd < 0)
+		return -1;
+
+	for (;;) {
+
+		nfds = epoll_wait(epfd, events, MAX_EVENTS, timeout);
+
+		if (exit_mainloop || !nfds)
+			return 0;
+
+		if (nfds < 0) {
+			if (errno == EINTR)
+				continue;
+			return -1;
+		}
+
+		for (i = 0; i < nfds; i++) {
+			md = events[i].data.ptr;
+
+			if (md->cb(md->fd, md->data) > 0)
+				return 0;
+		}
+	}
+}
+
+int mainloop_add(int fd, mainloop_callback_t cb, void *data)
+{
+	struct epoll_event ev = {
+		.events = EPOLLIN,
+	};
+
+	struct mainloop_data *md;
+
+	if (fd >= nrhandler) {
+		mds = realloc(mds, sizeof(*mds) * (fd + 1));
+		if (!mds)
+			return -1;
+		nrhandler = fd + 1;
+	}
+
+	md = malloc(sizeof(*md));
+	if (!md)
+		return -1;
+
+	md->data = data;
+	md->cb = cb;
+	md->fd = fd;
+
+	mds[fd] = md;
+	ev.data.ptr = md;
+
+	if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) < 0) {
+		free(md);
+		return -1;
+	}
+
+	return 0;
+}
+
+int mainloop_del(int fd)
+{
+	if (fd >= nrhandler)
+		return -1;
+
+	if (epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL) < 0)
+		return -1;
+
+	free(mds[fd]);
+
+	return 0;
+}
+
+int mainloop_init(void)
+{
+	epfd = epoll_create(2);
+	if (epfd < 0)
+		return -1;
+
+	return 0;
+}
+
+void mainloop_exit(void)
+{
+	exit_mainloop = 1;
+}
+
+void mainloop_fini(void)
+{
+	close(epfd);
+}
diff --git a/tools/thermal/lib/mainloop.h b/tools/thermal/lib/mainloop.h
new file mode 100644
index 000000000000..89b61e89d905
--- /dev/null
+++ b/tools/thermal/lib/mainloop.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/* Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> */
+#ifndef __THERMAL_TOOLS_MAINLOOP_H
+#define __THERMAL_TOOLS_MAINLOOP_H
+
+typedef int (*mainloop_callback_t)(int fd, void *data);
+
+extern int mainloop(unsigned int timeout);
+extern int mainloop_add(int fd, mainloop_callback_t cb, void *data);
+extern int mainloop_del(int fd);
+extern void mainloop_exit(void);
+extern int mainloop_init(void);
+extern void mainloop_fini(void);
+
+#endif
diff --git a/tools/thermal/lib/thermal-tools.h b/tools/thermal/lib/thermal-tools.h
new file mode 100644
index 000000000000..f43939a468a3
--- /dev/null
+++ b/tools/thermal/lib/thermal-tools.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/* Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> */
+#ifndef __THERMAL_TOOLS
+#define __THERMAL_TOOLS
+
+#include "log.h"
+#include "mainloop.h"
+#include "uptimeofday.h"
+
+#endif
diff --git a/tools/thermal/lib/uptimeofday.c b/tools/thermal/lib/uptimeofday.c
new file mode 100644
index 000000000000..dacb02956a68
--- /dev/null
+++ b/tools/thermal/lib/uptimeofday.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: LGPL-2.1+
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#include <stdio.h>
+#include <sys/time.h>
+#include <linux/sysinfo.h>
+#include "thermal-tools.h"
+
+static unsigned long __offset;
+static struct timeval __tv;
+
+int uptimeofday_init(void)
+{
+	struct sysinfo info;
+
+	if (sysinfo(&info))
+		return -1;
+
+	gettimeofday(&__tv, NULL);
+
+	__offset = __tv.tv_sec - info.uptime;
+
+	return 0;
+}
+
+unsigned long getuptimeofday_ms(void)
+{
+	gettimeofday(&__tv, NULL);
+
+	return ((__tv.tv_sec - __offset) * 1000) + (__tv.tv_usec / 1000);
+}
+
+struct timespec msec_to_timespec(int msec)
+{
+	struct timespec tv = {
+		.tv_sec = (msec / 1000),
+		.tv_nsec = (msec % 1000) * 1000000,
+	};
+
+	return tv;
+}
diff --git a/tools/thermal/lib/uptimeofday.h b/tools/thermal/lib/uptimeofday.h
new file mode 100644
index 000000000000..c0da5de41325
--- /dev/null
+++ b/tools/thermal/lib/uptimeofday.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+/* Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org> */
+#ifndef __THERMAL_TOOLS_UPTIMEOFDAY_H
+#define __THERMAL_TOOLS_UPTIMEOFDAY_H
+#include <sys/sysinfo.h>
+#include <sys/time.h>
+
+int uptimeofday_init(void);
+unsigned long getuptimeofday_ms(void);
+struct timespec msec_to_timespec(int msec);
+
+#endif
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 3/4] tools/thermal: A temperature capture tool
  2022-03-30 10:04 [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
  2022-03-30 10:04 ` [PATCH v2 1/4] tools/lib/thermal: Add a thermal library Daniel Lezcano
  2022-03-30 10:04 ` [PATCH v2 2/4] tools/thermal: Add util library Daniel Lezcano
@ 2022-03-30 10:04 ` Daniel Lezcano
  2022-03-30 10:04 ` [PATCH v2 4/4] tools/thermal: Add thermal daemon skeleton Daniel Lezcano
  2022-04-06  8:00 ` [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
  4 siblings, 0 replies; 19+ messages in thread
From: Daniel Lezcano @ 2022-03-30 10:04 UTC (permalink / raw)
  To: daniel.lezcano, rafael
  Cc: srinivas.pandruvada, linux-kernel, linux-pm, Amit Kucheria,
	Zhang Rui, Sasha Levin, William Breathitt Gray, Jonathan Cameron

The 'thermometer' tool allows to capture the temperature of a set of
thermal zones defined in a configuration file at a specified rate.

It is designed to have the lowest possible overhead. It will write the
captured temperature per thermal zone per file so making easier to
write a gnuplot script.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 tools/Makefile                             |  16 +-
 tools/thermal/thermometer/Build            |   2 +
 tools/thermal/thermometer/Makefile         |  26 +
 tools/thermal/thermometer/thermometer.8    |  93 ++++
 tools/thermal/thermometer/thermometer.c    | 558 +++++++++++++++++++++
 tools/thermal/thermometer/thermometer.conf |   5 +
 6 files changed, 697 insertions(+), 3 deletions(-)
 create mode 100644 tools/thermal/thermometer/Build
 create mode 100644 tools/thermal/thermometer/Makefile
 create mode 100644 tools/thermal/thermometer/thermometer.8
 create mode 100644 tools/thermal/thermometer/thermometer.c
 create mode 100644 tools/thermal/thermometer/thermometer.conf

diff --git a/tools/Makefile b/tools/Makefile
index c253cbd27c06..78615f8cb463 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -31,6 +31,7 @@ help:
 	@echo '  bootconfig             - boot config tool'
 	@echo '  spi                    - spi tools'
 	@echo '  tmon                   - thermal monitoring and tuning tool'
+	@echo '  thermometer            - temperature capture tool'
 	@echo '  thermal                - thermal library'
 	@echo '  tracing                - misc tracing tools'
 	@echo '  turbostat              - Intel CPU idle stats and freq reporting tool'
@@ -95,6 +96,9 @@ turbostat x86_energy_perf_policy intel-speed-select: FORCE
 tmon: FORCE
 	$(call descend,thermal/$@)
 
+thermometer: FORCE
+	$(call descend,thermal/$@)
+
 freefall: FORCE
 	$(call descend,laptop/$@)
 
@@ -105,7 +109,7 @@ all: acpi cgroup counter cpupower gpio hv firewire \
 		perf selftests bootconfig spi turbostat usb \
 		virtio vm bpf x86_energy_perf_policy \
 		tmon freefall iio objtool kvm_stat wmi \
-		pci debugging tracing thermal
+		pci debugging tracing thermal thermometer
 
 acpi_install:
 	$(call descend,power/$(@:_install=),install)
@@ -128,6 +132,9 @@ turbostat_install x86_energy_perf_policy_install intel-speed-select_install:
 tmon_install:
 	$(call descend,thermal/$(@:_install=),install)
 
+thermometer_install:
+	$(call descend,thermal/$(@:_install=),install)
+
 freefall_install:
 	$(call descend,laptop/$(@:_install=),install)
 
@@ -140,7 +147,7 @@ install: acpi_install cgroup_install counter_install cpupower_install gpio_insta
 		virtio_install vm_install bpf_install x86_energy_perf_policy_install \
 		tmon_install freefall_install objtool_install kvm_stat_install \
 		wmi_install pci_install debugging_install intel-speed-select_install \
-		tracing_install
+		tracing_install thermometer_install
 
 acpi_clean:
 	$(call descend,power/acpi,clean)
@@ -173,6 +180,9 @@ thermal_clean:
 turbostat_clean x86_energy_perf_policy_clean intel-speed-select_clean:
 	$(call descend,power/x86/$(@:_clean=),clean)
 
+thermometer_clean:
+	$(call descend,thermal/thermometer,clean)
+
 tmon_clean:
 	$(call descend,thermal/tmon,clean)
 
@@ -187,6 +197,6 @@ clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_cl
 		vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
 		freefall_clean build_clean libbpf_clean libsubcmd_clean \
 		gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \
-		intel-speed-select_clean tracing_clean thermal_clean
+		intel-speed-select_clean tracing_clean thermal_clean thermometer_clean
 
 .PHONY: FORCE
diff --git a/tools/thermal/thermometer/Build b/tools/thermal/thermometer/Build
new file mode 100644
index 000000000000..2531dda4acdd
--- /dev/null
+++ b/tools/thermal/thermometer/Build
@@ -0,0 +1,2 @@
+thermometer-y += thermometer.o
+
diff --git a/tools/thermal/thermometer/Makefile b/tools/thermal/thermometer/Makefile
new file mode 100644
index 000000000000..d8f8bc82fe3b
--- /dev/null
+++ b/tools/thermal/thermometer/Makefile
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for cgroup tools
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+# $(info Determined 'srctree' to be $(srctree))
+endif
+
+CFLAGS = -Wall -Wextra
+CFLAGS += -I$(srctree)/tools/thermal/lib
+
+LDFLAGS = -L$(srctree)/tools/thermal/lib
+LDFLAGS += -lthermal_tools
+LDFLAGS += -lconfig
+
+VERSION = 0.0.1
+TARGET=thermometer
+
+all: $(TARGET)
+%: %.c
+	$(CC) $(CFLAGS) -D VERSION=\"$(VERSION)\" -o $@ $^ $(LDFLAGS)
+
+clean:
+	$(RM) $(TARGET)
diff --git a/tools/thermal/thermometer/thermometer.8 b/tools/thermal/thermometer/thermometer.8
new file mode 100644
index 000000000000..5242220c12be
--- /dev/null
+++ b/tools/thermal/thermometer/thermometer.8
@@ -0,0 +1,93 @@
+.TH THERMOMETER 8
+# SPDX-License-Identifier: GPL-2.0
+.SH NAME
+\fBthermometer\fP - A thermal profiling tool
+
+.SH SYNOPSIS
+.ft B
+.B thermometer
+.RB [ options ]
+.RB [ command ]
+.br
+.SH DESCRIPTION
+\fBthermometer \fP captures the thermal zones temperature at a
+specified sampling period. It is optimized to reduce as much as
+possible the overhead while doing the temperature acquisition in order
+to prevent disrupting the running application we may want to profile.
+
+This low overhead also allows a high rate sampling for the temperature
+which could be necessary to spot overshots and undershots.
+
+If no configuration file is specified, then all the thermal zones will
+be monitored at 4Hz, so every 250ms. A configuration file specifies
+the thermal zone names and the desired sampling period. A thermal zone
+name can be a regular expression to specify a group of thermal zone.
+
+The sampling of the different thermal zones will be written into
+separate files with the thermal zone name. It is possible to specify a
+postfix to identify them for example for a specific scenario. The
+output directory can be specified in addition.
+
+Without any parameters, \fBthermometer \fP captures all the thermal
+zone temperatures every 250ms and write to the current directory the
+captured files postfixed with the current date.
+
+If a running \fBduration\fP is specified or a \fBcommand\fP, the
+capture ends at the end of the duration if the command did not
+finished before. The \fBduration\fP can be specified alone as well as
+the \fBcommand\fP. If none is specified, the capture will continue
+indefinitively until interrupted by \fBSIGINT\fP or \fBSIGQUIT\fP.
+.PP
+
+.SS Options
+.PP
+The \fB-h, --help\fP option shows a short usage help
+.PP
+The \fB-o <dir>, --output <dir>\fP option defines the output directory to put the
+sampling files
+.PP
+The \fB-c <config>, --config <config>\fP option specifies the configuration file to use
+.PP
+The \fB-d <seconds>, --duration <seconds>\fP option specifies the duration of the capture
+.PP
+The \fB-l <loglevel>, --loglevel <loglevel>\fP option sets the loglevel [DEBUG,INFO,NOTICE,WARN,ERROR]
+.PP
+The \fB-p <string>, --postfix <string>\fP option appends \fBstring\fP at the end of the capture filenames
+.PP
+The \fB-s, --syslog\fP option sets the output to syslog, default is \fBstdout\fP
+.PP
+The \fB-w, --overwrite\fP overwrites the output files if they exist
+.PP
+
+.PP
+
+.SS "Exit status:"
+.TP
+0
+if OK,
+.TP
+1
+Error with the options specified as parameters
+.TP
+2
+Error when configuring the logging facility
+.TP
+3
+Error when configuring the time
+.TP
+4
+Error in the initialization routine
+.TP
+5
+Error during the runtime
+
+.SH Capture file format
+
+Every file contains two columns. The first one is the uptime timestamp
+in order to find a point in time since the system started up if there
+is any thermal event. The second one is the temperature in milli
+degree. The first line contains the label of each column.
+
+.SH AUTHOR
+Daniel Lezcano <daniel.lezcano@kernel.org>
+
diff --git a/tools/thermal/thermometer/thermometer.c b/tools/thermal/thermometer/thermometer.c
new file mode 100644
index 000000000000..cb30a4a039cb
--- /dev/null
+++ b/tools/thermal/thermometer/thermometer.c
@@ -0,0 +1,558 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2022, Linaro Ltd - Daniel Lezcano <daniel.lezcano@linaro.org>
+#define _GNU_SOURCE
+#include <dirent.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <regex.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/signalfd.h>
+#include <sys/timerfd.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <linux/thermal.h>
+
+#include <libconfig.h>
+#include "thermal-tools.h"
+
+#define CLASS_THERMAL "/sys/class/thermal"
+
+enum {
+	THERMOMETER_SUCCESS = 0,
+	THERMOMETER_OPTION_ERROR,
+	THERMOMETER_LOG_ERROR,
+	THERMOMETER_CONFIG_ERROR,
+	THERMOMETER_TIME_ERROR,
+	THERMOMETER_INIT_ERROR,
+	THERMOMETER_RUNTIME_ERROR
+};
+
+struct options {
+	int loglvl;
+	int logopt;
+	int overwrite;
+	int duration;
+	const char *config;
+	char postfix[PATH_MAX];
+	char output[PATH_MAX];
+};
+
+struct tz_regex {
+	regex_t regex;
+	int polling;
+};
+
+struct configuration {
+	struct tz_regex *tz_regex;
+	int nr_tz_regex;
+
+};
+
+struct tz {
+	FILE *file_out;
+	int fd_temp;
+	int fd_timer;
+	int polling;
+	const char *name;
+};
+
+struct thermometer {
+	struct tz *tz;
+	int nr_tz;
+};
+
+static struct tz_regex *configuration_tz_match(const char *expr,
+					       struct configuration *config)
+{
+	int i;
+
+	for (i = 0; i < config->nr_tz_regex; i++) {
+
+		if (!regexec(&config->tz_regex[i].regex, expr, 0, NULL, 0))
+			return &config->tz_regex[i];
+	}
+
+	return NULL;
+}
+
+static int configuration_default_init(struct configuration *config)
+{
+	config->tz_regex = realloc(config->tz_regex, sizeof(*config->tz_regex) *
+				   (config->nr_tz_regex + 1));
+
+	if (regcomp(&config->tz_regex[config->nr_tz_regex].regex, ".*",
+		    REG_NOSUB | REG_EXTENDED)) {
+		ERROR("Invalid regular expression\n");
+		return -1;
+	}
+
+	config->tz_regex[config->nr_tz_regex].polling = 250;
+	config->nr_tz_regex = 1;
+
+	return 0;
+}
+
+static int configuration_init(const char *path, struct configuration *config)
+{
+	config_t cfg;
+
+	config_setting_t *tz;
+	int i, length;
+
+	if (path && access(path, F_OK)) {
+		ERROR("'%s' is not accessible\n", path);
+		return -1;
+	}
+
+	if (!path && !config->nr_tz_regex) {
+		INFO("No thermal zones configured, using wildcard for all of them\n");
+		return configuration_default_init(config);
+	}
+
+	config_init(&cfg);
+
+	if (!config_read_file(&cfg, path)) {
+		ERROR("Failed to parse %s:%d - %s\n", config_error_file(&cfg),
+		      config_error_line(&cfg), config_error_text(&cfg));
+
+		return -1;
+	}
+
+	tz = config_lookup(&cfg, "thermal-zones");
+	if (!tz) {
+		ERROR("No thermal zone configured to be monitored\n");
+		return -1;
+	}
+
+	length = config_setting_length(tz);
+
+	INFO("Found %d thermal zone(s) regular expression\n", length);
+
+	for (i = 0; i < length; i++) {
+
+		config_setting_t *node;
+		const char *name;
+		int polling;
+
+		node = config_setting_get_elem(tz, i);
+		if (!node) {
+			ERROR("Missing node name '%d'\n", i);
+			return -1;
+		};
+
+		if (!config_setting_lookup_string(node, "name", &name)) {
+			ERROR("Thermal zone name not found\n");
+			return -1;
+		}
+
+		if (!config_setting_lookup_int(node, "polling", &polling)) {
+			ERROR("Polling value not found");
+			return -1;
+		}
+
+		config->tz_regex = realloc(config->tz_regex, sizeof(*config->tz_regex) *
+					(config->nr_tz_regex + 1));
+
+		if (regcomp(&config->tz_regex[config->nr_tz_regex].regex, name,
+			    REG_NOSUB | REG_EXTENDED)) {
+			ERROR("Invalid regular expression '%s'\n", name);
+			continue;
+		}
+
+		config->tz_regex[config->nr_tz_regex].polling = polling;
+		config->nr_tz_regex++;
+
+		INFO("Thermal zone regular expression '%s' with polling %d\n",
+		     name, polling);
+	}
+
+	return 0;
+}
+
+static void help(const char *cmd)
+{
+	printf("%s Version: %s\n", cmd, VERSION);
+	printf("Usage: %s [options]\n", cmd);
+	printf("\t-h, --help\t\tthis help\n");
+	printf("\t-o, --output <dir>\toutput directory for temperature capture\n");
+	printf("\t-c, --config <file>\tconfiguration file\n");
+	printf("\t-d, --duration <seconds>\tcapture duration\n");
+	printf("\t-l, --loglevel <level>\tlog level: ");
+	printf("DEBUG, INFO, NOTICE, WARN, ERROR\n");
+	printf("\t-p, --postfix <string>\tpostfix to be happened at the end of the files\n");
+	printf("\t-s, --syslog\t\toutput to syslog\n");
+	printf("\t-w, --overwrite\t\toverwrite the temperature capture files if they exist\n");
+	printf("\n");
+	exit(0);
+}
+
+static int options_init(int argc, char *argv[], struct options *options)
+{
+	int opt;
+	time_t now = time(NULL);
+
+	struct option long_options[] = {
+		{ "help",	no_argument, NULL, 'h' },
+		{ "config",	required_argument, NULL, 'c' },
+		{ "duration",	required_argument, NULL, 'd' },
+		{ "loglevel",	required_argument, NULL, 'l' },
+		{ "postfix",	required_argument, NULL, 'p' },
+		{ "output",	required_argument, NULL, 'o' },
+		{ "syslog",	required_argument, NULL, 's' },
+		{ "overwrite",	no_argument, NULL, 'w' },
+		{ 0, 0, 0, 0 }
+	};
+
+	strftime(options->postfix, sizeof(options->postfix),
+		 "-%Y-%m-%d_%H:%M:%S", gmtime(&now));
+
+	while (1) {
+
+		int optindex = 0;
+
+		opt = getopt_long(argc, argv, "ho:c:d:l:p:sw", long_options, &optindex);
+		if (opt == -1)
+			break;
+
+		switch (opt) {
+		case 'c':
+			options->config = optarg;
+			break;
+		case 'd':
+			options->duration = atoi(optarg) * 1000;
+			break;
+		case 'l':
+			options->loglvl = log_str2level(optarg);
+			break;
+		case 'h':
+			help(basename(argv[0]));
+			break;
+		case 'p':
+			strcpy(options->postfix, optarg);
+			break;
+		case 'o':
+			strcpy(options->output, optarg);
+			break;
+		case 's':
+			options->logopt = TO_SYSLOG;
+			break;
+		case 'w':
+			options->overwrite = 1;
+			break;
+		default: /* '?' */
+			ERROR("Usage: %s --help\n", argv[0]);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int thermometer_add_tz(const char *path, const char *name, int polling,
+			      struct thermometer *thermometer)
+{
+	int fd;
+	char tz_path[PATH_MAX];
+
+	sprintf(tz_path, CLASS_THERMAL"/%s/temp", path);
+
+	fd = open(tz_path, O_RDONLY);
+	if (fd < 0) {
+		ERROR("Failed to open '%s': %m\n", tz_path);
+		return -1;
+	}
+
+	thermometer->tz = realloc(thermometer->tz,
+				  sizeof(*thermometer->tz) * (thermometer->nr_tz + 1));
+	if (!thermometer->tz) {
+		ERROR("Failed to allocate thermometer->tz\n");
+		return -1;
+	}
+
+	thermometer->tz[thermometer->nr_tz].fd_temp = fd;
+	thermometer->tz[thermometer->nr_tz].name = strdup(name);
+	thermometer->tz[thermometer->nr_tz].polling = polling;
+	thermometer->nr_tz++;
+
+	INFO("Added thermal zone '%s->%s (polling:%d)'\n", path, name, polling);
+
+	return 0;
+}
+
+static int thermometer_init(struct configuration *config,
+			    struct thermometer *thermometer)
+{
+	DIR *dir;
+	struct dirent *dirent;
+	struct tz_regex *tz_regex;
+	const char *tz_dirname = "thermal_zone";
+
+	if (mainloop_init()) {
+		ERROR("Failed to start mainloop\n");
+		return -1;
+	}
+
+	dir = opendir(CLASS_THERMAL);
+	if (!dir) {
+		ERROR("failed to open '%s'\n", CLASS_THERMAL);
+		return -1;
+	}
+
+	while ((dirent = readdir(dir))) {
+		char tz_type[THERMAL_NAME_LENGTH];
+		char tz_path[PATH_MAX];
+		FILE *tz_file;
+
+		if (strncmp(dirent->d_name, tz_dirname, strlen(tz_dirname)))
+			continue;
+
+		sprintf(tz_path, CLASS_THERMAL"/%s/type", dirent->d_name);
+
+		tz_file = fopen(tz_path, "r");
+		if (!tz_file) {
+			ERROR("Failed to open '%s': %m", tz_path);
+			continue;
+		}
+
+		fscanf(tz_file, "%s", tz_type);
+
+		fclose(tz_file);
+
+		tz_regex = configuration_tz_match(tz_type, config);
+		if (!tz_regex)
+			continue;
+
+		if (thermometer_add_tz(dirent->d_name, tz_type,
+				       tz_regex->polling, thermometer))
+			continue;
+	}
+
+	closedir(dir);
+
+	return 0;
+}
+
+static int timer_temperature_callback(int fd, void *arg)
+{
+	struct tz *tz = arg;
+	char buf[16] = { 0 };
+
+	pread(tz->fd_temp, buf, sizeof(buf), 0);
+
+	fprintf(tz->file_out, "%ld %s", getuptimeofday_ms(), buf);
+
+	read(fd, buf, sizeof(buf));
+
+	return 0;
+}
+
+static int thermometer_start(struct thermometer *thermometer,
+			     struct options *options)
+{
+	struct itimerspec timer_it = { 0 };
+	char *path;
+	FILE *f;
+	int i;
+
+	INFO("Capturing %d thermal zone(s) temperature...\n", thermometer->nr_tz);
+
+	if (access(options->output, F_OK) && mkdir(options->output, 0700)) {
+		ERROR("Failed to create directory '%s'\n", options->output);
+		return -1;
+	}
+
+	for (i = 0; i < thermometer->nr_tz; i++) {
+
+		asprintf(&path, "%s/%s%s", options->output,
+			 thermometer->tz[i].name, options->postfix);
+
+		if (!options->overwrite && !access(path, F_OK)) {
+			ERROR("'%s' already exists\n", path);
+			return -1;
+		}
+
+		f = fopen(path, "w");
+		if (!f) {
+			ERROR("Failed to create '%s':%m\n", path);
+			return -1;
+		}
+
+		fprintf(f, "timestamp(ms) %s(°mC)\n", thermometer->tz[i].name);
+
+		thermometer->tz[i].file_out = f;
+
+		DEBUG("Created '%s' file for thermal zone '%s'\n", path, thermometer->tz[i].name);
+
+		/*
+		 * Create polling timer
+		 */
+		thermometer->tz[i].fd_timer = timerfd_create(CLOCK_MONOTONIC, 0);
+		if (thermometer->tz[i].fd_timer < 0) {
+			ERROR("Failed to create timer for '%s': %m\n",
+			      thermometer->tz[i].name);
+			return -1;
+		}
+
+		DEBUG("Watching '%s' every %d ms\n",
+		      thermometer->tz[i].name, thermometer->tz[i].polling);
+
+		timer_it.it_interval = timer_it.it_value =
+			msec_to_timespec(thermometer->tz[i].polling);
+
+		if (timerfd_settime(thermometer->tz[i].fd_timer, 0,
+				    &timer_it, NULL) < 0)
+			return -1;
+
+		if (mainloop_add(thermometer->tz[i].fd_timer,
+				 timer_temperature_callback,
+				 &thermometer->tz[i]))
+			return -1;
+	}
+
+	return 0;
+}
+
+static int thermometer_execute(int argc, char *argv[], char *const envp[])
+{
+	pid_t pid;
+
+	if (!argc)
+		return 0;
+
+	pid = fork();
+	if (pid < 0) {
+		ERROR("Failed to fork process: %m");
+		return -1;
+	}
+
+	if (!pid) {
+		execvpe(argv[0], argv, envp);
+		exit(1);
+	}
+
+	return 0;
+}
+
+static int exit_mainloop(__maybe_unused int fd, __maybe_unused void *arg)
+{
+	mainloop_exit();
+
+	return 0;
+}
+
+static int thermometer_wait(struct options *options)
+{
+	int fd;
+	sigset_t mask;
+
+	/*
+	 * If there is a duration specified, we will exit the mainloop
+	 * and gracefully close all the files which will flush the
+	 * file system cache
+	 */
+	if (options->duration) {
+		struct itimerspec timer_it = { 0 };
+
+		timer_it.it_value = msec_to_timespec(options->duration);
+
+		fd = timerfd_create(CLOCK_MONOTONIC, 0);
+		if (fd < 0) {
+			ERROR("Failed to create duration timer: %m\n");
+			return -1;
+		}
+
+		if (timerfd_settime(fd, 0, &timer_it, NULL)) {
+			ERROR("Failed to set timer time: %m\n");
+			return -1;
+		}
+
+		if (mainloop_add(fd, exit_mainloop, NULL)) {
+			ERROR("Failed to set timer exit mainloop callback\n");
+			return -1;
+		}
+	}
+
+	/*
+	 * We want to catch any keyboard interrupt, as well as child
+	 * signals if any in order to exit properly
+	 */
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGINT);
+	sigaddset(&mask, SIGQUIT);
+	sigaddset(&mask, SIGCHLD);
+
+	if (sigprocmask(SIG_BLOCK, &mask, NULL)) {
+		ERROR("Failed to set sigprocmask: %m\n");
+		return -1;
+	}
+
+	fd = signalfd(-1, &mask, 0);
+	if (fd < 0) {
+		ERROR("Failed to set the signalfd: %m\n");
+		return -1;
+	}
+
+	if (mainloop_add(fd, exit_mainloop, NULL)) {
+		ERROR("Failed to set timer exit mainloop callback\n");
+		return -1;
+	}
+
+	return mainloop(-1);
+}
+
+static int thermometer_stop(struct thermometer *thermometer)
+{
+	int i;
+
+	INFO("Closing/flushing output files\n");
+
+	for (i = 0; i < thermometer->nr_tz; i++)
+		fclose(thermometer->tz[i].file_out);
+
+	return 0;
+}
+
+int main(int argc, char *argv[], char *const envp[])
+{
+	struct options options = {
+		.loglvl = LOG_DEBUG,
+		.logopt = TO_STDOUT,
+		.output = ".",
+	};
+	struct configuration config = { 0 };
+	struct thermometer thermometer = { 0 };
+
+	if (options_init(argc, argv, &options))
+		return THERMOMETER_OPTION_ERROR;
+
+	if (log_init(options.loglvl, argv[0], options.logopt))
+		return THERMOMETER_LOG_ERROR;
+
+	if (configuration_init(options.config, &config))
+		return THERMOMETER_CONFIG_ERROR;
+
+	if (uptimeofday_init())
+		return THERMOMETER_TIME_ERROR;
+
+	if (thermometer_init(&config, &thermometer))
+		return THERMOMETER_INIT_ERROR;
+
+	if (thermometer_start(&thermometer, &options))
+		return THERMOMETER_RUNTIME_ERROR;
+
+	if (thermometer_execute(argc - optind, &argv[optind], envp))
+		return THERMOMETER_RUNTIME_ERROR;
+
+	if (thermometer_wait(&options))
+		return THERMOMETER_RUNTIME_ERROR;
+
+	if (thermometer_stop(&thermometer))
+		return THERMOMETER_RUNTIME_ERROR;
+
+	return THERMOMETER_SUCCESS;
+}
diff --git a/tools/thermal/thermometer/thermometer.conf b/tools/thermal/thermometer/thermometer.conf
new file mode 100644
index 000000000000..456aa269c1b7
--- /dev/null
+++ b/tools/thermal/thermometer/thermometer.conf
@@ -0,0 +1,5 @@
+
+thermal-zones = (
+	      {	name = "cluster1-thermal";
+	      	polling = 100; }
+      )
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v2 4/4] tools/thermal: Add thermal daemon skeleton
  2022-03-30 10:04 [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
                   ` (2 preceding siblings ...)
  2022-03-30 10:04 ` [PATCH v2 3/4] tools/thermal: A temperature capture tool Daniel Lezcano
@ 2022-03-30 10:04 ` Daniel Lezcano
  2022-04-06  8:00 ` [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
  4 siblings, 0 replies; 19+ messages in thread
From: Daniel Lezcano @ 2022-03-30 10:04 UTC (permalink / raw)
  To: daniel.lezcano, rafael
  Cc: srinivas.pandruvada, linux-kernel, linux-pm, Amit Kucheria,
	Zhang Rui, Sasha Levin, Jonathan Cameron, William Breathitt Gray

This change provides a simple daemon skeleton. It is an example of how
to use the thermal library which wraps all the complex code related to
the netlink and transforms it into a callback oriented code.

The goal of this skeleton is to give a base brick for anyone
interested in writing its own thermal engine or as an example to rely
on to write its own thermal monitoring implementation.

In the future, it will evolve with more features and hopefully more
logic.

Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
---
 tools/Makefile                                |  16 +-
 tools/thermal/thermal-engine/Build            |   2 +
 tools/thermal/thermal-engine/Makefile         |  28 ++
 tools/thermal/thermal-engine/thermal-engine.c | 326 ++++++++++++++++++
 4 files changed, 369 insertions(+), 3 deletions(-)
 create mode 100644 tools/thermal/thermal-engine/Build
 create mode 100644 tools/thermal/thermal-engine/Makefile
 create mode 100644 tools/thermal/thermal-engine/thermal-engine.c

diff --git a/tools/Makefile b/tools/Makefile
index 78615f8cb463..b71cf39d3c08 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -32,6 +32,7 @@ help:
 	@echo '  spi                    - spi tools'
 	@echo '  tmon                   - thermal monitoring and tuning tool'
 	@echo '  thermometer            - temperature capture tool'
+	@echo '  thermal-engine         - thermal monitoring tool'
 	@echo '  thermal                - thermal library'
 	@echo '  tracing                - misc tracing tools'
 	@echo '  turbostat              - Intel CPU idle stats and freq reporting tool'
@@ -99,6 +100,9 @@ tmon: FORCE
 thermometer: FORCE
 	$(call descend,thermal/$@)
 
+thermal-engine: FORCE thermal
+	$(call descend,thermal/$@)
+
 freefall: FORCE
 	$(call descend,laptop/$@)
 
@@ -109,7 +113,7 @@ all: acpi cgroup counter cpupower gpio hv firewire \
 		perf selftests bootconfig spi turbostat usb \
 		virtio vm bpf x86_energy_perf_policy \
 		tmon freefall iio objtool kvm_stat wmi \
-		pci debugging tracing thermal thermometer
+		pci debugging tracing thermal thermometer thermal-engine
 
 acpi_install:
 	$(call descend,power/$(@:_install=),install)
@@ -135,6 +139,9 @@ tmon_install:
 thermometer_install:
 	$(call descend,thermal/$(@:_install=),install)
 
+thermal-engine_install:
+	$(call descend,thermal/$(@:_install=),install)
+
 freefall_install:
 	$(call descend,laptop/$(@:_install=),install)
 
@@ -147,7 +154,7 @@ install: acpi_install cgroup_install counter_install cpupower_install gpio_insta
 		virtio_install vm_install bpf_install x86_energy_perf_policy_install \
 		tmon_install freefall_install objtool_install kvm_stat_install \
 		wmi_install pci_install debugging_install intel-speed-select_install \
-		tracing_install thermometer_install
+		tracing_install thermometer_install thermal-engine_install
 
 acpi_clean:
 	$(call descend,power/acpi,clean)
@@ -183,6 +190,9 @@ turbostat_clean x86_energy_perf_policy_clean intel-speed-select_clean:
 thermometer_clean:
 	$(call descend,thermal/thermometer,clean)
 
+thermal-engine_clean:
+	$(call descend,thermal/thermal-engine,clean)
+
 tmon_clean:
 	$(call descend,thermal/tmon,clean)
 
@@ -197,6 +207,6 @@ clean: acpi_clean cgroup_clean counter_clean cpupower_clean hv_clean firewire_cl
 		vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
 		freefall_clean build_clean libbpf_clean libsubcmd_clean \
 		gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \
-		intel-speed-select_clean tracing_clean thermal_clean thermometer_clean
+		intel-speed-select_clean tracing_clean thermal_clean thermometer_clean thermal-engine_clean
 
 .PHONY: FORCE
diff --git a/tools/thermal/thermal-engine/Build b/tools/thermal/thermal-engine/Build
new file mode 100644
index 000000000000..0c8b65248c80
--- /dev/null
+++ b/tools/thermal/thermal-engine/Build
@@ -0,0 +1,2 @@
+thermal-engine-y += thermal-engine.o
+
diff --git a/tools/thermal/thermal-engine/Makefile b/tools/thermal/thermal-engine/Makefile
new file mode 100644
index 000000000000..6bd05ff89485
--- /dev/null
+++ b/tools/thermal/thermal-engine/Makefile
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for thermal tools
+
+ifeq ($(srctree),)
+srctree := $(patsubst %/,%,$(dir $(CURDIR)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+srctree := $(patsubst %/,%,$(dir $(srctree)))
+# $(info Determined 'srctree' to be $(srctree))
+endif
+
+CFLAGS = -Wall -Wextra
+CFLAGS += -I$(srctree)/tools/thermal/lib
+CFLAGS += -I$(srctree)/tools/lib/thermal/include
+
+LDFLAGS = -L$(srctree)/tools/thermal/lib
+LDFLAGS += -L$(srctree)/tools/lib/thermal
+LDFLAGS += -lthermal_tools
+LDFLAGS += -lthermal
+LDFLAGS += -lconfig
+LDFLAGS += -lnl-genl-3 -lnl-3
+
+VERSION = 0.0.1
+
+all: thermal-engine
+%: %.c
+	$(CC) $(CFLAGS) -D VERSION=\"$(VERSION)\" -o $@ $^ $(LDFLAGS)
+clean:
+	$(RM) thermal-engine
diff --git a/tools/thermal/thermal-engine/thermal-engine.c b/tools/thermal/thermal-engine/thermal-engine.c
new file mode 100644
index 000000000000..525520049aa2
--- /dev/null
+++ b/tools/thermal/thermal-engine/thermal-engine.c
@@ -0,0 +1,326 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Thermal monitoring tool based on the thermal netlink events.
+ *
+ * Copyright (C) 2022 Linaro Ltd.
+ *
+ * Author: Daniel Lezcano <daniel.lezcano@kernel.org>
+ */
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include <syslog.h>
+
+#include <sys/epoll.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <thermal.h>
+#include "thermal-tools.h"
+
+struct options {
+	int loglevel;
+	int logopt;
+	int interactive;
+	int daemonize;
+};
+
+struct thermal_data {
+	struct thermal_zone *tz;
+	struct thermal_handler *th;
+};
+
+static int show_trip(struct thermal_trip *tt, __maybe_unused void *arg)
+{
+	INFO("trip id=%d, type=%d, temp=%d, hyst=%d\n",
+	     tt->id, tt->type, tt->temp, tt->hyst);
+
+	return 0;
+}
+
+static int show_temp(struct thermal_zone *tz, __maybe_unused void *arg)
+{
+	thermal_cmd_get_temp(arg, tz);
+
+	INFO("temperature: %d\n", tz->temp);
+
+	return 0;
+}
+
+static int show_governor(struct thermal_zone *tz, __maybe_unused void *arg)
+{
+	thermal_cmd_get_governor(arg, tz);
+
+	INFO("governor: '%s'\n", tz->governor);
+
+	return 0;
+}
+
+static int show_tz(struct thermal_zone *tz, __maybe_unused void *arg)
+{
+	INFO("thermal zone '%s', id=%d\n", tz->name, tz->id);
+
+	for_each_thermal_trip(tz->trip, show_trip, NULL);
+
+	show_temp(tz, arg);
+
+	show_governor(tz, arg);
+
+	return 0;
+}
+
+static int tz_create(const char *name, int tz_id, __maybe_unused void *arg)
+{
+	INFO("Thermal zone '%s'/%d created\n", name, tz_id);
+
+	return 0;
+}
+
+static int tz_delete(int tz_id, __maybe_unused void *arg)
+{
+	INFO("Thermal zone %d deleted\n", tz_id);
+
+	return 0;
+}
+
+static int tz_disable(int tz_id, void *arg)
+{
+	struct thermal_data *td = arg;
+	struct thermal_zone *tz = thermal_zone_find_by_id(td->tz, tz_id);
+
+	INFO("Thermal zone %d ('%s') disabled\n", tz_id, tz->name);
+
+	return 0;
+}
+
+static int tz_enable(int tz_id, void *arg)
+{
+	struct thermal_data *td = arg;
+	struct thermal_zone *tz = thermal_zone_find_by_id(td->tz, tz_id);
+
+	INFO("Thermal zone %d ('%s') enabled\n", tz_id, tz->name);
+
+	return 0;
+}
+
+static int trip_high(int tz_id, int trip_id, int temp, void *arg)
+{
+	struct thermal_data *td = arg;
+	struct thermal_zone *tz = thermal_zone_find_by_id(td->tz, tz_id);
+
+	INFO("Thermal zone %d ('%s'): trip point %d crossed way up with %d °C\n",
+	     tz_id, tz->name, trip_id, temp);
+
+	return 0;
+}
+
+static int trip_low(int tz_id, int trip_id, int temp, void *arg)
+{
+	struct thermal_data *td = arg;
+	struct thermal_zone *tz = thermal_zone_find_by_id(td->tz, tz_id);
+
+	INFO("Thermal zone %d ('%s'): trip point %d crossed way down with %d °C\n",
+	     tz_id, tz->name, trip_id, temp);
+
+	return 0;
+}
+
+static int trip_add(int tz_id, int trip_id, int type, int temp, int hyst, __maybe_unused void *arg)
+{
+	INFO("Trip point added %d: id=%d, type=%d, temp=%d, hyst=%d\n",
+	     tz_id, trip_id, type, temp, hyst);
+
+	return 0;
+}
+
+static int trip_delete(int tz_id, int trip_id, __maybe_unused void *arg)
+{
+	INFO("Trip point deleted %d: id=%d\n", tz_id, trip_id);
+
+	return 0;
+}
+
+static int trip_change(int tz_id, int trip_id, int type, int temp,
+		       int hyst, __maybe_unused void *arg)
+{
+	struct thermal_data *td = arg;
+	struct thermal_zone *tz = thermal_zone_find_by_id(td->tz, tz_id);
+
+	INFO("Trip point changed %d: id=%d, type=%d, temp=%d, hyst=%d\n",
+	     tz_id, trip_id, type, temp, hyst);
+
+	tz->trip[trip_id].type = type;
+	tz->trip[trip_id].temp = temp;
+	tz->trip[trip_id].hyst = hyst;
+
+	return 0;
+}
+
+static int cdev_add(const char *name, int cdev_id, int max_state, __maybe_unused void *arg)
+{
+	INFO("Cooling device '%s'/%d (max state=%d) added\n", name, cdev_id, max_state);
+
+	return 0;
+}
+
+static int cdev_delete(int cdev_id, __maybe_unused void *arg)
+{
+	INFO("Cooling device %d deleted", cdev_id);
+
+	return 0;
+}
+
+static int cdev_update(int cdev_id, int cur_state, __maybe_unused void *arg)
+{
+	INFO("cdev:%d state:%d\n", cdev_id, cur_state);
+
+	return 0;
+}
+
+static int gov_change(int tz_id, const char *name, __maybe_unused void *arg)
+{
+	struct thermal_data *td = arg;
+	struct thermal_zone *tz = thermal_zone_find_by_id(td->tz, tz_id);
+
+	INFO("%s: governor changed %s -> %s\n", tz->name, tz->governor, name);
+
+	strcpy(tz->governor, name);
+
+	return 0;
+}
+
+static struct thermal_ops ops = {
+	.events.tz_create	= tz_create,
+	.events.tz_delete	= tz_delete,
+	.events.tz_disable	= tz_disable,
+	.events.tz_enable	= tz_enable,
+	.events.trip_high	= trip_high,
+	.events.trip_low	= trip_low,
+	.events.trip_add	= trip_add,
+	.events.trip_delete	= trip_delete,
+	.events.trip_change	= trip_change,
+	.events.cdev_add	= cdev_add,
+	.events.cdev_delete	= cdev_delete,
+	.events.cdev_update	= cdev_update,
+	.events.gov_change	= gov_change
+};
+
+static int thermal_event(__maybe_unused int fd, __maybe_unused void *arg)
+{
+	struct thermal_data *td = arg;
+
+	return thermal_events_handle(td->th, td);
+}
+
+static void help(const char *cmd)
+{
+	printf("%s : A thermal monitoring engine based on notifications\n", cmd);
+	printf("Usage: %s [options]\n", cmd);
+	printf("\t-h, --help\t\tthis help\n");
+	printf("\t-d, --daemonize\tcapture duration\n");
+	printf("\t-l <level>, --loglevel <level>\tlog level: ");
+	printf("DEBUG, INFO, NOTICE, WARN, ERROR\n");
+	printf("\t-s, --syslog\t\toutput to syslog\n");
+	printf("\n");
+	exit(0);
+}
+
+static int options_init(int argc, char *argv[], struct options *options)
+{
+	int opt;
+
+	struct option long_options[] = {
+		{ "help",	no_argument, NULL, 'h' },
+		{ "daemonize",	no_argument, NULL, 'd' },
+		{ "syslog",	no_argument, NULL, 's' },
+		{ "loglevel",	required_argument, NULL, 'l' },
+		{ 0, 0, 0, 0 }
+	};
+
+	while (1) {
+
+		int optindex = 0;
+
+		opt = getopt_long(argc, argv, "l:dhs", long_options, &optindex);
+		if (opt == -1)
+			break;
+
+		switch (opt) {
+		case 'l':
+			options->loglevel = log_str2level(optarg);
+			break;
+		case 'd':
+			options->daemonize = 1;
+			break;
+		case 's':
+			options->logopt = TO_SYSLOG;
+			break;
+		case 'h':
+			help(basename(argv[0]));
+			break;
+		default: /* '?' */
+			ERROR("Usage: %s --help\n", argv[0]);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+enum {
+	THERMAL_ENGINE_SUCCESS = 0,
+	THERMAL_ENGINE_OPTION_ERROR,
+	THERMAL_ENGINE_DAEMON_ERROR,
+	THERMAL_ENGINE_LOG_ERROR,
+	THERMAL_ENGINE_THERMAL_ERROR,
+	THERMAL_ENGINE_MAINLOOP_ERROR,
+};
+
+int main(int argc, char *argv[])
+{
+	struct thermal_data td;
+	struct options options = {
+		.loglevel = LOG_INFO,
+		.logopt = TO_STDOUT,
+	};
+
+	if (options_init(argc, argv, &options))
+		return THERMAL_ENGINE_OPTION_ERROR;
+
+	if (options.daemonize && daemon(0, 0))
+		return THERMAL_ENGINE_DAEMON_ERROR;
+
+	if (log_init(options.loglevel, basename(argv[0]), options.logopt))
+		return THERMAL_ENGINE_LOG_ERROR;
+
+	td.th = thermal_init(&ops);
+	if (!td.th)
+		return THERMAL_ENGINE_THERMAL_ERROR;
+
+	td.tz = thermal_zone_discover(td.th);
+	if (!td.tz)
+		return THERMAL_ENGINE_THERMAL_ERROR;
+
+	for_each_thermal_zone(td.tz, show_tz, td.th);
+
+	if (mainloop_init())
+		return THERMAL_ENGINE_MAINLOOP_ERROR;
+
+	if (mainloop_add(thermal_events_fd(td.th), thermal_event, &td))
+		return THERMAL_ENGINE_MAINLOOP_ERROR;
+
+	INFO("Waiting for thermal events ...\n");
+
+	if (mainloop(-1))
+		return THERMAL_ENGINE_MAINLOOP_ERROR;
+
+	return THERMAL_ENGINE_SUCCESS;
+}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-03-30 10:04 [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
                   ` (3 preceding siblings ...)
  2022-03-30 10:04 ` [PATCH v2 4/4] tools/thermal: Add thermal daemon skeleton Daniel Lezcano
@ 2022-04-06  8:00 ` Daniel Lezcano
  2022-04-06 14:28   ` srinivas pandruvada
  4 siblings, 1 reply; 19+ messages in thread
From: Daniel Lezcano @ 2022-04-06  8:00 UTC (permalink / raw)
  To: rafael; +Cc: srinivas.pandruvada, linux-kernel, linux-pm


Hi,

if there is no comment for the series, shall I pick it so we can go 
forward ?



On 30/03/2022 12:04, Daniel Lezcano wrote:
> These changes are providing the following tools and library:
> 
>   - A thermal library doing the netlink abstraction from the kernel in
>     order to make the userspace thermal implementation easier. Having
>     the library integrated with the kernel tree is also a guarantee to
>     keep the message format and their encoding/decoding aligned
>                                                                                                                                                                                                                                                                                 
>   - A thermal tools library providing a set of functions to deal with
>     usual features like the log, the mainloop and the time. This
>     library is used by the provided tools below
> 
>   - An data acquisition program to capture the temperature of the
>     different thermal zone during an amount of time or during the
>     execution of an application. The output is formated to be easily
>     parsed by gnuplot, a spreadsheet program or a statistical command
>     line utility. The timestamp is based on the system uptime, thus
>     giving an indication of when a thermal event happened, that can
>     help to spot or reproduce thermal issue in the long run
> 
>   - A thermal monitoring program based on the thermal library. It gives
>     a skeleton to build any logic on top of it and shows how to use the
>     thermal library. It does nothing except discovering the thermal
>     zones, their trip points and listening for events like cooling
>     devices state changes or trip point crossed
> 
>   Changelog:
> 
>   v1: Initial post after a RFC
> 
>   v2:
> 
>    - Fixed all trailing whitespaces and some other checkpatch
>      warnings. Some warnings remain but they can be considered as false
>      positive
> 
>    - Added in the thermometer tool:
>      - Usage/help option as well as a man page
>      - The ability to execute a program
>      - The capture duration
>      - Create the output directory if it does not exist
> 
>    - Add in the thermal-engine tool:
>      - A usage/help option
>      - A message telling the userspace it is waiting for events
>      - A daemonize option
> 
>    - Minor bug fixes here and there, as well as typos
> 
> Daniel Lezcano (4):
>    tools/lib/thermal: Add a thermal library
>    tools/thermal: Add util library
>    tools/thermal: A temperature capture tool
>    tools/thermal: Add thermal daemon skeleton
> 
>   MAINTAINERS                                   |   1 +
>   tools/Makefile                                |  36 +-
>   tools/lib/thermal/.gitignore                  |   2 +
>   tools/lib/thermal/Build                       |   5 +
>   tools/lib/thermal/Makefile                    | 165 ++++++
>   tools/lib/thermal/commands.c                  | 349 +++++++++++
>   tools/lib/thermal/events.c                    | 164 +++++
>   tools/lib/thermal/include/thermal.h           | 142 +++++
>   tools/lib/thermal/libthermal.map              |  25 +
>   tools/lib/thermal/libthermal.pc.template      |  12 +
>   tools/lib/thermal/sampling.c                  |  75 +++
>   tools/lib/thermal/thermal.c                   | 126 ++++
>   tools/lib/thermal/thermal_nl.c                | 215 +++++++
>   tools/lib/thermal/thermal_nl.h                |  46 ++
>   tools/thermal/lib/Build                       |   3 +
>   tools/thermal/lib/Makefile                    | 158 +++++
>   .../thermal/lib/libthermal_tools.pc.template  |  12 +
>   tools/thermal/lib/log.c                       |  77 +++
>   tools/thermal/lib/log.h                       |  31 +
>   tools/thermal/lib/mainloop.c                  | 120 ++++
>   tools/thermal/lib/mainloop.h                  |  15 +
>   tools/thermal/lib/thermal-tools.h             |  10 +
>   tools/thermal/lib/uptimeofday.c               |  40 ++
>   tools/thermal/lib/uptimeofday.h               |  12 +
>   tools/thermal/thermal-engine/Build            |   2 +
>   tools/thermal/thermal-engine/Makefile         |  28 +
>   tools/thermal/thermal-engine/thermal-engine.c | 326 ++++++++++
>   tools/thermal/thermometer/Build               |   2 +
>   tools/thermal/thermometer/Makefile            |  26 +
>   tools/thermal/thermometer/thermometer.8       |  93 +++
>   tools/thermal/thermometer/thermometer.c       | 558 ++++++++++++++++++
>   tools/thermal/thermometer/thermometer.conf    |   5 +
>   32 files changed, 2878 insertions(+), 3 deletions(-)
>   create mode 100644 tools/lib/thermal/.gitignore
>   create mode 100644 tools/lib/thermal/Build
>   create mode 100644 tools/lib/thermal/Makefile
>   create mode 100644 tools/lib/thermal/commands.c
>   create mode 100644 tools/lib/thermal/events.c
>   create mode 100644 tools/lib/thermal/include/thermal.h
>   create mode 100644 tools/lib/thermal/libthermal.map
>   create mode 100644 tools/lib/thermal/libthermal.pc.template
>   create mode 100644 tools/lib/thermal/sampling.c
>   create mode 100644 tools/lib/thermal/thermal.c
>   create mode 100644 tools/lib/thermal/thermal_nl.c
>   create mode 100644 tools/lib/thermal/thermal_nl.h
>   create mode 100644 tools/thermal/lib/Build
>   create mode 100644 tools/thermal/lib/Makefile
>   create mode 100644 tools/thermal/lib/libthermal_tools.pc.template
>   create mode 100644 tools/thermal/lib/log.c
>   create mode 100644 tools/thermal/lib/log.h
>   create mode 100644 tools/thermal/lib/mainloop.c
>   create mode 100644 tools/thermal/lib/mainloop.h
>   create mode 100644 tools/thermal/lib/thermal-tools.h
>   create mode 100644 tools/thermal/lib/uptimeofday.c
>   create mode 100644 tools/thermal/lib/uptimeofday.h
>   create mode 100644 tools/thermal/thermal-engine/Build
>   create mode 100644 tools/thermal/thermal-engine/Makefile
>   create mode 100644 tools/thermal/thermal-engine/thermal-engine.c
>   create mode 100644 tools/thermal/thermometer/Build
>   create mode 100644 tools/thermal/thermometer/Makefile
>   create mode 100644 tools/thermal/thermometer/thermometer.8
>   create mode 100644 tools/thermal/thermometer/thermometer.c
>   create mode 100644 tools/thermal/thermometer/thermometer.conf
> 


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-06  8:00 ` [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
@ 2022-04-06 14:28   ` srinivas pandruvada
  2022-04-06 14:44     ` Daniel Lezcano
  0 siblings, 1 reply; 19+ messages in thread
From: srinivas pandruvada @ 2022-04-06 14:28 UTC (permalink / raw)
  To: Daniel Lezcano, rafael; +Cc: linux-kernel, linux-pm

Hi Daniel,

On Wed, 2022-04-06 at 10:00 +0200, Daniel Lezcano wrote:
> 
> Hi,
> 
> if there is no comment for the series, shall I pick it so we can go 
> forward ?
Didn't get time to check yet. It will still be for the next merge
window, correct?

Thanks,
Srinivas

> 
> 
> 
> On 30/03/2022 12:04, Daniel Lezcano wrote:
> > These changes are providing the following tools and library:
> > 
> >   - A thermal library doing the netlink abstraction from the kernel
> > in
> >     order to make the userspace thermal implementation easier.
> > Having
> >     the library integrated with the kernel tree is also a guarantee
> > to
> >     keep the message format and their encoding/decoding aligned
> >                                                                    
> >                                                                    
> >                                                                    
> >                                                                    
> >    
> >   - A thermal tools library providing a set of functions to deal
> > with
> >     usual features like the log, the mainloop and the time. This
> >     library is used by the provided tools below
> > 
> >   - An data acquisition program to capture the temperature of the
> >     different thermal zone during an amount of time or during the
> >     execution of an application. The output is formated to be
> > easily
> >     parsed by gnuplot, a spreadsheet program or a statistical
> > command
> >     line utility. The timestamp is based on the system uptime, thus
> >     giving an indication of when a thermal event happened, that can
> >     help to spot or reproduce thermal issue in the long run
> > 
> >   - A thermal monitoring program based on the thermal library. It
> > gives
> >     a skeleton to build any logic on top of it and shows how to use
> > the
> >     thermal library. It does nothing except discovering the thermal
> >     zones, their trip points and listening for events like cooling
> >     devices state changes or trip point crossed
> > 
> >   Changelog:
> > 
> >   v1: Initial post after a RFC
> > 
> >   v2:
> > 
> >    - Fixed all trailing whitespaces and some other checkpatch
> >      warnings. Some warnings remain but they can be considered as
> > false
> >      positive
> > 
> >    - Added in the thermometer tool:
> >      - Usage/help option as well as a man page
> >      - The ability to execute a program
> >      - The capture duration
> >      - Create the output directory if it does not exist
> > 
> >    - Add in the thermal-engine tool:
> >      - A usage/help option
> >      - A message telling the userspace it is waiting for events
> >      - A daemonize option
> > 
> >    - Minor bug fixes here and there, as well as typos
> > 
> > Daniel Lezcano (4):
> >    tools/lib/thermal: Add a thermal library
> >    tools/thermal: Add util library
> >    tools/thermal: A temperature capture tool
> >    tools/thermal: Add thermal daemon skeleton
> > 
> >   MAINTAINERS                                   |   1 +
> >   tools/Makefile                                |  36 +-
> >   tools/lib/thermal/.gitignore                  |   2 +
> >   tools/lib/thermal/Build                       |   5 +
> >   tools/lib/thermal/Makefile                    | 165 ++++++
> >   tools/lib/thermal/commands.c                  | 349 +++++++++++
> >   tools/lib/thermal/events.c                    | 164 +++++
> >   tools/lib/thermal/include/thermal.h           | 142 +++++
> >   tools/lib/thermal/libthermal.map              |  25 +
> >   tools/lib/thermal/libthermal.pc.template      |  12 +
> >   tools/lib/thermal/sampling.c                  |  75 +++
> >   tools/lib/thermal/thermal.c                   | 126 ++++
> >   tools/lib/thermal/thermal_nl.c                | 215 +++++++
> >   tools/lib/thermal/thermal_nl.h                |  46 ++
> >   tools/thermal/lib/Build                       |   3 +
> >   tools/thermal/lib/Makefile                    | 158 +++++
> >   .../thermal/lib/libthermal_tools.pc.template  |  12 +
> >   tools/thermal/lib/log.c                       |  77 +++
> >   tools/thermal/lib/log.h                       |  31 +
> >   tools/thermal/lib/mainloop.c                  | 120 ++++
> >   tools/thermal/lib/mainloop.h                  |  15 +
> >   tools/thermal/lib/thermal-tools.h             |  10 +
> >   tools/thermal/lib/uptimeofday.c               |  40 ++
> >   tools/thermal/lib/uptimeofday.h               |  12 +
> >   tools/thermal/thermal-engine/Build            |   2 +
> >   tools/thermal/thermal-engine/Makefile         |  28 +
> >   tools/thermal/thermal-engine/thermal-engine.c | 326 ++++++++++
> >   tools/thermal/thermometer/Build               |   2 +
> >   tools/thermal/thermometer/Makefile            |  26 +
> >   tools/thermal/thermometer/thermometer.8       |  93 +++
> >   tools/thermal/thermometer/thermometer.c       | 558
> > ++++++++++++++++++
> >   tools/thermal/thermometer/thermometer.conf    |   5 +
> >   32 files changed, 2878 insertions(+), 3 deletions(-)
> >   create mode 100644 tools/lib/thermal/.gitignore
> >   create mode 100644 tools/lib/thermal/Build
> >   create mode 100644 tools/lib/thermal/Makefile
> >   create mode 100644 tools/lib/thermal/commands.c
> >   create mode 100644 tools/lib/thermal/events.c
> >   create mode 100644 tools/lib/thermal/include/thermal.h
> >   create mode 100644 tools/lib/thermal/libthermal.map
> >   create mode 100644 tools/lib/thermal/libthermal.pc.template
> >   create mode 100644 tools/lib/thermal/sampling.c
> >   create mode 100644 tools/lib/thermal/thermal.c
> >   create mode 100644 tools/lib/thermal/thermal_nl.c
> >   create mode 100644 tools/lib/thermal/thermal_nl.h
> >   create mode 100644 tools/thermal/lib/Build
> >   create mode 100644 tools/thermal/lib/Makefile
> >   create mode 100644 tools/thermal/lib/libthermal_tools.pc.template
> >   create mode 100644 tools/thermal/lib/log.c
> >   create mode 100644 tools/thermal/lib/log.h
> >   create mode 100644 tools/thermal/lib/mainloop.c
> >   create mode 100644 tools/thermal/lib/mainloop.h
> >   create mode 100644 tools/thermal/lib/thermal-tools.h
> >   create mode 100644 tools/thermal/lib/uptimeofday.c
> >   create mode 100644 tools/thermal/lib/uptimeofday.h
> >   create mode 100644 tools/thermal/thermal-engine/Build
> >   create mode 100644 tools/thermal/thermal-engine/Makefile
> >   create mode 100644 tools/thermal/thermal-engine/thermal-engine.c
> >   create mode 100644 tools/thermal/thermometer/Build
> >   create mode 100644 tools/thermal/thermometer/Makefile
> >   create mode 100644 tools/thermal/thermometer/thermometer.8
> >   create mode 100644 tools/thermal/thermometer/thermometer.c
> >   create mode 100644 tools/thermal/thermometer/thermometer.conf
> > 
> 
> 



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-06 14:28   ` srinivas pandruvada
@ 2022-04-06 14:44     ` Daniel Lezcano
  2022-04-13 15:06       ` Rafael J. Wysocki
  0 siblings, 1 reply; 19+ messages in thread
From: Daniel Lezcano @ 2022-04-06 14:44 UTC (permalink / raw)
  To: srinivas pandruvada, rafael; +Cc: linux-kernel, linux-pm

On 06/04/2022 16:28, srinivas pandruvada wrote:
> Hi Daniel,
> 
> On Wed, 2022-04-06 at 10:00 +0200, Daniel Lezcano wrote:
>>
>> Hi,
>>
>> if there is no comment for the series, shall I pick it so we can go
>> forward ?
> Didn't get time to check yet. It will still be for the next merge
> window, correct?

Right, but I would like to continue adding more features, scripts and 
tests. Iteratively.

>>
>> On 30/03/2022 12:04, Daniel Lezcano wrote:
>>> These changes are providing the following tools and library:
>>>
>>>    - A thermal library doing the netlink abstraction from the kernel
>>> in
>>>      order to make the userspace thermal implementation easier.
>>> Having
>>>      the library integrated with the kernel tree is also a guarantee
>>> to
>>>      keep the message format and their encoding/decoding aligned
>>>                                                                     
>>>                                                                     
>>>                                                                     
>>>                                                                     
>>>     
>>>    - A thermal tools library providing a set of functions to deal
>>> with
>>>      usual features like the log, the mainloop and the time. This
>>>      library is used by the provided tools below
>>>
>>>    - An data acquisition program to capture the temperature of the
>>>      different thermal zone during an amount of time or during the
>>>      execution of an application. The output is formated to be
>>> easily
>>>      parsed by gnuplot, a spreadsheet program or a statistical
>>> command
>>>      line utility. The timestamp is based on the system uptime, thus
>>>      giving an indication of when a thermal event happened, that can
>>>      help to spot or reproduce thermal issue in the long run
>>>
>>>    - A thermal monitoring program based on the thermal library. It
>>> gives
>>>      a skeleton to build any logic on top of it and shows how to use
>>> the
>>>      thermal library. It does nothing except discovering the thermal
>>>      zones, their trip points and listening for events like cooling
>>>      devices state changes or trip point crossed
>>>
>>>    Changelog:
>>>
>>>    v1: Initial post after a RFC
>>>
>>>    v2:
>>>
>>>     - Fixed all trailing whitespaces and some other checkpatch
>>>       warnings. Some warnings remain but they can be considered as
>>> false
>>>       positive
>>>
>>>     - Added in the thermometer tool:
>>>       - Usage/help option as well as a man page
>>>       - The ability to execute a program
>>>       - The capture duration
>>>       - Create the output directory if it does not exist
>>>
>>>     - Add in the thermal-engine tool:
>>>       - A usage/help option
>>>       - A message telling the userspace it is waiting for events
>>>       - A daemonize option
>>>
>>>     - Minor bug fixes here and there, as well as typos
>>>
>>> Daniel Lezcano (4):
>>>     tools/lib/thermal: Add a thermal library
>>>     tools/thermal: Add util library
>>>     tools/thermal: A temperature capture tool
>>>     tools/thermal: Add thermal daemon skeleton
>>>
>>>    MAINTAINERS                                   |   1 +
>>>    tools/Makefile                                |  36 +-
>>>    tools/lib/thermal/.gitignore                  |   2 +
>>>    tools/lib/thermal/Build                       |   5 +
>>>    tools/lib/thermal/Makefile                    | 165 ++++++
>>>    tools/lib/thermal/commands.c                  | 349 +++++++++++
>>>    tools/lib/thermal/events.c                    | 164 +++++
>>>    tools/lib/thermal/include/thermal.h           | 142 +++++
>>>    tools/lib/thermal/libthermal.map              |  25 +
>>>    tools/lib/thermal/libthermal.pc.template      |  12 +
>>>    tools/lib/thermal/sampling.c                  |  75 +++
>>>    tools/lib/thermal/thermal.c                   | 126 ++++
>>>    tools/lib/thermal/thermal_nl.c                | 215 +++++++
>>>    tools/lib/thermal/thermal_nl.h                |  46 ++
>>>    tools/thermal/lib/Build                       |   3 +
>>>    tools/thermal/lib/Makefile                    | 158 +++++
>>>    .../thermal/lib/libthermal_tools.pc.template  |  12 +
>>>    tools/thermal/lib/log.c                       |  77 +++
>>>    tools/thermal/lib/log.h                       |  31 +
>>>    tools/thermal/lib/mainloop.c                  | 120 ++++
>>>    tools/thermal/lib/mainloop.h                  |  15 +
>>>    tools/thermal/lib/thermal-tools.h             |  10 +
>>>    tools/thermal/lib/uptimeofday.c               |  40 ++
>>>    tools/thermal/lib/uptimeofday.h               |  12 +
>>>    tools/thermal/thermal-engine/Build            |   2 +
>>>    tools/thermal/thermal-engine/Makefile         |  28 +
>>>    tools/thermal/thermal-engine/thermal-engine.c | 326 ++++++++++
>>>    tools/thermal/thermometer/Build               |   2 +
>>>    tools/thermal/thermometer/Makefile            |  26 +
>>>    tools/thermal/thermometer/thermometer.8       |  93 +++
>>>    tools/thermal/thermometer/thermometer.c       | 558
>>> ++++++++++++++++++
>>>    tools/thermal/thermometer/thermometer.conf    |   5 +
>>>    32 files changed, 2878 insertions(+), 3 deletions(-)
>>>    create mode 100644 tools/lib/thermal/.gitignore
>>>    create mode 100644 tools/lib/thermal/Build
>>>    create mode 100644 tools/lib/thermal/Makefile
>>>    create mode 100644 tools/lib/thermal/commands.c
>>>    create mode 100644 tools/lib/thermal/events.c
>>>    create mode 100644 tools/lib/thermal/include/thermal.h
>>>    create mode 100644 tools/lib/thermal/libthermal.map
>>>    create mode 100644 tools/lib/thermal/libthermal.pc.template
>>>    create mode 100644 tools/lib/thermal/sampling.c
>>>    create mode 100644 tools/lib/thermal/thermal.c
>>>    create mode 100644 tools/lib/thermal/thermal_nl.c
>>>    create mode 100644 tools/lib/thermal/thermal_nl.h
>>>    create mode 100644 tools/thermal/lib/Build
>>>    create mode 100644 tools/thermal/lib/Makefile
>>>    create mode 100644 tools/thermal/lib/libthermal_tools.pc.template
>>>    create mode 100644 tools/thermal/lib/log.c
>>>    create mode 100644 tools/thermal/lib/log.h
>>>    create mode 100644 tools/thermal/lib/mainloop.c
>>>    create mode 100644 tools/thermal/lib/mainloop.h
>>>    create mode 100644 tools/thermal/lib/thermal-tools.h
>>>    create mode 100644 tools/thermal/lib/uptimeofday.c
>>>    create mode 100644 tools/thermal/lib/uptimeofday.h
>>>    create mode 100644 tools/thermal/thermal-engine/Build
>>>    create mode 100644 tools/thermal/thermal-engine/Makefile
>>>    create mode 100644 tools/thermal/thermal-engine/thermal-engine.c
>>>    create mode 100644 tools/thermal/thermometer/Build
>>>    create mode 100644 tools/thermal/thermometer/Makefile
>>>    create mode 100644 tools/thermal/thermometer/thermometer.8
>>>    create mode 100644 tools/thermal/thermometer/thermometer.c
>>>    create mode 100644 tools/thermal/thermometer/thermometer.conf
>>>
>>
>>
> 
> 


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-06 14:44     ` Daniel Lezcano
@ 2022-04-13 15:06       ` Rafael J. Wysocki
  2022-04-13 17:21         ` srinivas pandruvada
  0 siblings, 1 reply; 19+ messages in thread
From: Rafael J. Wysocki @ 2022-04-13 15:06 UTC (permalink / raw)
  To: Daniel Lezcano, srinivas pandruvada
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, Linux PM

On Wed, Apr 6, 2022 at 4:44 PM Daniel Lezcano <daniel.lezcano@linaro.org> wrote:
>
> On 06/04/2022 16:28, srinivas pandruvada wrote:
> > Hi Daniel,
> >
> > On Wed, 2022-04-06 at 10:00 +0200, Daniel Lezcano wrote:
> >>
> >> Hi,
> >>
> >> if there is no comment for the series, shall I pick it so we can go
> >> forward ?
> > Didn't get time to check yet. It will still be for the next merge
> > window, correct?
>
> Right, but I would like to continue adding more features, scripts and
> tests. Iteratively.

Srinivas, if you can give this a go, please, it will help.

Otherwise, I think that all of your comments so far have been
addressed, or have I missed anything?

>
> >>
> >> On 30/03/2022 12:04, Daniel Lezcano wrote:
> >>> These changes are providing the following tools and library:
> >>>
> >>>    - A thermal library doing the netlink abstraction from the kernel
> >>> in
> >>>      order to make the userspace thermal implementation easier.
> >>> Having
> >>>      the library integrated with the kernel tree is also a guarantee
> >>> to
> >>>      keep the message format and their encoding/decoding aligned
> >>>
> >>>
> >>>
> >>>
> >>>
> >>>    - A thermal tools library providing a set of functions to deal
> >>> with
> >>>      usual features like the log, the mainloop and the time. This
> >>>      library is used by the provided tools below
> >>>
> >>>    - An data acquisition program to capture the temperature of the
> >>>      different thermal zone during an amount of time or during the
> >>>      execution of an application. The output is formated to be
> >>> easily
> >>>      parsed by gnuplot, a spreadsheet program or a statistical
> >>> command
> >>>      line utility. The timestamp is based on the system uptime, thus
> >>>      giving an indication of when a thermal event happened, that can
> >>>      help to spot or reproduce thermal issue in the long run
> >>>
> >>>    - A thermal monitoring program based on the thermal library. It
> >>> gives
> >>>      a skeleton to build any logic on top of it and shows how to use
> >>> the
> >>>      thermal library. It does nothing except discovering the thermal
> >>>      zones, their trip points and listening for events like cooling
> >>>      devices state changes or trip point crossed
> >>>
> >>>    Changelog:
> >>>
> >>>    v1: Initial post after a RFC
> >>>
> >>>    v2:
> >>>
> >>>     - Fixed all trailing whitespaces and some other checkpatch
> >>>       warnings. Some warnings remain but they can be considered as
> >>> false
> >>>       positive
> >>>
> >>>     - Added in the thermometer tool:
> >>>       - Usage/help option as well as a man page
> >>>       - The ability to execute a program
> >>>       - The capture duration
> >>>       - Create the output directory if it does not exist
> >>>
> >>>     - Add in the thermal-engine tool:
> >>>       - A usage/help option
> >>>       - A message telling the userspace it is waiting for events
> >>>       - A daemonize option
> >>>
> >>>     - Minor bug fixes here and there, as well as typos
> >>>
> >>> Daniel Lezcano (4):
> >>>     tools/lib/thermal: Add a thermal library
> >>>     tools/thermal: Add util library
> >>>     tools/thermal: A temperature capture tool
> >>>     tools/thermal: Add thermal daemon skeleton
> >>>
> >>>    MAINTAINERS                                   |   1 +
> >>>    tools/Makefile                                |  36 +-
> >>>    tools/lib/thermal/.gitignore                  |   2 +
> >>>    tools/lib/thermal/Build                       |   5 +
> >>>    tools/lib/thermal/Makefile                    | 165 ++++++
> >>>    tools/lib/thermal/commands.c                  | 349 +++++++++++
> >>>    tools/lib/thermal/events.c                    | 164 +++++
> >>>    tools/lib/thermal/include/thermal.h           | 142 +++++
> >>>    tools/lib/thermal/libthermal.map              |  25 +
> >>>    tools/lib/thermal/libthermal.pc.template      |  12 +
> >>>    tools/lib/thermal/sampling.c                  |  75 +++
> >>>    tools/lib/thermal/thermal.c                   | 126 ++++
> >>>    tools/lib/thermal/thermal_nl.c                | 215 +++++++
> >>>    tools/lib/thermal/thermal_nl.h                |  46 ++
> >>>    tools/thermal/lib/Build                       |   3 +
> >>>    tools/thermal/lib/Makefile                    | 158 +++++
> >>>    .../thermal/lib/libthermal_tools.pc.template  |  12 +
> >>>    tools/thermal/lib/log.c                       |  77 +++
> >>>    tools/thermal/lib/log.h                       |  31 +
> >>>    tools/thermal/lib/mainloop.c                  | 120 ++++
> >>>    tools/thermal/lib/mainloop.h                  |  15 +
> >>>    tools/thermal/lib/thermal-tools.h             |  10 +
> >>>    tools/thermal/lib/uptimeofday.c               |  40 ++
> >>>    tools/thermal/lib/uptimeofday.h               |  12 +
> >>>    tools/thermal/thermal-engine/Build            |   2 +
> >>>    tools/thermal/thermal-engine/Makefile         |  28 +
> >>>    tools/thermal/thermal-engine/thermal-engine.c | 326 ++++++++++
> >>>    tools/thermal/thermometer/Build               |   2 +
> >>>    tools/thermal/thermometer/Makefile            |  26 +
> >>>    tools/thermal/thermometer/thermometer.8       |  93 +++
> >>>    tools/thermal/thermometer/thermometer.c       | 558
> >>> ++++++++++++++++++
> >>>    tools/thermal/thermometer/thermometer.conf    |   5 +
> >>>    32 files changed, 2878 insertions(+), 3 deletions(-)
> >>>    create mode 100644 tools/lib/thermal/.gitignore
> >>>    create mode 100644 tools/lib/thermal/Build
> >>>    create mode 100644 tools/lib/thermal/Makefile
> >>>    create mode 100644 tools/lib/thermal/commands.c
> >>>    create mode 100644 tools/lib/thermal/events.c
> >>>    create mode 100644 tools/lib/thermal/include/thermal.h
> >>>    create mode 100644 tools/lib/thermal/libthermal.map
> >>>    create mode 100644 tools/lib/thermal/libthermal.pc.template
> >>>    create mode 100644 tools/lib/thermal/sampling.c
> >>>    create mode 100644 tools/lib/thermal/thermal.c
> >>>    create mode 100644 tools/lib/thermal/thermal_nl.c
> >>>    create mode 100644 tools/lib/thermal/thermal_nl.h
> >>>    create mode 100644 tools/thermal/lib/Build
> >>>    create mode 100644 tools/thermal/lib/Makefile
> >>>    create mode 100644 tools/thermal/lib/libthermal_tools.pc.template
> >>>    create mode 100644 tools/thermal/lib/log.c
> >>>    create mode 100644 tools/thermal/lib/log.h
> >>>    create mode 100644 tools/thermal/lib/mainloop.c
> >>>    create mode 100644 tools/thermal/lib/mainloop.h
> >>>    create mode 100644 tools/thermal/lib/thermal-tools.h
> >>>    create mode 100644 tools/thermal/lib/uptimeofday.c
> >>>    create mode 100644 tools/thermal/lib/uptimeofday.h
> >>>    create mode 100644 tools/thermal/thermal-engine/Build
> >>>    create mode 100644 tools/thermal/thermal-engine/Makefile
> >>>    create mode 100644 tools/thermal/thermal-engine/thermal-engine.c
> >>>    create mode 100644 tools/thermal/thermometer/Build
> >>>    create mode 100644 tools/thermal/thermometer/Makefile
> >>>    create mode 100644 tools/thermal/thermometer/thermometer.8
> >>>    create mode 100644 tools/thermal/thermometer/thermometer.c
> >>>    create mode 100644 tools/thermal/thermometer/thermometer.conf
> >>>
> >>
> >>
> >
> >
>
>
> --
> <http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs
>
> Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> <http://twitter.com/#!/linaroorg> Twitter |
> <http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-13 15:06       ` Rafael J. Wysocki
@ 2022-04-13 17:21         ` srinivas pandruvada
  2022-04-16  3:50           ` srinivas pandruvada
  0 siblings, 1 reply; 19+ messages in thread
From: srinivas pandruvada @ 2022-04-13 17:21 UTC (permalink / raw)
  To: Rafael J. Wysocki, Daniel Lezcano; +Cc: Linux Kernel Mailing List, Linux PM

On Wed, 2022-04-13 at 17:06 +0200, Rafael J. Wysocki wrote:
> On Wed, Apr 6, 2022 at 4:44 PM Daniel Lezcano <
> daniel.lezcano@linaro.org> wrote:
> > 
> > On 06/04/2022 16:28, srinivas pandruvada wrote:
> > > Hi Daniel,
> > > 
> > > On Wed, 2022-04-06 at 10:00 +0200, Daniel Lezcano wrote:
> > > > 
> > > > Hi,
> > > > 
> > > > if there is no comment for the series, shall I pick it so we
> > > > can go
> > > > forward ?
> > > Didn't get time to check yet. It will still be for the next merge
> > > window, correct?
> > 
> > Right, but I would like to continue adding more features, scripts
> > and
> > tests. Iteratively.
> 
> Srinivas, if you can give this a go, please, it will help.
> 
> Otherwise, I think that all of your comments so far have been
> addressed, or have I missed anything?
> 
I will provide by the end of this week.

Thanks,
Srinivas


> > 
> > > > 
> > > > On 30/03/2022 12:04, Daniel Lezcano wrote:
> > > > > These changes are providing the following tools and library:
> > > > > 
> > > > >    - A thermal library doing the netlink abstraction from the
> > > > > kernel
> > > > > in
> > > > >      order to make the userspace thermal implementation
> > > > > easier.
> > > > > Having
> > > > >      the library integrated with the kernel tree is also a
> > > > > guarantee
> > > > > to
> > > > >      keep the message format and their encoding/decoding
> > > > > aligned
> > > > > 
> > > > > 
> > > > > 
> > > > > 
> > > > > 
> > > > >    - A thermal tools library providing a set of functions to
> > > > > deal
> > > > > with
> > > > >      usual features like the log, the mainloop and the time.
> > > > > This
> > > > >      library is used by the provided tools below
> > > > > 
> > > > >    - An data acquisition program to capture the temperature
> > > > > of the
> > > > >      different thermal zone during an amount of time or
> > > > > during the
> > > > >      execution of an application. The output is formated to
> > > > > be
> > > > > easily
> > > > >      parsed by gnuplot, a spreadsheet program or a
> > > > > statistical
> > > > > command
> > > > >      line utility. The timestamp is based on the system
> > > > > uptime, thus
> > > > >      giving an indication of when a thermal event happened,
> > > > > that can
> > > > >      help to spot or reproduce thermal issue in the long run
> > > > > 
> > > > >    - A thermal monitoring program based on the thermal
> > > > > library. It
> > > > > gives
> > > > >      a skeleton to build any logic on top of it and shows how
> > > > > to use
> > > > > the
> > > > >      thermal library. It does nothing except discovering the
> > > > > thermal
> > > > >      zones, their trip points and listening for events like
> > > > > cooling
> > > > >      devices state changes or trip point crossed
> > > > > 
> > > > >    Changelog:
> > > > > 
> > > > >    v1: Initial post after a RFC
> > > > > 
> > > > >    v2:
> > > > > 
> > > > >     - Fixed all trailing whitespaces and some other
> > > > > checkpatch
> > > > >       warnings. Some warnings remain but they can be
> > > > > considered as
> > > > > false
> > > > >       positive
> > > > > 
> > > > >     - Added in the thermometer tool:
> > > > >       - Usage/help option as well as a man page
> > > > >       - The ability to execute a program
> > > > >       - The capture duration
> > > > >       - Create the output directory if it does not exist
> > > > > 
> > > > >     - Add in the thermal-engine tool:
> > > > >       - A usage/help option
> > > > >       - A message telling the userspace it is waiting for
> > > > > events
> > > > >       - A daemonize option
> > > > > 
> > > > >     - Minor bug fixes here and there, as well as typos
> > > > > 
> > > > > Daniel Lezcano (4):
> > > > >     tools/lib/thermal: Add a thermal library
> > > > >     tools/thermal: Add util library
> > > > >     tools/thermal: A temperature capture tool
> > > > >     tools/thermal: Add thermal daemon skeleton
> > > > > 
> > > > >    MAINTAINERS                                   |   1 +
> > > > >    tools/Makefile                                |  36 +-
> > > > >    tools/lib/thermal/.gitignore                  |   2 +
> > > > >    tools/lib/thermal/Build                       |   5 +
> > > > >    tools/lib/thermal/Makefile                    | 165 ++++++
> > > > >    tools/lib/thermal/commands.c                  | 349
> > > > > +++++++++++
> > > > >    tools/lib/thermal/events.c                    | 164 +++++
> > > > >    tools/lib/thermal/include/thermal.h           | 142 +++++
> > > > >    tools/lib/thermal/libthermal.map              |  25 +
> > > > >    tools/lib/thermal/libthermal.pc.template      |  12 +
> > > > >    tools/lib/thermal/sampling.c                  |  75 +++
> > > > >    tools/lib/thermal/thermal.c                   | 126 ++++
> > > > >    tools/lib/thermal/thermal_nl.c                | 215
> > > > > +++++++
> > > > >    tools/lib/thermal/thermal_nl.h                |  46 ++
> > > > >    tools/thermal/lib/Build                       |   3 +
> > > > >    tools/thermal/lib/Makefile                    | 158 +++++
> > > > >    .../thermal/lib/libthermal_tools.pc.template  |  12 +
> > > > >    tools/thermal/lib/log.c                       |  77 +++
> > > > >    tools/thermal/lib/log.h                       |  31 +
> > > > >    tools/thermal/lib/mainloop.c                  | 120 ++++
> > > > >    tools/thermal/lib/mainloop.h                  |  15 +
> > > > >    tools/thermal/lib/thermal-tools.h             |  10 +
> > > > >    tools/thermal/lib/uptimeofday.c               |  40 ++
> > > > >    tools/thermal/lib/uptimeofday.h               |  12 +
> > > > >    tools/thermal/thermal-engine/Build            |   2 +
> > > > >    tools/thermal/thermal-engine/Makefile         |  28 +
> > > > >    tools/thermal/thermal-engine/thermal-engine.c | 326
> > > > > ++++++++++
> > > > >    tools/thermal/thermometer/Build               |   2 +
> > > > >    tools/thermal/thermometer/Makefile            |  26 +
> > > > >    tools/thermal/thermometer/thermometer.8       |  93 +++
> > > > >    tools/thermal/thermometer/thermometer.c       | 558
> > > > > ++++++++++++++++++
> > > > >    tools/thermal/thermometer/thermometer.conf    |   5 +
> > > > >    32 files changed, 2878 insertions(+), 3 deletions(-)
> > > > >    create mode 100644 tools/lib/thermal/.gitignore
> > > > >    create mode 100644 tools/lib/thermal/Build
> > > > >    create mode 100644 tools/lib/thermal/Makefile
> > > > >    create mode 100644 tools/lib/thermal/commands.c
> > > > >    create mode 100644 tools/lib/thermal/events.c
> > > > >    create mode 100644 tools/lib/thermal/include/thermal.h
> > > > >    create mode 100644 tools/lib/thermal/libthermal.map
> > > > >    create mode 100644
> > > > > tools/lib/thermal/libthermal.pc.template
> > > > >    create mode 100644 tools/lib/thermal/sampling.c
> > > > >    create mode 100644 tools/lib/thermal/thermal.c
> > > > >    create mode 100644 tools/lib/thermal/thermal_nl.c
> > > > >    create mode 100644 tools/lib/thermal/thermal_nl.h
> > > > >    create mode 100644 tools/thermal/lib/Build
> > > > >    create mode 100644 tools/thermal/lib/Makefile
> > > > >    create mode 100644
> > > > > tools/thermal/lib/libthermal_tools.pc.template
> > > > >    create mode 100644 tools/thermal/lib/log.c
> > > > >    create mode 100644 tools/thermal/lib/log.h
> > > > >    create mode 100644 tools/thermal/lib/mainloop.c
> > > > >    create mode 100644 tools/thermal/lib/mainloop.h
> > > > >    create mode 100644 tools/thermal/lib/thermal-tools.h
> > > > >    create mode 100644 tools/thermal/lib/uptimeofday.c
> > > > >    create mode 100644 tools/thermal/lib/uptimeofday.h
> > > > >    create mode 100644 tools/thermal/thermal-engine/Build
> > > > >    create mode 100644 tools/thermal/thermal-engine/Makefile
> > > > >    create mode 100644 tools/thermal/thermal-engine/thermal-
> > > > > engine.c
> > > > >    create mode 100644 tools/thermal/thermometer/Build
> > > > >    create mode 100644 tools/thermal/thermometer/Makefile
> > > > >    create mode 100644 tools/thermal/thermometer/thermometer.8
> > > > >    create mode 100644 tools/thermal/thermometer/thermometer.c
> > > > >    create mode 100644
> > > > > tools/thermal/thermometer/thermometer.conf
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > 
> > 
> > --
> > <http://www.linaro.org/> Linaro.org │ Open source software for ARM
> > SoCs
> > 
> > Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> > <http://twitter.com/#!/linaroorg> Twitter |
> > <http://www.linaro.org/linaro-blog/> Blog



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-13 17:21         ` srinivas pandruvada
@ 2022-04-16  3:50           ` srinivas pandruvada
  2022-04-16  7:55             ` Daniel Lezcano
  0 siblings, 1 reply; 19+ messages in thread
From: srinivas pandruvada @ 2022-04-16  3:50 UTC (permalink / raw)
  To: Rafael J. Wysocki, Daniel Lezcano; +Cc: Linux Kernel Mailing List, Linux PM

On Wed, 2022-04-13 at 10:21 -0700, srinivas pandruvada wrote:
> On Wed, 2022-04-13 at 17:06 +0200, Rafael J. Wysocki wrote:
> > On Wed, Apr 6, 2022 at 4:44 PM Daniel Lezcano <
> > daniel.lezcano@linaro.org> wrote:
> > > 
> > > On 06/04/2022 16:28, srinivas pandruvada wrote:
> > > > Hi Daniel,
> > > > 
> > > > On Wed, 2022-04-06 at 10:00 +0200, Daniel Lezcano wrote:
> > > > > 
> > > > > Hi,
> > > > > 
> > > > > if there is no comment for the series, shall I pick it so we
> > > > > can go
> > > > > forward ?
> > > > Didn't get time to check yet. It will still be for the next merge
> > > > window, correct?
> > > 
> > > Right, but I would like to continue adding more features, scripts
> > > and
> > > tests. Iteratively.
> > 
> > Srinivas, if you can give this a go, please, it will help.
> > 
> > Otherwise, I think that all of your comments so far have been
> > addressed, or have I missed anything?
> > 
> I will provide by the end of this week.

1. Some warnings in applying patch

Applying: tools/lib/thermal: Add a thermal library
Applying: tools/thermal: Add util library
Applying: tools/thermal: A temperature capture tool
.git/rebase-apply/patch:795: space before tab in indent.
	      	polling = 100; }
.git/rebase-apply/patch:90: new blank line at EOF.
+
.git/rebase-apply/patch:221: new blank line at EOF.
+
warning: 3 lines add whitespace errors.
Applying: tools/thermal: Add thermal daemon skeleton
.git/rebase-apply/patch:86: new blank line at EOF.
+
warning: 1 line adds whitespace errors.

2. Thermometer is fine

3. segfault for thermal-engine

LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH ./thermal-
engine
Segmentation fault (core dumped)
root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
./thermal-engine --help
thermal-engine : A thermal monitoring engine based on notifications
Usage: thermal-engine [options]
	-h, --help		this help
	-d, --daemonize	capture duration
	-l <level>, --loglevel <level>	log level: DEBUG, INFO,
NOTICE, WARN, ERROR
	-s, --syslog		output to syslog

root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
./thermal-engine -l DEBUG
Segmentation fault (core dumped)
root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
./thermal-engine --loglevel DEBUG
Segmentation fault (core dumped)
root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
./thermal-engine -s
Segmentation fault (core dumped)

Thanks,
Srinivas

> 
> Thanks,
> Srinivas
> 
> 
> > > 
> > > > > 
> > > > > On 30/03/2022 12:04, Daniel Lezcano wrote:
> > > > > > These changes are providing the following tools and library:
> > > > > > 
> > > > > >    - A thermal library doing the netlink abstraction from the
> > > > > > kernel
> > > > > > in
> > > > > >      order to make the userspace thermal implementation
> > > > > > easier.
> > > > > > Having
> > > > > >      the library integrated with the kernel tree is also a
> > > > > > guarantee
> > > > > > to
> > > > > >      keep the message format and their encoding/decoding
> > > > > > aligned
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > > 
> > > > > >    - A thermal tools library providing a set of functions to
> > > > > > deal
> > > > > > with
> > > > > >      usual features like the log, the mainloop and the time.
> > > > > > This
> > > > > >      library is used by the provided tools below
> > > > > > 
> > > > > >    - An data acquisition program to capture the temperature
> > > > > > of the
> > > > > >      different thermal zone during an amount of time or
> > > > > > during the
> > > > > >      execution of an application. The output is formated to
> > > > > > be
> > > > > > easily
> > > > > >      parsed by gnuplot, a spreadsheet program or a
> > > > > > statistical
> > > > > > command
> > > > > >      line utility. The timestamp is based on the system
> > > > > > uptime, thus
> > > > > >      giving an indication of when a thermal event happened,
> > > > > > that can
> > > > > >      help to spot or reproduce thermal issue in the long run
> > > > > > 
> > > > > >    - A thermal monitoring program based on the thermal
> > > > > > library. It
> > > > > > gives
> > > > > >      a skeleton to build any logic on top of it and shows how
> > > > > > to use
> > > > > > the
> > > > > >      thermal library. It does nothing except discovering the
> > > > > > thermal
> > > > > >      zones, their trip points and listening for events like
> > > > > > cooling
> > > > > >      devices state changes or trip point crossed
> > > > > > 
> > > > > >    Changelog:
> > > > > > 
> > > > > >    v1: Initial post after a RFC
> > > > > > 
> > > > > >    v2:
> > > > > > 
> > > > > >     - Fixed all trailing whitespaces and some other
> > > > > > checkpatch
> > > > > >       warnings. Some warnings remain but they can be
> > > > > > considered as
> > > > > > false
> > > > > >       positive
> > > > > > 
> > > > > >     - Added in the thermometer tool:
> > > > > >       - Usage/help option as well as a man page
> > > > > >       - The ability to execute a program
> > > > > >       - The capture duration
> > > > > >       - Create the output directory if it does not exist
> > > > > > 
> > > > > >     - Add in the thermal-engine tool:
> > > > > >       - A usage/help option
> > > > > >       - A message telling the userspace it is waiting for
> > > > > > events
> > > > > >       - A daemonize option
> > > > > > 
> > > > > >     - Minor bug fixes here and there, as well as typos
> > > > > > 
> > > > > > Daniel Lezcano (4):
> > > > > >     tools/lib/thermal: Add a thermal library
> > > > > >     tools/thermal: Add util library
> > > > > >     tools/thermal: A temperature capture tool
> > > > > >     tools/thermal: Add thermal daemon skeleton
> > > > > > 
> > > > > >    MAINTAINERS                                   |   1 +
> > > > > >    tools/Makefile                                |  36 +-
> > > > > >    tools/lib/thermal/.gitignore                  |   2 +
> > > > > >    tools/lib/thermal/Build                       |   5 +
> > > > > >    tools/lib/thermal/Makefile                    | 165 ++++++
> > > > > >    tools/lib/thermal/commands.c                  | 349
> > > > > > +++++++++++
> > > > > >    tools/lib/thermal/events.c                    | 164 +++++
> > > > > >    tools/lib/thermal/include/thermal.h           | 142 +++++
> > > > > >    tools/lib/thermal/libthermal.map              |  25 +
> > > > > >    tools/lib/thermal/libthermal.pc.template      |  12 +
> > > > > >    tools/lib/thermal/sampling.c                  |  75 +++
> > > > > >    tools/lib/thermal/thermal.c                   | 126 ++++
> > > > > >    tools/lib/thermal/thermal_nl.c                | 215
> > > > > > +++++++
> > > > > >    tools/lib/thermal/thermal_nl.h                |  46 ++
> > > > > >    tools/thermal/lib/Build                       |   3 +
> > > > > >    tools/thermal/lib/Makefile                    | 158 +++++
> > > > > >    .../thermal/lib/libthermal_tools.pc.template  |  12 +
> > > > > >    tools/thermal/lib/log.c                       |  77 +++
> > > > > >    tools/thermal/lib/log.h                       |  31 +
> > > > > >    tools/thermal/lib/mainloop.c                  | 120 ++++
> > > > > >    tools/thermal/lib/mainloop.h                  |  15 +
> > > > > >    tools/thermal/lib/thermal-tools.h             |  10 +
> > > > > >    tools/thermal/lib/uptimeofday.c               |  40 ++
> > > > > >    tools/thermal/lib/uptimeofday.h               |  12 +
> > > > > >    tools/thermal/thermal-engine/Build            |   2 +
> > > > > >    tools/thermal/thermal-engine/Makefile         |  28 +
> > > > > >    tools/thermal/thermal-engine/thermal-engine.c | 326
> > > > > > ++++++++++
> > > > > >    tools/thermal/thermometer/Build               |   2 +
> > > > > >    tools/thermal/thermometer/Makefile            |  26 +
> > > > > >    tools/thermal/thermometer/thermometer.8       |  93 +++
> > > > > >    tools/thermal/thermometer/thermometer.c       | 558
> > > > > > ++++++++++++++++++
> > > > > >    tools/thermal/thermometer/thermometer.conf    |   5 +
> > > > > >    32 files changed, 2878 insertions(+), 3 deletions(-)
> > > > > >    create mode 100644 tools/lib/thermal/.gitignore
> > > > > >    create mode 100644 tools/lib/thermal/Build
> > > > > >    create mode 100644 tools/lib/thermal/Makefile
> > > > > >    create mode 100644 tools/lib/thermal/commands.c
> > > > > >    create mode 100644 tools/lib/thermal/events.c
> > > > > >    create mode 100644 tools/lib/thermal/include/thermal.h
> > > > > >    create mode 100644 tools/lib/thermal/libthermal.map
> > > > > >    create mode 100644
> > > > > > tools/lib/thermal/libthermal.pc.template
> > > > > >    create mode 100644 tools/lib/thermal/sampling.c
> > > > > >    create mode 100644 tools/lib/thermal/thermal.c
> > > > > >    create mode 100644 tools/lib/thermal/thermal_nl.c
> > > > > >    create mode 100644 tools/lib/thermal/thermal_nl.h
> > > > > >    create mode 100644 tools/thermal/lib/Build
> > > > > >    create mode 100644 tools/thermal/lib/Makefile
> > > > > >    create mode 100644
> > > > > > tools/thermal/lib/libthermal_tools.pc.template
> > > > > >    create mode 100644 tools/thermal/lib/log.c
> > > > > >    create mode 100644 tools/thermal/lib/log.h
> > > > > >    create mode 100644 tools/thermal/lib/mainloop.c
> > > > > >    create mode 100644 tools/thermal/lib/mainloop.h
> > > > > >    create mode 100644 tools/thermal/lib/thermal-tools.h
> > > > > >    create mode 100644 tools/thermal/lib/uptimeofday.c
> > > > > >    create mode 100644 tools/thermal/lib/uptimeofday.h
> > > > > >    create mode 100644 tools/thermal/thermal-engine/Build
> > > > > >    create mode 100644 tools/thermal/thermal-engine/Makefile
> > > > > >    create mode 100644 tools/thermal/thermal-engine/thermal-
> > > > > > engine.c
> > > > > >    create mode 100644 tools/thermal/thermometer/Build
> > > > > >    create mode 100644 tools/thermal/thermometer/Makefile
> > > > > >    create mode 100644 tools/thermal/thermometer/thermometer.8
> > > > > >    create mode 100644 tools/thermal/thermometer/thermometer.c
> > > > > >    create mode 100644
> > > > > > tools/thermal/thermometer/thermometer.conf
> > > > > > 
> > > > > 
> > > > > 
> > > > 
> > > > 
> > > 
> > > 
> > > --
> > > <http://www.linaro.org/> Linaro.org │ Open source software for ARM
> > > SoCs
> > > 
> > > Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
> > > <http://twitter.com/#!/linaroorg> Twitter |
> > > <http://www.linaro.org/linaro-blog/> Blog
> 
> 



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-16  3:50           ` srinivas pandruvada
@ 2022-04-16  7:55             ` Daniel Lezcano
  2022-04-17  4:23               ` srinivas pandruvada
  0 siblings, 1 reply; 19+ messages in thread
From: Daniel Lezcano @ 2022-04-16  7:55 UTC (permalink / raw)
  To: srinivas pandruvada, Rafael J. Wysocki
  Cc: Linux Kernel Mailing List, Linux PM


Hi Srinivas,


On 16/04/2022 05:50, srinivas pandruvada wrote:
> On Wed, 2022-04-13 at 10:21 -0700, srinivas pandruvada wrote:
>> On Wed, 2022-04-13 at 17:06 +0200, Rafael J. Wysocki wrote:
>>> On Wed, Apr 6, 2022 at 4:44 PM Daniel Lezcano <
>>> daniel.lezcano@linaro.org> wrote:
>>>>
>>>> On 06/04/2022 16:28, srinivas pandruvada wrote:
>>>>> Hi Daniel,
>>>>>
>>>>> On Wed, 2022-04-06 at 10:00 +0200, Daniel Lezcano wrote:
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> if there is no comment for the series, shall I pick it so we
>>>>>> can go
>>>>>> forward ?
>>>>> Didn't get time to check yet. It will still be for the next merge
>>>>> window, correct?
>>>>
>>>> Right, but I would like to continue adding more features, scripts
>>>> and
>>>> tests. Iteratively.
>>>
>>> Srinivas, if you can give this a go, please, it will help.
>>>
>>> Otherwise, I think that all of your comments so far have been
>>> addressed, or have I missed anything?
>>>
>> I will provide by the end of this week.
> 
> 1. Some warnings in applying patch
> 
> Applying: tools/lib/thermal: Add a thermal library
> Applying: tools/thermal: Add util library
> Applying: tools/thermal: A temperature capture tool
> .git/rebase-apply/patch:795: space before tab in indent.
> 	      	polling = 100; }
> .git/rebase-apply/patch:90: new blank line at EOF.
> +
> .git/rebase-apply/patch:221: new blank line at EOF.
> +
> warning: 3 lines add whitespace errors.
> Applying: tools/thermal: Add thermal daemon skeleton
> .git/rebase-apply/patch:86: new blank line at EOF.
> +
> warning: 1 line adds whitespace errors.

Strange, I did not have those but I'll try to reproduce

> 2. Thermometer is fine
> 
> 3. segfault for thermal-engine
> 
> LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH ./thermal-
> engine
> Segmentation fault (core dumped)
> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
> engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> ./thermal-engine --help
> thermal-engine : A thermal monitoring engine based on notifications
> Usage: thermal-engine [options]
> 	-h, --help		this help
> 	-d, --daemonize	capture duration
> 	-l <level>, --loglevel <level>	log level: DEBUG, INFO,
> NOTICE, WARN, ERROR
> 	-s, --syslog		output to syslog
> 
> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
> engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> ./thermal-engine -l DEBUG
> Segmentation fault (core dumped)
> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
> engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> ./thermal-engine --loglevel DEBUG
> Segmentation fault (core dumped)
> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
> engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> ./thermal-engine -s
> Segmentation fault (core dumped)

Is CONFIG_THERMAL_NETLINK set ?



-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-16  7:55             ` Daniel Lezcano
@ 2022-04-17  4:23               ` srinivas pandruvada
  2022-04-17  8:20                 ` Daniel Lezcano
  0 siblings, 1 reply; 19+ messages in thread
From: srinivas pandruvada @ 2022-04-17  4:23 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki; +Cc: Linux Kernel Mailing List, Linux PM

Hi Daniel,

On Sat, 2022-04-16 at 09:55 +0200, Daniel Lezcano wrote:
> 
> Hi Srinivas,
> 
> 
> On 16/04/2022 05:50, srinivas pandruvada wrote:
> > On Wed, 2022-04-13 at 10:21 -0700, srinivas pandruvada wrote:
> > > On Wed, 2022-04-13 at 17:06 +0200, Rafael J. Wysocki wrote:
> > > > On Wed, Apr 6, 2022 at 4:44 PM Daniel Lezcano <
> > > > daniel.lezcano@linaro.org> wrote:
> > > > > 
> > 

[...]

> > root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
> > engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> > ./thermal-engine -l DEBUG
> > Segmentation fault (core dumped)
> > root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
> > engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> > ./thermal-engine --loglevel DEBUG
> > Segmentation fault (core dumped)
> > root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
> > engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> > ./thermal-engine -s
> > Segmentation fault (core dumped)
> 
> Is CONFIG_THERMAL_NETLINK set ?

Yes, Thermometer program works fine. Just thermal-engine fails.
CONFIG_THERMAL=y
CONFIG_THERMAL_NETLINK=y
CONFIG_THERMAL_STATISTICS=y
CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
CONFIG_THERMAL_HWMON=y
CONFIG_THERMAL_WRITABLE_TRIPS=y
CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
# CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
# CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_THERMAL_GOV_STEP_WISE=y
CONFIG_THERMAL_GOV_BANG_BANG=y
CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_DEVFREQ_THERMAL=y
CONFIG_THERMAL_EMULATION=y

This may help

#gdb ./thermal-engine 
GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show
copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./thermal-engine...(no debugging symbols
found)...done.
(gdb) run
Starting program:
/home/labuser/development/linux/tools/thermal/thermal-engine/thermal-
engine 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-
gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
tz=0x555555607898) at commands.c:143
143		__tt[size].id = -1;
(gdb) backtrace 
#0  0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
tz=0x555555607898) at commands.c:143
#1  0x00007ffff7402233 in handle_netlink (unused=0x0,
cmd=0x7ffff76052f8 <thermal_cmds+120>, info=0x7fffffffdf60,
arg=0x555555607898) at commands.c:206
#2  0x00007ffff7003435 in ?? () from /lib/x86_64-linux-gnu/libnl-genl-
3.so.200
#3  0x00007ffff6810c1c in nl_recvmsgs_report () from /lib/x86_64-linux-
gnu/libnl-3.so.200
#4  0x00007ffff6811049 in nl_recvmsgs () from /lib/x86_64-linux-
gnu/libnl-3.so.200
#5  0x00007ffff7402eaf in nl_send_msg (sock=0x555555606040,
cb=0x5555556065d0, msg=0x555555606110, rx_handler=0x7ffff70036f0
<genl_handle_msg>, data=0x555555607898) at thermal_nl.c:70
#6  0x00007ffff7402327 in thermal_genl_auto (th=0x5555556048a0, id=1,
cmd=2, flags=0, arg=0x555555607898) at commands.c:282
#7  0x00007ffff74023e0 in thermal_cmd_get_trip (th=0x5555556048a0,
tz=0x555555607898) at commands.c:304
#8  0x00007ffff74039db in __thermal_zone_discover (tz=0x555555607898,
th=0x5555556048a0) at thermal.c:71
#9  0x00007ffff7403842 in for_each_thermal_zone (tz=0x555555607860,
cb=0x7ffff74039b8 <__thermal_zone_discover>, arg=0x5555556048a0) at
thermal.c:33
#10 0x00007ffff7403a5b in thermal_zone_discover (th=0x5555556048a0) at
thermal.c:87
#11 0x00005555554019bd in main ()

Thanks,
Srinivas

> 



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-17  4:23               ` srinivas pandruvada
@ 2022-04-17  8:20                 ` Daniel Lezcano
  2022-04-18  3:36                   ` srinivas pandruvada
  0 siblings, 1 reply; 19+ messages in thread
From: Daniel Lezcano @ 2022-04-17  8:20 UTC (permalink / raw)
  To: srinivas pandruvada, Rafael J. Wysocki
  Cc: Linux Kernel Mailing List, Linux PM


Hi Srinivas,

thanks for the information. I've indeed not tested on x86_64 but on ARM64.

I'll give a try to reproduce and fix the issue.

Thanks again for taking the time to run it

   -- Daniel

On 17/04/2022 06:23, srinivas pandruvada wrote:
> Hi Daniel,
> 
> On Sat, 2022-04-16 at 09:55 +0200, Daniel Lezcano wrote:
>>
>> Hi Srinivas,
>>
>>
>> On 16/04/2022 05:50, srinivas pandruvada wrote:
>>> On Wed, 2022-04-13 at 10:21 -0700, srinivas pandruvada wrote:
>>>> On Wed, 2022-04-13 at 17:06 +0200, Rafael J. Wysocki wrote:
>>>>> On Wed, Apr 6, 2022 at 4:44 PM Daniel Lezcano <
>>>>> daniel.lezcano@linaro.org> wrote:
>>>>>>
>>>
> 
> [...]
> 
>>> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
>>> engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
>>> ./thermal-engine -l DEBUG
>>> Segmentation fault (core dumped)
>>> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
>>> engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
>>> ./thermal-engine --loglevel DEBUG
>>> Segmentation fault (core dumped)
>>> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/thermal-
>>> engine# LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
>>> ./thermal-engine -s
>>> Segmentation fault (core dumped)
>>
>> Is CONFIG_THERMAL_NETLINK set ?
> 
> Yes, Thermometer program works fine. Just thermal-engine fails.
> CONFIG_THERMAL=y
> CONFIG_THERMAL_NETLINK=y
> CONFIG_THERMAL_STATISTICS=y
> CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
> CONFIG_THERMAL_HWMON=y
> CONFIG_THERMAL_WRITABLE_TRIPS=y
> CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
> # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
> # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
> CONFIG_THERMAL_GOV_FAIR_SHARE=y
> CONFIG_THERMAL_GOV_STEP_WISE=y
> CONFIG_THERMAL_GOV_BANG_BANG=y
> CONFIG_THERMAL_GOV_USER_SPACE=y
> CONFIG_DEVFREQ_THERMAL=y
> CONFIG_THERMAL_EMULATION=y
> 
> This may help
> 
> #gdb ./thermal-engine
> GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
> Copyright (C) 2018 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later
> <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.  Type "show
> copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-linux-gnu".
> Type "show configuration" for configuration details.
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>.
> Find the GDB manual and other documentation resources online at:
> <http://www.gnu.org/software/gdb/documentation/>.
> For help, type "help".
> Type "apropos word" to search for commands related to "word"...
> Reading symbols from ./thermal-engine...(no debugging symbols
> found)...done.
> (gdb) run
> Starting program:
> /home/labuser/development/linux/tools/thermal/thermal-engine/thermal-
> engine
> [Thread debugging using libthread_db enabled]
> Using host libthread_db library "/lib/x86_64-linux-
> gnu/libthread_db.so.1".
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
> tz=0x555555607898) at commands.c:143
> 143		__tt[size].id = -1;
> (gdb) backtrace
> #0  0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
> tz=0x555555607898) at commands.c:143
> #1  0x00007ffff7402233 in handle_netlink (unused=0x0,
> cmd=0x7ffff76052f8 <thermal_cmds+120>, info=0x7fffffffdf60,
> arg=0x555555607898) at commands.c:206
> #2  0x00007ffff7003435 in ?? () from /lib/x86_64-linux-gnu/libnl-genl-
> 3.so.200
> #3  0x00007ffff6810c1c in nl_recvmsgs_report () from /lib/x86_64-linux-
> gnu/libnl-3.so.200
> #4  0x00007ffff6811049 in nl_recvmsgs () from /lib/x86_64-linux-
> gnu/libnl-3.so.200
> #5  0x00007ffff7402eaf in nl_send_msg (sock=0x555555606040,
> cb=0x5555556065d0, msg=0x555555606110, rx_handler=0x7ffff70036f0
> <genl_handle_msg>, data=0x555555607898) at thermal_nl.c:70
> #6  0x00007ffff7402327 in thermal_genl_auto (th=0x5555556048a0, id=1,
> cmd=2, flags=0, arg=0x555555607898) at commands.c:282
> #7  0x00007ffff74023e0 in thermal_cmd_get_trip (th=0x5555556048a0,
> tz=0x555555607898) at commands.c:304
> #8  0x00007ffff74039db in __thermal_zone_discover (tz=0x555555607898,
> th=0x5555556048a0) at thermal.c:71
> #9  0x00007ffff7403842 in for_each_thermal_zone (tz=0x555555607860,
> cb=0x7ffff74039b8 <__thermal_zone_discover>, arg=0x5555556048a0) at
> thermal.c:33
> #10 0x00007ffff7403a5b in thermal_zone_discover (th=0x5555556048a0) at
> thermal.c:87
> #11 0x00005555554019bd in main ()
> 
> Thanks,
> Srinivas
> 
>>
> 
> 


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-17  8:20                 ` Daniel Lezcano
@ 2022-04-18  3:36                   ` srinivas pandruvada
  2022-04-18  3:38                     ` srinivas pandruvada
                                       ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: srinivas pandruvada @ 2022-04-18  3:36 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki; +Cc: Linux Kernel Mailing List, Linux PM

[-- Attachment #1: Type: text/plain, Size: 5296 bytes --]

Hi Daniel,

The attached diff fixes the crash,

Also when you run in daemon mode, you need to use some pid lock file.
Otherwise it launches multiple daemons.

Thanks,
Srinivas



On Sun, 2022-04-17 at 10:20 +0200, Daniel Lezcano wrote:
> 
> Hi Srinivas,
> 
> thanks for the information. I've indeed not tested on x86_64 but on
> ARM64.
> 
> I'll give a try to reproduce and fix the issue.
> 
> Thanks again for taking the time to run it
> 
>    -- Daniel
> 
> On 17/04/2022 06:23, srinivas pandruvada wrote:
> > Hi Daniel,
> > 
> > On Sat, 2022-04-16 at 09:55 +0200, Daniel Lezcano wrote:
> > > 
> > > Hi Srinivas,
> > > 
> > > 
> > > On 16/04/2022 05:50, srinivas pandruvada wrote:
> > > > On Wed, 2022-04-13 at 10:21 -0700, srinivas pandruvada wrote:
> > > > > On Wed, 2022-04-13 at 17:06 +0200, Rafael J. Wysocki wrote:
> > > > > > On Wed, Apr 6, 2022 at 4:44 PM Daniel Lezcano <
> > > > > > daniel.lezcano@linaro.org> wrote:
> > > > > > > 
> > > > 
> > 
> > [...]
> > 
> > > > root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/the
> > > > rmal-
> > > > engine#
> > > > LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> > > > ./thermal-engine -l DEBUG
> > > > Segmentation fault (core dumped)
> > > > root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/the
> > > > rmal-
> > > > engine#
> > > > LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> > > > ./thermal-engine --loglevel DEBUG
> > > > Segmentation fault (core dumped)
> > > > root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/the
> > > > rmal-
> > > > engine#
> > > > LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> > > > ./thermal-engine -s
> > > > Segmentation fault (core dumped)
> > > 
> > > Is CONFIG_THERMAL_NETLINK set ?
> > 
> > Yes, Thermometer program works fine. Just thermal-engine fails.
> > CONFIG_THERMAL=y
> > CONFIG_THERMAL_NETLINK=y
> > CONFIG_THERMAL_STATISTICS=y
> > CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
> > CONFIG_THERMAL_HWMON=y
> > CONFIG_THERMAL_WRITABLE_TRIPS=y
> > CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
> > # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
> > # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
> > CONFIG_THERMAL_GOV_FAIR_SHARE=y
> > CONFIG_THERMAL_GOV_STEP_WISE=y
> > CONFIG_THERMAL_GOV_BANG_BANG=y
> > CONFIG_THERMAL_GOV_USER_SPACE=y
> > CONFIG_DEVFREQ_THERMAL=y
> > CONFIG_THERMAL_EMULATION=y
> > 
> > This may help
> > 
> > #gdb ./thermal-engine
> > GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
> > Copyright (C) 2018 Free Software Foundation, Inc.
> > License GPLv3+: GNU GPL version 3 or later
> > <http://gnu.org/licenses/gpl.html>
> > This is free software: you are free to change and redistribute it.
> > There is NO WARRANTY, to the extent permitted by law.  Type "show
> > copying"
> > and "show warranty" for details.
> > This GDB was configured as "x86_64-linux-gnu".
> > Type "show configuration" for configuration details.
> > For bug reporting instructions, please see:
> > <http://www.gnu.org/software/gdb/bugs/>.
> > Find the GDB manual and other documentation resources online at:
> > <http://www.gnu.org/software/gdb/documentation/>.
> > For help, type "help".
> > Type "apropos word" to search for commands related to "word"...
> > Reading symbols from ./thermal-engine...(no debugging symbols
> > found)...done.
> > (gdb) run
> > Starting program:
> > /home/labuser/development/linux/tools/thermal/thermal-
> > engine/thermal-
> > engine
> > [Thread debugging using libthread_db enabled]
> > Using host libthread_db library "/lib/x86_64-linux-
> > gnu/libthread_db.so.1".
> > 
> > Program received signal SIGSEGV, Segmentation fault.
> > 0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
> > tz=0x555555607898) at commands.c:143
> > 143             __tt[size].id = -1;
> > (gdb) backtrace
> > #0  0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
> > tz=0x555555607898) at commands.c:143
> > #1  0x00007ffff7402233 in handle_netlink (unused=0x0,
> > cmd=0x7ffff76052f8 <thermal_cmds+120>, info=0x7fffffffdf60,
> > arg=0x555555607898) at commands.c:206
> > #2  0x00007ffff7003435 in ?? () from /lib/x86_64-linux-gnu/libnl-
> > genl-
> > 3.so.200
> > #3  0x00007ffff6810c1c in nl_recvmsgs_report () from /lib/x86_64-
> > linux-
> > gnu/libnl-3.so.200
> > #4  0x00007ffff6811049 in nl_recvmsgs () from /lib/x86_64-linux-
> > gnu/libnl-3.so.200
> > #5  0x00007ffff7402eaf in nl_send_msg (sock=0x555555606040,
> > cb=0x5555556065d0, msg=0x555555606110, rx_handler=0x7ffff70036f0
> > <genl_handle_msg>, data=0x555555607898) at thermal_nl.c:70
> > #6  0x00007ffff7402327 in thermal_genl_auto (th=0x5555556048a0,
> > id=1,
> > cmd=2, flags=0, arg=0x555555607898) at commands.c:282
> > #7  0x00007ffff74023e0 in thermal_cmd_get_trip (th=0x5555556048a0,
> > tz=0x555555607898) at commands.c:304
> > #8  0x00007ffff74039db in __thermal_zone_discover
> > (tz=0x555555607898,
> > th=0x5555556048a0) at thermal.c:71
> > #9  0x00007ffff7403842 in for_each_thermal_zone (tz=0x555555607860,
> > cb=0x7ffff74039b8 <__thermal_zone_discover>, arg=0x5555556048a0) at
> > thermal.c:33
> > #10 0x00007ffff7403a5b in thermal_zone_discover (th=0x5555556048a0)
> > at
> > thermal.c:87
> > #11 0x00005555554019bd in main ()
> > 
> > Thanks,
> > Srinivas
> > 
> > > 
> > 
> > 
> 
> 


[-- Attachment #2: segv.diff --]
[-- Type: text/x-patch, Size: 2642 bytes --]

git diff
diff --git a/tools/lib/thermal/commands.c b/tools/lib/thermal/commands.c
index 539083780107..b8d933f19909 100644
--- a/tools/lib/thermal/commands.c
+++ b/tools/lib/thermal/commands.c
@@ -117,6 +117,8 @@ static int parse_tz_get_trip(struct genl_info *info, struct thermal_zone *tz)
        size_t size = 0;
        int rem;
 
+       tz->trip_count = 0;
+
        nla_for_each_nested(attr, info->attrs[THERMAL_GENL_ATTR_TZ_TRIP], rem) {
 
                if (nla_type(attr) == THERMAL_GENL_ATTR_TZ_TRIP_ID) {
@@ -140,10 +142,15 @@ static int parse_tz_get_trip(struct genl_info *info, struct thermal_zone *tz)
                        __tt[size - 1].hyst = nla_get_u32(attr);
        }
 
+       if (!size)
+               return THERMAL_ERROR;
+
        __tt[size].id = -1;
 
        tz->trip = __tt;
 
+       tz->trip_count = size;
+
        return THERMAL_SUCCESS;
 }
 
diff --git a/tools/lib/thermal/include/thermal.h b/tools/lib/thermal/include/thermal.h
index 1abc560602cf..5cb9ba8c6c0e 100644
--- a/tools/lib/thermal/include/thermal.h
+++ b/tools/lib/thermal/include/thermal.h
@@ -51,6 +51,7 @@ struct thermal_zone {
        char name[THERMAL_NAME_LENGTH];
        char governor[THERMAL_NAME_LENGTH];
        struct thermal_trip *trip;
+       int trip_count;
 };
 
 struct thermal_cdev {
diff --git a/tools/lib/thermal/thermal.c b/tools/lib/thermal/thermal.c
index a80b967ce334..dd4ebfbbf1d0 100644
--- a/tools/lib/thermal/thermal.c
+++ b/tools/lib/thermal/thermal.c
@@ -19,7 +19,10 @@ int for_each_thermal_trip(struct thermal_trip *tt, cb_tt_t cb, void *arg)
 {
        int i, ret = 0;
 
-       for (i = 0; tt[i].id != -1; i++)
+       if (!tt)
+               return -1;
+
+       for (i = 0; &tt[i] && tt[i].id != -1; i++)
                ret |= cb(&tt[i], arg);
 
        return ret;
@@ -29,6 +32,9 @@ int for_each_thermal_zone(struct thermal_zone *tz, cb_tz_t cb, void *arg)
 {
        int i, ret = 0;
 
+       if (!tz)
+               return 0;
+
        for (i = 0; tz[i].id != -1; i++)
                ret |= cb(&tz[i], arg);
 
diff --git a/tools/thermal/thermal-engine/thermal-engine.c b/tools/thermal/thermal-engine/thermal-engine.c
index 525520049aa2..4e446aec22b5 100644
--- a/tools/thermal/thermal-engine/thermal-engine.c
+++ b/tools/thermal/thermal-engine/thermal-engine.c
@@ -68,7 +68,8 @@ static int show_tz(struct thermal_zone *tz, __maybe_unused void *arg)
 {
        INFO("thermal zone '%s', id=%d\n", tz->name, tz->id);
 
-       for_each_thermal_trip(tz->trip, show_trip, NULL);
+       if (tz->trip_count)
+               for_each_thermal_trip(tz->trip, show_trip, NULL);
 
        show_temp(tz, arg);


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-18  3:36                   ` srinivas pandruvada
@ 2022-04-18  3:38                     ` srinivas pandruvada
  2022-04-18  7:46                     ` Daniel Lezcano
  2022-04-19 20:26                     ` Daniel Lezcano
  2 siblings, 0 replies; 19+ messages in thread
From: srinivas pandruvada @ 2022-04-18  3:38 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki; +Cc: Linux Kernel Mailing List, Linux PM

On Sun, 2022-04-17 at 20:36 -0700, srinivas pandruvada wrote:
> Hi Daniel,
> 
> The attached diff fixes the crash,
> 
> Also when you run in daemon mode, you need to use some pid lock file.
> Otherwise it launches multiple daemons.
> 
With the diff
./thermal-engine 
thermal zone 'acpitz', id=0
trip id=0, type=3, temp=119000, hyst=0
trip id=1, type=0, temp=71000, hyst=0
trip id=2, type=0, temp=55000, hyst=0
trip id=3, type=0, temp=50000, hyst=0
trip id=4, type=0, temp=45000, hyst=0
trip id=5, type=0, temp=40000, hyst=0
temperature: 25000
governor: 'step_wise'
thermal zone 'INT3400 Thermal', id=1
temperature: 20000
governor: 'user_space'
thermal zone 'B0D4', id=2
trip id=0, type=3, temp=110050, hyst=0
trip id=1, type=2, temp=110050, hyst=0
trip id=2, type=1, temp=110050, hyst=0
trip id=3, type=0, temp=90050, hyst=0
trip id=4, type=0, temp=85050, hyst=0
trip id=5, type=0, temp=80050, hyst=0
trip id=6, type=0, temp=75050, hyst=0
trip id=7, type=0, temp=70050, hyst=0
temperature: 26050
governor: 'user_space'
thermal zone 'x86_pkg_temp', id=3
trip id=0, type=1, temp=-274000, hyst=0
trip id=1, type=1, temp=-274000, hyst=0
temperature: 26000
governor: 'step_wise'
Waiting for thermal events ...

> Thanks,
> Srinivas
> 
> 
> 
> On Sun, 2022-04-17 at 10:20 +0200, Daniel Lezcano wrote:
> > 
> > Hi Srinivas,
> > 
> > thanks for the information. I've indeed not tested on x86_64 but on
> > ARM64.
> > 
> > I'll give a try to reproduce and fix the issue.
> > 
> > Thanks again for taking the time to run it
> > 
> >    -- Daniel
> > 
> > On 17/04/2022 06:23, srinivas pandruvada wrote:
> > > Hi Daniel,
> > > 
> > > On Sat, 2022-04-16 at 09:55 +0200, Daniel Lezcano wrote:
> > > > 
> > > > Hi Srinivas,
> > > > 
> > > > 
> > > > On 16/04/2022 05:50, srinivas pandruvada wrote:
> > > > > On Wed, 2022-04-13 at 10:21 -0700, srinivas pandruvada wrote:
> > > > > > On Wed, 2022-04-13 at 17:06 +0200, Rafael J. Wysocki wrote:
> > > > > > > On Wed, Apr 6, 2022 at 4:44 PM Daniel Lezcano <
> > > > > > > daniel.lezcano@linaro.org> wrote:
> > > > > > > > 
> > > > > 
> > > 
> > > [...]
> > > 
> > > > > root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/the
> > > > > rmal-
> > > > > engine#
> > > > > LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> > > > > ./thermal-engine -l DEBUG
> > > > > Segmentation fault (core dumped)
> > > > > root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/the
> > > > > rmal-
> > > > > engine#
> > > > > LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> > > > > ./thermal-engine --loglevel DEBUG
> > > > > Segmentation fault (core dumped)
> > > > > root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/the
> > > > > rmal-
> > > > > engine#
> > > > > LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
> > > > > ./thermal-engine -s
> > > > > Segmentation fault (core dumped)
> > > > 
> > > > Is CONFIG_THERMAL_NETLINK set ?
> > > 
> > > Yes, Thermometer program works fine. Just thermal-engine fails.
> > > CONFIG_THERMAL=y
> > > CONFIG_THERMAL_NETLINK=y
> > > CONFIG_THERMAL_STATISTICS=y
> > > CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
> > > CONFIG_THERMAL_HWMON=y
> > > CONFIG_THERMAL_WRITABLE_TRIPS=y
> > > CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
> > > # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
> > > # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
> > > CONFIG_THERMAL_GOV_FAIR_SHARE=y
> > > CONFIG_THERMAL_GOV_STEP_WISE=y
> > > CONFIG_THERMAL_GOV_BANG_BANG=y
> > > CONFIG_THERMAL_GOV_USER_SPACE=y
> > > CONFIG_DEVFREQ_THERMAL=y
> > > CONFIG_THERMAL_EMULATION=y
> > > 
> > > This may help
> > > 
> > > #gdb ./thermal-engine
> > > GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
> > > Copyright (C) 2018 Free Software Foundation, Inc.
> > > License GPLv3+: GNU GPL version 3 or later
> > > <http://gnu.org/licenses/gpl.html>
> > > This is free software: you are free to change and redistribute it.
> > > There is NO WARRANTY, to the extent permitted by law.  Type "show
> > > copying"
> > > and "show warranty" for details.
> > > This GDB was configured as "x86_64-linux-gnu".
> > > Type "show configuration" for configuration details.
> > > For bug reporting instructions, please see:
> > > <http://www.gnu.org/software/gdb/bugs/>.
> > > Find the GDB manual and other documentation resources online at:
> > > <http://www.gnu.org/software/gdb/documentation/>.
> > > For help, type "help".
> > > Type "apropos word" to search for commands related to "word"...
> > > Reading symbols from ./thermal-engine...(no debugging symbols
> > > found)...done.
> > > (gdb) run
> > > Starting program:
> > > /home/labuser/development/linux/tools/thermal/thermal-
> > > engine/thermal-
> > > engine
> > > [Thread debugging using libthread_db enabled]
> > > Using host libthread_db library "/lib/x86_64-linux-
> > > gnu/libthread_db.so.1".
> > > 
> > > Program received signal SIGSEGV, Segmentation fault.
> > > 0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
> > > tz=0x555555607898) at commands.c:143
> > > 143             __tt[size].id = -1;
> > > (gdb) backtrace
> > > #0  0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
> > > tz=0x555555607898) at commands.c:143
> > > #1  0x00007ffff7402233 in handle_netlink (unused=0x0,
> > > cmd=0x7ffff76052f8 <thermal_cmds+120>, info=0x7fffffffdf60,
> > > arg=0x555555607898) at commands.c:206
> > > #2  0x00007ffff7003435 in ?? () from /lib/x86_64-linux-gnu/libnl-
> > > genl-
> > > 3.so.200
> > > #3  0x00007ffff6810c1c in nl_recvmsgs_report () from /lib/x86_64-
> > > linux-
> > > gnu/libnl-3.so.200
> > > #4  0x00007ffff6811049 in nl_recvmsgs () from /lib/x86_64-linux-
> > > gnu/libnl-3.so.200
> > > #5  0x00007ffff7402eaf in nl_send_msg (sock=0x555555606040,
> > > cb=0x5555556065d0, msg=0x555555606110, rx_handler=0x7ffff70036f0
> > > <genl_handle_msg>, data=0x555555607898) at thermal_nl.c:70
> > > #6  0x00007ffff7402327 in thermal_genl_auto (th=0x5555556048a0,
> > > id=1,
> > > cmd=2, flags=0, arg=0x555555607898) at commands.c:282
> > > #7  0x00007ffff74023e0 in thermal_cmd_get_trip (th=0x5555556048a0,
> > > tz=0x555555607898) at commands.c:304
> > > #8  0x00007ffff74039db in __thermal_zone_discover
> > > (tz=0x555555607898,
> > > th=0x5555556048a0) at thermal.c:71
> > > #9  0x00007ffff7403842 in for_each_thermal_zone (tz=0x555555607860,
> > > cb=0x7ffff74039b8 <__thermal_zone_discover>, arg=0x5555556048a0) at
> > > thermal.c:33
> > > #10 0x00007ffff7403a5b in thermal_zone_discover (th=0x5555556048a0)
> > > at
> > > thermal.c:87
> > > #11 0x00005555554019bd in main ()
> > > 
> > > Thanks,
> > > Srinivas
> > > 
> > > > 
> > > 
> > > 
> > 
> > 
> 



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-18  3:36                   ` srinivas pandruvada
  2022-04-18  3:38                     ` srinivas pandruvada
@ 2022-04-18  7:46                     ` Daniel Lezcano
  2022-04-19 20:26                     ` Daniel Lezcano
  2 siblings, 0 replies; 19+ messages in thread
From: Daniel Lezcano @ 2022-04-18  7:46 UTC (permalink / raw)
  To: srinivas pandruvada, Rafael J. Wysocki
  Cc: Linux Kernel Mailing List, Linux PM


Hi Srinivas,

thanks for the fix !

On 18/04/2022 05:36, srinivas pandruvada wrote:
> Hi Daniel,
> 
> The attached diff fixes the crash,
> 
> Also when you run in daemon mode, you need to use some pid lock file.
> Otherwise it launches multiple daemons.

Thanks for the feedback, I'll add it

   -- Daniel

> 
> On Sun, 2022-04-17 at 10:20 +0200, Daniel Lezcano wrote:
>>
>> Hi Srinivas,
>>
>> thanks for the information. I've indeed not tested on x86_64 but on
>> ARM64.
>>
>> I'll give a try to reproduce and fix the issue.
>>
>> Thanks again for taking the time to run it
>>
>>     -- Daniel
>>
>> On 17/04/2022 06:23, srinivas pandruvada wrote:
>>> Hi Daniel,
>>>
>>> On Sat, 2022-04-16 at 09:55 +0200, Daniel Lezcano wrote:
>>>>
>>>> Hi Srinivas,
>>>>
>>>>
>>>> On 16/04/2022 05:50, srinivas pandruvada wrote:
>>>>> On Wed, 2022-04-13 at 10:21 -0700, srinivas pandruvada wrote:
>>>>>> On Wed, 2022-04-13 at 17:06 +0200, Rafael J. Wysocki wrote:
>>>>>>> On Wed, Apr 6, 2022 at 4:44 PM Daniel Lezcano <
>>>>>>> daniel.lezcano@linaro.org> wrote:
>>>>>>>>
>>>>>
>>>
>>> [...]
>>>
>>>>> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/the
>>>>> rmal-
>>>>> engine#
>>>>> LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
>>>>> ./thermal-engine -l DEBUG
>>>>> Segmentation fault (core dumped)
>>>>> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/the
>>>>> rmal-
>>>>> engine#
>>>>> LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
>>>>> ./thermal-engine --loglevel DEBUG
>>>>> Segmentation fault (core dumped)
>>>>> root@srinivas-otcpl-icl-u:~/development/linux/tools/thermal/the
>>>>> rmal-
>>>>> engine#
>>>>> LD_LIBRARY_PATH=../lib:../../lib/thermal:$LD_LIBRARY_pATH
>>>>> ./thermal-engine -s
>>>>> Segmentation fault (core dumped)
>>>>
>>>> Is CONFIG_THERMAL_NETLINK set ?
>>>
>>> Yes, Thermometer program works fine. Just thermal-engine fails.
>>> CONFIG_THERMAL=y
>>> CONFIG_THERMAL_NETLINK=y
>>> CONFIG_THERMAL_STATISTICS=y
>>> CONFIG_THERMAL_EMERGENCY_POWEROFF_DELAY_MS=0
>>> CONFIG_THERMAL_HWMON=y
>>> CONFIG_THERMAL_WRITABLE_TRIPS=y
>>> CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y
>>> # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set
>>> # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set
>>> CONFIG_THERMAL_GOV_FAIR_SHARE=y
>>> CONFIG_THERMAL_GOV_STEP_WISE=y
>>> CONFIG_THERMAL_GOV_BANG_BANG=y
>>> CONFIG_THERMAL_GOV_USER_SPACE=y
>>> CONFIG_DEVFREQ_THERMAL=y
>>> CONFIG_THERMAL_EMULATION=y
>>>
>>> This may help
>>>
>>> #gdb ./thermal-engine
>>> GNU gdb (Ubuntu 8.1.1-0ubuntu1) 8.1.1
>>> Copyright (C) 2018 Free Software Foundation, Inc.
>>> License GPLv3+: GNU GPL version 3 or later
>>> <http://gnu.org/licenses/gpl.html>
>>> This is free software: you are free to change and redistribute it.
>>> There is NO WARRANTY, to the extent permitted by law.  Type "show
>>> copying"
>>> and "show warranty" for details.
>>> This GDB was configured as "x86_64-linux-gnu".
>>> Type "show configuration" for configuration details.
>>> For bug reporting instructions, please see:
>>> <http://www.gnu.org/software/gdb/bugs/>.
>>> Find the GDB manual and other documentation resources online at:
>>> <http://www.gnu.org/software/gdb/documentation/>.
>>> For help, type "help".
>>> Type "apropos word" to search for commands related to "word"...
>>> Reading symbols from ./thermal-engine...(no debugging symbols
>>> found)...done.
>>> (gdb) run
>>> Starting program:
>>> /home/labuser/development/linux/tools/thermal/thermal-
>>> engine/thermal-
>>> engine
>>> [Thread debugging using libthread_db enabled]
>>> Using host libthread_db library "/lib/x86_64-linux-
>>> gnu/libthread_db.so.1".
>>>
>>> Program received signal SIGSEGV, Segmentation fault.
>>> 0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
>>> tz=0x555555607898) at commands.c:143
>>> 143             __tt[size].id = -1;
>>> (gdb) backtrace
>>> #0  0x00007ffff7402036 in parse_tz_get_trip (info=0x7fffffffdf60,
>>> tz=0x555555607898) at commands.c:143
>>> #1  0x00007ffff7402233 in handle_netlink (unused=0x0,
>>> cmd=0x7ffff76052f8 <thermal_cmds+120>, info=0x7fffffffdf60,
>>> arg=0x555555607898) at commands.c:206
>>> #2  0x00007ffff7003435 in ?? () from /lib/x86_64-linux-gnu/libnl-
>>> genl-
>>> 3.so.200
>>> #3  0x00007ffff6810c1c in nl_recvmsgs_report () from /lib/x86_64-
>>> linux-
>>> gnu/libnl-3.so.200
>>> #4  0x00007ffff6811049 in nl_recvmsgs () from /lib/x86_64-linux-
>>> gnu/libnl-3.so.200
>>> #5  0x00007ffff7402eaf in nl_send_msg (sock=0x555555606040,
>>> cb=0x5555556065d0, msg=0x555555606110, rx_handler=0x7ffff70036f0
>>> <genl_handle_msg>, data=0x555555607898) at thermal_nl.c:70
>>> #6  0x00007ffff7402327 in thermal_genl_auto (th=0x5555556048a0,
>>> id=1,
>>> cmd=2, flags=0, arg=0x555555607898) at commands.c:282
>>> #7  0x00007ffff74023e0 in thermal_cmd_get_trip (th=0x5555556048a0,
>>> tz=0x555555607898) at commands.c:304
>>> #8  0x00007ffff74039db in __thermal_zone_discover
>>> (tz=0x555555607898,
>>> th=0x5555556048a0) at thermal.c:71
>>> #9  0x00007ffff7403842 in for_each_thermal_zone (tz=0x555555607860,
>>> cb=0x7ffff74039b8 <__thermal_zone_discover>, arg=0x5555556048a0) at
>>> thermal.c:33
>>> #10 0x00007ffff7403a5b in thermal_zone_discover (th=0x5555556048a0)
>>> at
>>> thermal.c:87
>>> #11 0x00005555554019bd in main ()
>>>
>>> Thanks,
>>> Srinivas
>>>
>>>>
>>>
>>>
>>
>>
> 


-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-18  3:36                   ` srinivas pandruvada
  2022-04-18  3:38                     ` srinivas pandruvada
  2022-04-18  7:46                     ` Daniel Lezcano
@ 2022-04-19 20:26                     ` Daniel Lezcano
  2022-04-20  3:16                       ` srinivas pandruvada
  2 siblings, 1 reply; 19+ messages in thread
From: Daniel Lezcano @ 2022-04-19 20:26 UTC (permalink / raw)
  To: srinivas pandruvada, Rafael J. Wysocki
  Cc: Linux Kernel Mailing List, Linux PM


Hi Srinivas,


On 18/04/2022 05:36, srinivas pandruvada wrote:
> Hi Daniel,
> 
> The attached diff fixes the crash,
> 
> Also when you run in daemon mode, you need to use some pid lock file.
> Otherwise it launches multiple daemons.

I've been thinking about it and I don't think it is a problem to have 
multiple instances of the daemon. The netlink allows multicast and can 
be run as non-root user.

If the finality of the thermal engine is to manage the system and has 
some code making actions on the system with the root privilege, the init 
scripts can take care of the pid lock



-- 
<http://www.linaro.org/> Linaro.org │ Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [PATCH v2 0/4] tools/thermal: thermal library and tools
  2022-04-19 20:26                     ` Daniel Lezcano
@ 2022-04-20  3:16                       ` srinivas pandruvada
  0 siblings, 0 replies; 19+ messages in thread
From: srinivas pandruvada @ 2022-04-20  3:16 UTC (permalink / raw)
  To: Daniel Lezcano, Rafael J. Wysocki; +Cc: Linux Kernel Mailing List, Linux PM

Hi Daniel,

On Tue, 2022-04-19 at 22:26 +0200, Daniel Lezcano wrote:
> 
> Hi Srinivas,
> 
> 
> On 18/04/2022 05:36, srinivas pandruvada wrote:
> > Hi Daniel,
> > 
> > The attached diff fixes the crash,
> > 
> > Also when you run in daemon mode, you need to use some pid lock
> > file.
> > Otherwise it launches multiple daemons.
> 
> I've been thinking about it and I don't think it is a problem to have
> multiple instances of the daemon. The netlink allows multicast and
> can 
> be run as non-root user.
> 
> If the finality of the thermal engine is to manage the system and has
> some code making actions on the system with the root privilege, the
> init 
> scripts can take care of the pid lock
> 
If there is use case, then this is fine otherwise wasting system
resources.

Thanks,
Srinivas





> 
> 



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2022-04-20  3:16 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-30 10:04 [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
2022-03-30 10:04 ` [PATCH v2 1/4] tools/lib/thermal: Add a thermal library Daniel Lezcano
2022-03-30 10:04 ` [PATCH v2 2/4] tools/thermal: Add util library Daniel Lezcano
2022-03-30 10:04 ` [PATCH v2 3/4] tools/thermal: A temperature capture tool Daniel Lezcano
2022-03-30 10:04 ` [PATCH v2 4/4] tools/thermal: Add thermal daemon skeleton Daniel Lezcano
2022-04-06  8:00 ` [PATCH v2 0/4] tools/thermal: thermal library and tools Daniel Lezcano
2022-04-06 14:28   ` srinivas pandruvada
2022-04-06 14:44     ` Daniel Lezcano
2022-04-13 15:06       ` Rafael J. Wysocki
2022-04-13 17:21         ` srinivas pandruvada
2022-04-16  3:50           ` srinivas pandruvada
2022-04-16  7:55             ` Daniel Lezcano
2022-04-17  4:23               ` srinivas pandruvada
2022-04-17  8:20                 ` Daniel Lezcano
2022-04-18  3:36                   ` srinivas pandruvada
2022-04-18  3:38                     ` srinivas pandruvada
2022-04-18  7:46                     ` Daniel Lezcano
2022-04-19 20:26                     ` Daniel Lezcano
2022-04-20  3:16                       ` srinivas pandruvada

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.