Thermal Management (열 관리)
Linux 커널 Thermal 서브시스템은 CPU/GPU/SoC 센서 온도를 기반으로 thermal zone, trip point, cooling map을 구성하고 cooling device를 제어해 과열을 방지합니다. step_wise/fair_share/power_allocator governor의 제어 전략, cpufreq/devfreq·fan·throttle 연동, ACPI·Device Tree·hwmon 통합, 열 한계와 성능 사이의 정책 설계, 운영 환경에서의 throttling 원인 분석과 디버깅 절차를 상세히 다룹니다.
핵심 요약
- Thermal Zone — CPU, GPU 등 온도를 측정하는 하드웨어 영역. 온도 센서와 trip point를 포함합니다.
- Trip Point — 온도 임계값. active, passive, hot, critical 4가지 타입으로 cooling 정책을 다르게 트리거합니다.
- Cooling Device — 온도를 낮추는 장치. CPU 주파수 제한, 팬 속도 증가, GPU throttling 등.
- Thermal Governor — thermal zone과 cooling device를 연결하는 정책 알고리즘. step_wise, power_allocator 등.
- 제어 루프 — 온도 샘플링 → trip 비교 → governor 판단 → cooling 조정 → 온도 하강 → 반복.
단계별 이해
- Thermal Zone 확인
/sys/class/thermal/thermal_zone*/에서 현재 시스템의 온도 센서와 trip point를 확인합니다. - Cooling Device 파악
/sys/class/thermal/cooling_device*/에서 사용 가능한 cooling 수단과 상태 범위를 확인합니다. - Governor 정책 이해
step_wise, power_allocator 등 governor 알고리즘이 온도에 따라 cooling을 어떻게 조정하는지 학습합니다. - Tracing으로 동작 추적
thermal tracepoint를 활성화하여 온도 변화와 cooling 동작을 실시간으로 관찰합니다.
개요
Thermal Management 서브시스템은 하드웨어 과열을 방지하고 성능과 전력 소비를 균형있게 조절하는 커널의 핵심 컴포넌트입니다.
주요 구성 요소
- Thermal Zone — 온도를 측정할 수 있는 하드웨어 영역 (CPU 코어, GPU 다이, SoC 등)
- Cooling Device — 온도를 낮추기 위한 장치 (CPU 주파수 제한, 팬 속도 제어, GPU throttling)
- Thermal Governor — thermal zone과 cooling device 간의 정책 결정 알고리즘
- Trip Point — 온도 임계값. 특정 온도에 도달하면 cooling action 트리거
아키텍처
Thermal Zone
thermal_zone_device 구조체
struct thermal_zone_device {
int id;
char type[THERMAL_NAME_LENGTH];
struct device device;
struct thermal_zone_device_ops *ops;
const struct thermal_zone_params *tzp;
struct thermal_governor *governor;
struct list_head thermal_instances; /* cooling device 바인딩 */
int temperature; /* 현재 온도 (milli-Celsius) */
int last_temperature; /* 이전 측정 온도 */
int polling_delay; /* 폴링 주기 (msec) */
int passive; /* passive cooling 활성화 */
bool forced_passive;
struct thermal_zone_device_ops *ops;
struct list_head node;
};
thermal_zone_device_ops
struct thermal_zone_device_ops {
int (*bind)(struct thermal_zone_device *,
struct thermal_cooling_device *);
int (*unbind)(struct thermal_zone_device *,
struct thermal_cooling_device *);
int (*get_temp)(struct thermal_zone_device *, int *temp);
int (*set_trips)(struct thermal_zone_device *, int, int);
int (*get_mode)(struct thermal_zone_device *,
enum thermal_device_mode *);
int (*set_mode)(struct thermal_zone_device *,
enum thermal_device_mode);
int (*get_trip_type)(struct thermal_zone_device *, int,
enum thermal_trip_type *);
int (*get_trip_temp)(struct thermal_zone_device *, int, int *);
int (*get_crit_temp)(struct thermal_zone_device *, int *);
int (*notify)(struct thermal_zone_device *, int,
enum thermal_trip_type);
};
Trip Points (온도 임계값)
Trip point는 특정 온도에 도달했을 때 cooling action을 트리거하는 임계값입니다.
| Trip Type | 설명 | 동작 |
|---|---|---|
THERMAL_TRIP_ACTIVE |
능동적 냉각 시작 | 팬 속도 증가, 주파수 감소 |
THERMAL_TRIP_PASSIVE |
수동적 냉각 시작 | CPU 주파수 제한, GPU throttling |
THERMAL_TRIP_HOT |
고온 경고 | 로그 기록, 경고 알림 |
THERMAL_TRIP_CRITICAL |
임계 온도 | 시스템 강제 종료 (orderly_poweroff) |
Thermal Zone 등록
struct thermal_zone_device *
thermal_zone_device_register(
const char *type,
int trips,
int mask,
void *devdata,
struct thermal_zone_device_ops *ops,
struct thermal_zone_params *tzp,
int passive_delay,
int polling_delay
);
/* 예: ACPI Thermal Zone 등록 */
struct thermal_zone_device *tz;
tz = thermal_zone_device_register("acpitz", 4, 0xf, tz_data,
&acpi_thermal_zone_ops,
&acpi_thermal_params,
10000, 0);
Cooling Device
thermal_cooling_device 구조체
struct thermal_cooling_device {
int id;
char type[THERMAL_NAME_LENGTH];
struct device device;
struct thermal_cooling_device_ops *ops;
bool updated;
unsigned long max_state; /* 최대 cooling level */
unsigned long cur_state; /* 현재 cooling level */
struct list_head node;
};
thermal_cooling_device_ops
struct thermal_cooling_device_ops {
int (*get_max_state)(struct thermal_cooling_device *,
unsigned long *);
int (*get_cur_state)(struct thermal_cooling_device *,
unsigned long *);
int (*set_cur_state)(struct thermal_cooling_device *,
unsigned long);
int (*get_requested_power)(struct thermal_cooling_device *,
struct thermal_zone_device *, u32 *);
int (*state2power)(struct thermal_cooling_device *,
struct thermal_zone_device *,
unsigned long, u32 *);
int (*power2state)(struct thermal_cooling_device *,
struct thermal_zone_device *, u32,
unsigned long *);
};
Cooling Device 종류
- CPU Frequency Cooling (
cpufreq_cooling_register) — CPU 주파수를 낮춰 전력 소비 감소 - Fan Cooling — PWM 제어로 팬 속도 조절
- GPU Throttling — GPU 주파수/전압 제한
- Devfreq Cooling (
devfreq_cooling_register) — Memory Controller, GPU 등 devfreq 장치
Cooling Device 등록
/* CPUFreq Cooling Device 등록 */
struct thermal_cooling_device *cdev;
struct cpumask clip_cpus;
cpumask_set_cpu(0, &clip_cpus);
cdev = cpufreq_cooling_register(&clip_cpus);
/* Fan Cooling Device 등록 */
struct thermal_cooling_device *fan_cdev;
fan_cdev = thermal_cooling_device_register("Fan", fan_data,
&fan_cooling_ops);
Thermal Governor
Thermal Governor는 thermal zone의 온도에 따라 cooling device를 제어하는 정책 알고리즘입니다.
Governor 종류
| Governor | 설명 | 적용 대상 |
|---|---|---|
step_wise |
온도 변화에 따라 단계적으로 cooling state 조정 | 범용 (기본값) |
fair_share |
여러 cooling device에 cooling 부하를 공평하게 분배 | 다중 cooling device |
power_allocator |
전력 예산 기반 제어. PID 컨트롤러 사용 | 모바일 SoC, ARM big.LITTLE |
bang_bang |
On/Off 방식. 임계값 초과 시 full cooling | 단순 Fan 제어 |
user_space |
userspace 데몬이 cooling 제어 | 커스텀 열 정책 |
Step-Wise Governor (기본)
step_wise governor는 온도가 trip point를 초과하면 cooling state를 한 단계씩 증가시키고, 온도가 낮아지면 한 단계씩 감소시킵니다.
/* Step-Wise Governor 알고리즘 */
if (temperature > trip_temp) {
/* 온도 상승: cooling state 증가 */
new_state = cur_state + 1;
if (new_state > max_state)
new_state = max_state;
} else {
/* 온도 하강: cooling state 감소 */
if (cur_state > 0)
new_state = cur_state - 1;
}
set_cur_state(cdev, new_state);
Power Allocator Governor
ARM 모바일 SoC에서 널리 사용됩니다. PID(Proportional-Integral-Derivative) 컨트롤러를 사용해 전력 예산을 동적으로 할당합니다.
struct thermal_zone_params {
char governor_name[THERMAL_NAME_LENGTH];
bool no_hwmon;
int num_tbps;
struct thermal_bind_params *tbp;
/* Power Allocator 전용 */
s32 k_po; /* PID proportional gain (overshoot) */
s32 k_pu; /* PID proportional gain (undershoot) */
s32 k_i; /* PID integral gain */
s32 k_d; /* PID derivative gain */
s32 integral_cutoff;
int sustainable_power; /* 지속 가능 전력 (mW) */
};
Governor 선택
# sysfs로 governor 변경 */
# cat /sys/class/thermal/thermal_zone0/available_policies
step_wise fair_share power_allocator bang_bang user_space
# echo power_allocator > /sys/class/thermal/thermal_zone0/policy
ACPI Thermal Zone
UEFI/ACPI 플랫폼에서는 ACPI 펌웨어가 thermal zone과 cooling method를 정의합니다.
ACPI Thermal Methods
| Method | 설명 |
|---|---|
_TMP |
현재 온도 반환 (1/10 Kelvin 단위) |
_CRT |
Critical 온도 임계값 |
_HOT |
Hot 온도 임계값 |
_PSV |
Passive 온도 임계값 |
_ACx |
Active cooling 임계값 (x = 0~9) |
_ALx |
Active cooling 대응 팬 리스트 |
_PSL |
Passive cooling 대상 프로세서 리스트 |
_TC1, _TC2, _TSP |
Passive cooling 상수 |
ACPI Thermal Zone 예시
/* ACPI DSDT에서 Thermal Zone 정의 예시 (ASL) */
ThermalZone (TZ00) {
Method (_TMP, 0) {
/* EC(Embedded Controller)에서 온도 읽기 */
Return (\_SB.PCI0.LPCB.EC0.TMP0) /* 0.1K 단위 */
}
Method (_CRT) { Return (3732) } /* 100°C (373.2K) */
Method (_PSV) { Return (3632) } /* 90°C */
Method (_AC0) { Return (3532) } /* 80°C */
Method (_AL0) { Return (Package(){\_SB.FAN0}) }
Name (_PSL, Package(){\_SB.CPU0, \_SB.CPU1}) /* Passive 대상 CPU */
}
sysfs 인터페이스
Thermal Zone sysfs
Cooling Device sysfs
sysfs 사용 예시
# 모든 thermal zone 온도 확인
# for tz in /sys/class/thermal/thermal_zone*; do
echo "$tz: $(cat $tz/type) = $(cat $tz/temp | awk '{print $1/1000}')°C"
done
# Cooling device 상태 확인
# cat /sys/class/thermal/cooling_device0/type
Processor
# cat /sys/class/thermal/cooling_device0/cur_state
0
# cat /sys/class/thermal/cooling_device0/max_state
10
# Governor 변경
# echo power_allocator > /sys/class/thermal/thermal_zone0/policy
hwmon 통합
Thermal 서브시스템은 hwmon 센서와 통합되어 다양한 온도 센서를 thermal zone으로 노출할 수 있습니다.
/* hwmon thermal zone 자동 생성 (CONFIG_THERMAL_HWMON) */
struct thermal_hwmon_device {
struct device *device;
int count;
struct list_head tz_list;
struct list_head node;
};
/* /sys/class/hwmon/hwmon0/temp1_input과 연동 */
CPU Frequency Cooling
CPUFreq cooling device는 CPU 주파수를 제한하여 온도를 낮춥니다.
CPUFreq Cooling 등록
#include <linux/cpu_cooling.h>
struct thermal_cooling_device *cdev;
struct cpumask clip_cpus;
struct cpufreq_policy *policy;
policy = cpufreq_cpu_get(0);
cpumask_copy(&clip_cpus, policy->related_cpus);
cpufreq_cpu_put(policy);
/* Cooling device 등록 */
cdev = cpufreq_cooling_register(&clip_cpus);
if (IS_ERR(cdev))
return PTR_ERR(cdev);
/* OPP 기반 cooling (전력 인식) */
cdev = of_cpufreq_cooling_register(np, &clip_cpus);
Cooling State와 주파수 매핑
CPUFreq cooling device는 가용 주파수를 cooling state로 매핑합니다.
/* 예: max_state=10, 가용 주파수가 11개라면 */
State 0: 2400 MHz /* 최대 주파수 */
State 1: 2200 MHz
State 2: 2000 MHz
...
State 10: 400 MHz /* 최소 주파수 */
Devfreq Cooling
GPU, Memory Controller 등 devfreq 장치를 cooling device로 등록합니다.
#include <linux/devfreq_cooling.h>
struct thermal_cooling_device *
devfreq_cooling_register(struct devfreq *df,
struct devfreq_cooling_power *dfc_power);
/* GPU devfreq cooling 등록 */
struct devfreq *gpu_devfreq;
struct thermal_cooling_device *gpu_cdev;
gpu_cdev = devfreq_cooling_register(gpu_devfreq, NULL);
Thermal Interrupts
일부 하드웨어는 온도 임계값 도달 시 인터럽트를 발생시킵니다.
Thermal IRQ 처리
static irqreturn_t thermal_zone_irq_handler(int irq, void *data)
{
struct thermal_zone_device *tz = data;
/* 온도 업데이트 트리거 */
thermal_zone_device_update(tz, THERMAL_EVENT_UNSPECIFIED);
return IRQ_HANDLED;
}
/* 인터럽트 등록 */
devm_request_threaded_irq(dev, irq, NULL,
thermal_zone_irq_handler,
IRQF_ONESHOT, "thermal", tz);
Thermal Netlink
커널 5.9+에서 thermal 이벤트를 netlink로 userspace에 전달합니다.
#include <linux/thermal.h>
/* Thermal Netlink 이벤트 */
enum thermal_notify_event {
THERMAL_EVENT_UNSPECIFIED,
THERMAL_EVENT_TEMP_SAMPLE, /* 온도 샘플링 */
THERMAL_TRIP_VIOLATED, /* trip point 초과 */
THERMAL_TRIP_CHANGED, /* trip point 변경 */
THERMAL_DEVICE_DOWN, /* thermal zone 비활성화 */
THERMAL_DEVICE_UP, /* thermal zone 활성화 */
THERMAL_DEVICE_NEW, /* 새 thermal zone 등록 */
THERMAL_DEVICE_DEL, /* thermal zone 제거 */
};
/* Netlink 그룹: THERMAL_GENL_SAMPLING_GROUP, THERMAL_GENL_EVENT_GROUP */
디버깅 & 모니터링
Tracing
# Thermal tracepoint 활성화
# cd /sys/kernel/debug/tracing
# echo 1 > events/thermal/enable
# 주요 tracepoint
thermal_temperature # 온도 샘플링
thermal_zone_trip # trip point 도달
cdev_update # cooling device 상태 변경
thermal_power_allocator # power allocator governor
# trace 출력
# cat trace
kworker/0:1-123 [000] .... 123.456: thermal_temperature: thermal_zone=acpitz temp=55000
실시간 모니터링
#!/bin/bash
# thermal_monitor.sh - 실시간 온도 모니터링
while true; do
clear
echo "===== Thermal Status ====="
for tz in /sys/class/thermal/thermal_zone*; do
type=$(cat $tz/type)
temp=$(cat $tz/temp)
policy=$(cat $tz/policy 2>/dev/null || echo "N/A")
printf "%-20s: %6.2f°C Governor: %s\\n" \
"$type" $(awk "BEGIN {print $temp/1000}") "$policy"
done
echo
echo "===== Cooling Devices ====="
for cdev in /sys/class/thermal/cooling_device*; do
type=$(cat $cdev/type)
cur=$(cat $cdev/cur_state)
max=$(cat $cdev/max_state)
printf "%-20s: %2d / %2d\\n" "$type" "$cur" "$max"
done
sleep 1
done
thermald (Thermal Daemon)
Intel thermald는 userspace thermal management 데몬입니다.
# thermald 설치 (Ubuntu/Debian)
# apt install thermald
# 서비스 상태 확인
# systemctl status thermald
# 설정 파일: /etc/thermald/thermal-conf.xml
# 로그: journalctl -u thermald
성능 고려사항
Polling Delay 조정
온도 폴링 주기는 응답 속도와 CPU 오버헤드 사이의 트레이드오프입니다.
- passive_delay — passive cooling 활성화 시 폴링 주기 (msec, 짧게)
- polling_delay — 일반 폴링 주기 (msec, 길게)
/* 폴링 주기 예시 */
passive_delay = 10000; /* 10초 (passive cooling 시) */
polling_delay = 0; /* 0 = 인터럽트 기반 */
Hysteresis (히스테리시스)
온도가 임계값 근처에서 진동할 때 cooling device가 계속 on/off되는 것을 방지합니다.
struct thermal_trip {
int temperature; /* trip 온도 */
int hysteresis; /* 히스테리시스 (milli-Celsius) */
enum thermal_trip_type type;
};
/* 예: trip_temp=80°C, hysteresis=5°C */
/* → 85°C 초과 시 cooling 시작 */
/* → 75°C 이하로 떨어지면 cooling 중단 */
커널 설정
CONFIG_THERMAL=y # Thermal 서브시스템
CONFIG_THERMAL_HWMON=y # hwmon 통합
CONFIG_THERMAL_GOV_STEP_WISE=y # Step-Wise Governor
CONFIG_THERMAL_GOV_FAIR_SHARE=y # Fair-Share Governor
CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y # Power Allocator Governor
CONFIG_THERMAL_GOV_BANG_BANG=y # Bang-Bang Governor
CONFIG_THERMAL_GOV_USER_SPACE=y # Userspace Governor
CONFIG_CPU_THERMAL=y # CPUFreq Cooling
CONFIG_DEVFREQ_THERMAL=y # Devfreq Cooling
CONFIG_THERMAL_EMULATION=y # 온도 에뮬레이션 (테스트용)
CONFIG_THERMAL_STATISTICS=y # Cooling 통계
# 플랫폼 특화
CONFIG_ACPI_THERMAL=y # ACPI Thermal Zone
CONFIG_INTEL_POWERCLAMP=y # Intel Idle Injection
CONFIG_X86_PKG_TEMP_THERMAL=y # Intel Package Temperature
CONFIG_INT340X_THERMAL=y # Intel INT3400/INT3403 DPTF
Common Issues
- Critical 온도 미설정 —
_CRT메서드 누락 시 시스템이 과열로 손상될 수 있음 - Passive Cooling 무한 루프 — 너무 짧은
passive_delay로 CPU 부하 증가 - Cooling Device 미바인딩 — thermal zone과 cooling device가 연결되지 않아 cooling 동작 안 함
- ACPI Thermal Zone 초기화 실패 — BIOS 버그로
_TMP메서드 실패
Troubleshooting
# Thermal zone 정보 확인
# cat /sys/class/thermal/thermal_zone0/type
# cat /sys/class/thermal/thermal_zone0/temp
# cat /sys/class/thermal/thermal_zone0/mode
# Cooling device 바인딩 확인
# ls -l /sys/class/thermal/thermal_zone0/cdev*
# ACPI thermal zone 디버깅
# dmesg | grep -i thermal
# dmesg | grep -i acpi
# Thermal emulation (테스트용)
# echo 85000 > /sys/class/thermal/thermal_zone0/emul_temp
참고자료
- Linux Thermal Framework Documentation
- Intel Thermal Daemon (thermald)
drivers/thermal/thermal_core.c— Thermal Core 구현drivers/thermal/gov_*.c— Thermal Governor 구현drivers/thermal/cpu_cooling.c— CPUFreq Coolingdrivers/acpi/thermal.c— ACPI Thermal Zone
- hwmon (Hardware Monitoring) — 온도 센서 드라이버
- 전원 관리 — DVFS와 thermal 통합
- ACPI — ACPI Thermal Zone
- CPU 토폴로지 — 코어별 온도 관리