RAPL & powercap

Linux powercap 프레임워크와 Intel RAPL의 실전 활용을 다룹니다. package/core/uncore/DRAM 도메인별 에너지 카운터 해석, PL1·PL2·time window 기반 전력 제한 모델, MSR·sysfs·hwmon 인터페이스 사용법, thermal·cpufreq와의 상호작용, 전력 캡 적용 시 성능 회귀 검증, 데이터센터 전력 예산 운영 시나리오와 모니터링 지표까지 종합적으로 정리합니다.

전제 조건: 전원관리Thermal 서브시스템 문서를 먼저 읽으세요. 전력/열 관리 주제는 성능과 안정성의 절충이 핵심이므로, 제어 루프와 임계값 정책을 함께 이해해야 운영 사고를 줄일 수 있습니다.
일상 비유: 이 주제는 건물 냉난방과 전력 피크 제어와 비슷합니다. 쾌적함과 전력 비용을 함께 맞추듯이, 커널도 성능과 열 한계를 동시에 고려해 동작합니다.

핵심 요약

  • RAPL (Running Average Power Limit) — Intel/AMD 프로세서의 하드웨어 전력 모니터링 및 제한 인터페이스입니다.
  • powercap 프레임워크 — 커널의 통합 전력 상한 설정 인터페이스. RAPL이 대표적인 백엔드입니다.
  • 전력 도메인 — package(전체 소켓), core(CPU 코어), dram(메모리), uncore(iGPU) 등으로 분리하여 측정합니다.
  • PL1/PL2 — 장기(Long-Term) 및 단기(Short-Term) 전력 제한. TDP와 Turbo 성능을 제어합니다.
  • 에너지 카운터 — 마이크로줄(μJ) 단위로 실시간 에너지 소비를 측정하여 전력 효율을 분석합니다.

단계별 이해

  1. 현재 전력 확인cat /sys/class/powercap/intel-rapl:0/energy_uj로 현재 소비 에너지를 확인합니다.

    또는 turbostat --show Package,Core,Uncore --interval 1로 실시간 전력을 모니터링합니다.

  2. 도메인별 측정perf stat -e power/energy-pkg/,power/energy-cores/ ./workload로 워크로드의 에너지 소비를 측정합니다.

    package와 core 도메인을 분리하여 CPU vs 언코어 전력 비중을 파악합니다.

  3. 전력 제한 설정echo 25000000 > /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw로 PL1을 25W로 제한합니다.

    열 문제나 배터리 수명 연장이 필요할 때 TDP를 동적으로 조절합니다.

  4. 효과 검증 — 전력 제한 전후로 벤치마크 성능과 온도/전력을 비교합니다.

    stress-ng --cpu 8 --timeout 60s로 부하를 주고 turbostat로 차이를 확인하세요.

관련 표준: Intel SDM Vol.4 (전력 관리 MSR) — RAPL은 Intel/AMD 프로세서의 하드웨어 전력 관리 인터페이스입니다. 종합 목록은 참고자료 — 표준 & 규격 섹션을 참고하세요.
교차 참조: 전원 관리 기초는 전원 관리, MSR 레지스터 접근은 MSR, CPU 토폴로지는 CPU 토폴로지 페이지를 참조하십시오.

powercap & RAPL

powercap 프레임워크는 전력 상한(power capping)을 설정하는 통합 인터페이스를 제공합니다. 가장 대표적인 백엔드는 Intel/AMD의 RAPL(Running Average Power Limit)로, 프로세서 패키지·코어·메모리 등 전력 도메인별 에너지 소비를 모니터링하고 제한할 수 있습니다.

powercap/RAPL 아키텍처

RAPL은 하드웨어 MSR(또는 TPMI)에서 에너지 카운터와 전력 제한을 읽고 쓰는 커널 드라이버를 통해 powercap 프레임워크에 등록됩니다. 사용자 공간은 sysfs 또는 perf 이벤트를 통해 접근합니다.

Userspace perf stat power/ turbostat powertop /sys/class/powercap/ powercap sysfs write powercap Framework (drivers/powercap/powercap_sys.c) intel_rapl_common.c (RAPL 코어 로직) perf_event_intel_rapl.c (PMU 드라이버) powercap_zone ops perf PMU intel_rapl_msr.c intel_rapl_tpmi.c amd_energy.c Hardware MSR (606h, 610h, 619h …) TPMI (Intel Meteor Lake+) MSR (C001_0299h, Family 17h+)

RAPL 도메인

RAPL은 프로세서 내부를 여러 전력 도메인(power domain)으로 분리하여 도메인별 에너지 측정과 전력 제한을 제공합니다. 지원 도메인은 프로세서 세대에 따라 다릅니다.

도메인설명IntelAMD
package소켓 전체 (CPU + 언코어 + iGPU)Sandy Bridge+ (2세대+)Zen (Family 17h+)
core (PP0)CPU 코어만Sandy Bridge+Zen+
uncore (PP1)iGPU / 언코어클라이언트 전용 (Sandy Bridge+)
dram메모리 컨트롤러/DRAM서버 (Sandy Bridge-EP+), 클라이언트 (Haswell+)
psys플랫폼 전체 (SoC + PCH)Skylake+ (모바일/NUC)
참고: psys 도메인은 CPU뿐 아니라 PCH, 온보드 디바이스를 포함한 플랫폼 전체 전력을 측정합니다. 노트북/NUC 등 배터리 기반 시스템에서 전체 시스템 전력 예산(power budget) 관리에 유용합니다.

도메인별 전력 분포

워크로드 유형에 따라 도메인별 전력 소비 비중이 크게 달라집니다. 다음은 실제 측정 데이터입니다:

워크로드PackageCoreUncore (iGPU)DRAM특징
Idle (유휴)8W2W (25%)3W (37%)3W (37%)백그라운드 활동
CPU 집약 (컴파일)65W48W (74%)10W (15%)7W (11%)코어 전력 지배적
메모리 집약 (STREAM)45W20W (44%)8W (18%)17W (38%)DRAM 전력 증가
GPU 렌더링 (iGPU)55W15W (27%)32W (58%)8W (15%)Uncore 전력 급증
혼합 (웹 브라우징)25W12W (48%)8W (32%)5W (20%)균형 분포

측정 환경: Intel Core i7-1165G7 (Tiger Lake, 28W TDP), DDR4-3200 16GB, 유휴 배경 프로세스 최소화

실무 인사이트:
  • CPU 집약적 워크로드는 Core 도메인이 70% 이상 차지 — CPU 주파수/전압 최적화가 효과적
  • 메모리 집약적 워크로드는 DRAM이 30~40% — 메모리 주파수 낮추기로 절전 가능
  • iGPU 활성 시 Uncore가 50% 이상 — 외장 GPU 사용 시 iGPU 비활성화로 10W 이상 절감
  • Idle 시에도 8W 소비 — C-state 진입 최적화와 디바이스 runtime PM 중요

PL1/PL2/PL3/PL4 전력 제한 계층

RAPL은 최대 4단계의 전력 제한(Power Limit)을 제공합니다. 각 단계는 허용 전력과 시간 윈도우가 다르며, 하드웨어가 자율적으로 스로틀링을 적용합니다.

레벨명칭시간 윈도우동작 방식MSR
PL1Long-Term (장기)1~128초 (설정 가능)지속 가능한 TDP. 윈도우 내 평균 전력이 PL1 이하 유지MSR_PKG_POWER_LIMIT [14:0]
PL2Short-Term (단기)1~10ms 수준Turbo Boost 시 허용하는 순간 최대 전력. PL1의 1.2~1.5배MSR_PKG_POWER_LIMIT [46:32]
PL3Peak Power (피크)~10ms배터리 기반 시스템의 순간 피크 제한 (Kaby Lake+)MSR_PL3_CONTROL
PL4Max Power (최대)즉시하드웨어 즉시 차단 — 전류/전력 한계 초과 시 주파수 급강하MSR_VR_CURRENT_CONFIG

PL 전력 제한 타임라인

다음 다이어그램은 워크로드 시작 시 PL1/PL2/PL4가 시간에 따라 어떻게 작동하는지 보여줍니다:

0W 15W 30W 45W 60W 75W 90W 전력 (W) 0s 2s 5s 10s 20s 시간 (초) PL4 (90W) 즉시 차단 PL2 (65W) ~10ms PL1 (45W) 장기 평균 Turbo Boost 워크로드 시작 PL2 윈도우 종료 PL1 수렴 실제 전력 소비 패턴 실제 소비 PL1 (Long-Term) PL2 (Short-Term)
동작 설명: 워크로드 시작 직후 CPU는 Turbo Boost를 활성화하여 PL2(65W) 근처까지 순간 전력을 사용합니다. 약 2초(PL2 시간 윈도우) 후 하드웨어는 전력을 PL1(45W)로 제한하기 시작하며, 10초 정도 지나면 장기 평균 전력이 PL1에 수렴합니다. PL4(90W)는 전류 한계를 넘으면 즉시 주파수를 급강하시키는 보호 메커니즘입니다.
/* powercap sysfs에서 PL1/PL2 확인 및 설정 */

# PL1 (constraint_0) 확인
cat /sys/class/powercap/intel-rapl:0/constraint_0_name          # "long_term"
cat /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw  # 현재 PL1 (μW)
cat /sys/class/powercap/intel-rapl:0/constraint_0_time_window_us  # 시간 윈도우 (μs)

# PL2 (constraint_1) 확인
cat /sys/class/powercap/intel-rapl:0/constraint_1_name          # "short_term"
cat /sys/class/powercap/intel-rapl:0/constraint_1_power_limit_uw

# PL1을 15W로 설정 (root 권한 필요)
echo 15000000 > /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw
주의: PL1/PL2 값을 무리하게 높이면 과열 및 thermal throttling이 발생합니다. 반대로 PL1을 지나치게 낮추면 성능이 심각하게 저하됩니다. PL3/PL4는 대부분 BIOS/펌웨어가 설정하며 커널에서 직접 제어하지 않습니다.

powercap sysfs 인터페이스

RAPL powercap sysfs 계층 구조 /sys/class/powercap/ intel-rapl:0/ (package-0) 공통 속성 name = "package-0" energy_uj 누적 에너지 (읽기 전용, μJ) max_energy_range_uj 오버플로 범위 enabled 도메인 활성화 여부 (0/1) constraint_0 (long_term = PL1) power_limit_uw time_window_us max_power_uw constraint_1 (short_term = PL2) power_limit_uw time_window_us max_power_uw :0:0/ :0:1/ :0:2/ core (PP0) name="core" energy_uj uncore (PP1) name="uncore" energy_uj dram (PP2) name="dram" energy_uj PL1 / PL2 전력 제한 비교 구분 constraint_0 (PL1) constraint_1 (PL2) 이름 long_term short_term 시간 윈도우 ~28초 (BIOS 기본값) ~2.44ms 용도 지속 전력 제한 (TDP 상당) 순간 버스트 전력 제한 쓰기 예시 echo 65000000 > constraint_0_power_limit_uw echo 95000000 > constraint_1_power_limit_uw

RAPL 커널 드라이버 구조

커널의 RAPL 지원은 공통 로직과 하드웨어 백엔드로 분리된 모듈러 구조입니다.

모듈경로역할
intel_rapl_commondrivers/powercap/intel_rapl_common.cRAPL 도메인 관리, powercap zone 등록, 에너지 단위 변환, PL 읽기/쓰기 공통 로직
intel_rapl_msrdrivers/powercap/intel_rapl_msr.cMSR 기반 백엔드 — 대부분의 Intel/AMD CPU. rdmsr/wrmsr로 RAPL MSR 접근
intel_rapl_tpmidrivers/powercap/intel_rapl_tpmi.cTPMI(Topology Aware Register and PM Capsule Interface) 백엔드 — Meteor Lake+ MMIO 기반
amd_energydrivers/hwmon/amd_energy.cAMD Zen hwmon 드라이버 (powercap 미사용, hwmon으로 에너지 노출)
/* intel_rapl_common.c — 핵심 구조체 */
struct rapl_domain {
    const char          *name;
    enum rapl_domain_type id;        /* RAPL_DOMAIN_PACKAGE, PP0, PP1, DRAM, PLATFORM */
    u64                  energy_unit;  /* 에너지 단위 (MSR_RAPL_POWER_UNIT에서 파생) */
    u64                  power_unit;   /* 전력 단위 */
    struct powercap_zone power_zone;  /* powercap 프레임워크 zone */
    struct rapl_package  *rp;         /* 소속 패키지 */
};

struct rapl_package {
    unsigned int          id;          /* 패키지(소켓) ID */
    unsigned int          nr_domains;  /* 이 패키지의 도메인 수 */
    struct rapl_domain    *domains;    /* 도메인 배열 */
    struct rapl_if_priv  *priv;       /* 백엔드별 private 데이터 */
};
# RAPL 모듈 로드 확인
lsmod | grep rapl
# intel_rapl_msr         20480  0
# intel_rapl_common      36864  1 intel_rapl_msr
# powercap               16384  1 intel_rapl_common

# 에너지 단위 확인 (MSR_RAPL_POWER_UNIT, 606h)
rdmsr 0x606
# 결과 해석: bits[12:8]=에너지 단위, bits[3:0]=전력 단위, bits[19:16]=시간 단위

TPMI (Topology Aware Register and PM Capsule Interface)

TPMI는 Intel Meteor Lake(클라이언트, 2023) 및 Sapphire Rapids(서버, 4세대 Xeon) 이후 도입된 MMIO 기반 PM 레지스터 인터페이스입니다. PCIe 표준 기반의 아키텍처 모델로 설계되어, 기존 MSR의 모델별 코드 유지보수 부담을 줄이고 멀티 다이/칩렛 아키텍처에서 다이별(per-die) 세밀한 전력 관리를 지원합니다. Granite Rapids(Xeon 6 P-core), Sierra Forest(Xeon 6 E-core), Clearwater Forest 등 후속 세대에서 전면 채택되었습니다.

핵심 차이: MSR은 CPU별(rdmsr/wrmsr) 직렬 접근이지만, TPMI는 PCI MMIO BAR를 통해 토폴로지 인식(topology-aware) 병렬 접근이 가능합니다. RAPL뿐 아니라 SST, Uncore 주파수 제어, 성능 제한 사유(PLR) 등 다양한 PM 기능이 TPMI를 통해 통합 제공됩니다.

TPMI vs MSR 비교

항목MSR 방식TPMI 방식
접근 방식rdmsr/wrmsr (CPU 명령어)MMIO (readq/writeq, PCI BAR 매핑)
토폴로지CPU별 (per-CPU), IPI로 원격 CPU 접근다이별 (per-die), 직접 MMIO 매핑
확장성다이 수 증가 시 MSR 주소 충돌 우려PCI VSEC + PFS로 동적 열거, 다이별 독립 주소 공간
병렬 접근MSR 접근은 직렬화 (serialize)서로 다른 다이의 MMIO에 동시 접근 가능
기능 발견CPUID + MSR 존재 여부 수동 확인PFS(PM Feature Structure)로 자동 열거
디바이스 모델직접 MSR 접근, 플랫폼 디바이스 없음PCI auxiliary 디바이스로 등록, 표준 드라이버 모델
유지보수CPU 모델별 MSR 테이블 유지 필요아키텍처 인터페이스 — 세대 간 호환 유지
토폴로지 계층소켓 → CPU (flat)소켓 → 다이 → 전력 도메인 → 패브릭 클러스터
지원 범위Sandy Bridge (2011) 이후 전 세대Meteor Lake/Sapphire Rapids (2023) 이후

TPMI 아키텍처

TPMI는 PCI VSEC(Vendor Specific Extended Capability, ID=66)를 통해 발견됩니다. Intel VSEC 드라이버(intel_vsec.c)가 OOB(Out-of-Band) PCI 디바이스의 VSEC/DVSEC 구조를 스캔하여 TPMI를 감지하면, auxiliary 버스에 TPMI 코어 디바이스를 생성합니다. TPMI 코어는 VSEC 헤더의 tBIR(BAR Indicator Register) 필드로 대상 PCI BAR를 식별하고, Address 필드로 BAR 내 PFS 시작 오프셋을 계산합니다.

PCI 열거 단계 PCI VSEC (Vendor Specific) intel_vsec.c (VSEC 드라이버) PCI BAR → MMIO 매핑 TPMI 코어 (drivers/platform/x86/intel/tpmi.c) PFS 파싱 → 기능별 auxiliary 디바이스 생성 PFS (PM Feature Structure) 테이블 Feature ID | MMIO 오프셋 | 크기 | 잠금 상태 — 다이별 독립 엔트리 TPMI Feature 드라이버 (auxiliary_device) intel_rapl_tpmi ID=0 (RAPL) isst_tpmi ID=5 (SST) uncore-freq-tpmi ID=2 (UFS) tpmi_plr ID=8 (PLR) tpmi_power_domains ID=12 (PWR DMN) 사용자 공간 인터페이스 powercap sysfs (RAPL) isst_if sysfs (SST) uncore-freq sysfs debugfs (PLR) Hardware (Meteor Lake+ SoC) Compute Die 0: TPMI MMIO Region (BAR) Compute Die 1: TPMI MMIO Region (BAR) RAPL regs SST regs RAPL regs SST regs

PCI VSEC 발견 및 PFS 파싱

TPMI는 PCIe 설정 공간의 VSEC(Vendor Specific Extended Capability)를 통해 발견됩니다. Intel VSEC 드라이버(intel_vsec.c)가 TPMI 타입의 VSEC를 감지하면 TPMI 코어 드라이버를 로드하고, TPMI 코어는 MMIO에 매핑된 PFS(PM Feature Structure) 테이블을 파싱합니다.

/* PFS (PM Feature Structure) 엔트리 — 하드웨어 비트필드 레이아웃 */
/* drivers/platform/x86/intel/vsec_tpmi.c (커널 6.13+, 이전: tpmi.c) */
struct intel_tpmi_pfs_entry {
    u64 tpmi_id:8;       /* PM 기능 식별자 (0=RAPL, 2=UFS, 5=SST ...) */
    u64 num_entries:8;  /* 인스턴스 수 (전력 도메인/다이 수와 대응) */
    u64 entry_size:16;  /* 인스턴스 MMIO 블록 크기 (32비트 워드 단위) */
    u64 cap_offset:16;  /* PM_Features 베이스로부터 오프셋 (KB 단위) */
    u64 attribute:2;    /* 속성 플래그 (읽기 전용, 잠금 등) */
    u64 reserved:14;
} __packed;

/* TPMI 코어의 PFS 파싱 흐름 */
tpmi_pfs_init(tpmi_info):
    /* 1. PCI BAR0에서 PFS 헤더 읽기 */
    pfs_start = devm_ioremap_resource(dev, &pci_resource);

    /* 2. PFS 엔트리 순회하며 기능 열거 */
    for (i = 0; i < pfs_count; i++) {
        read_pfs_entry(&pfs[i]);
        /* 3. 기능별 MMIO 영역 매핑 */
        feature_mem = pfs_start + pfs[i].cap_offset;
        /* 4. auxiliary 디바이스 생성 (intel_rapl_tpmi, isst_tpmi 등) */
        intel_vsec_add_aux(dev, NULL, &feature_info, name);
    }

TPMI Feature ID 매핑

각 PM 기능은 고유한 TPMI ID를 가지며, PFS 테이블에서 이 ID를 통해 발견됩니다. 커널은 ID에 따라 해당 feature 드라이버의 auxiliary 디바이스를 생성합니다.

ID이름커널 드라이버설명
0RAPLintel_rapl_tpmiMMIO 기반 RAPL 도메인 — 에너지 측정 및 전력 제한
1PEM(커널 내부)Performance and Energy Monitoring — 성능/에너지 모니터링
2UFSuncore-freq-tpmiUncore Frequency Scaling — 다이별 언코어 주파수 제어
5SSTisst_tpmiIntel Speed Select Technology — PP/BF/TF/CP 프로파일
8PLRtpmi_plrPerformance Limit Reasons — 스로틀링 원인 보고 (debugfs)
10UMSuncore-freq-tpmiUncore Mesh/SoC 주파수 제어
12PWR_DMNtpmi_power_domains전력 도메인 파티셔닝
0x81INFO(TPMI 코어 내부)CPU↔PCI 토폴로지 매핑 (패키지 ID, PCI BDF). 실제 PM 기능이 아닌 메타 정보
참고: TPMI_INFO_ID(0x81)는 CPU 소켓과 PCI 디바이스 간의 매핑 정보를 제공하는 특수 pseudo-feature입니다. TPMI 코어가 이 정보를 읽어 intel_tpmi_plat_infopackage_id와 PCI BDF를 채웁니다.

TPMI 코어 구조체

/* include/linux/intel_tpmi.h — TPMI API 핵심 구조체 */

/* Feature 드라이버가 TPMI 코어에서 받는 플랫폼 정보 */
struct intel_tpmi_plat_info {
    u8  package_id;        /* CPU 소켓(패키지) ID */
    u8  bus_number;        /* PCI 버스 번호 */
    u8  device_number;     /* PCI 디바이스 번호 */
    u8  function_number;   /* PCI 펑션 번호 */
    u8  segment;           /* PCI 세그먼트 ID */
    u8  partition;          /* 패키지 파티션 ID */
    u16 cdie_mask;          /* 현재 파티션의 컴퓨트 다이 비트맵 */
};

/* TPMI 코어 내부 — 디바이스별 기능 관리 */
struct intel_tpmi_info {
    struct auxiliary_device *vsec_dev;    /* 부모 VSEC auxiliary 디바이스 */
    int                   feature_count;  /* 발견된 PM 기능 수 */
    struct intel_tpmi_pm_feature *tpmi_features; /* PM 기능 배열 */
};

/* PM 기능 인스턴스 정보 */
struct intel_tpmi_pm_feature {
    struct intel_tpmi_pfs_entry pfs_header;  /* 하드웨어 PFS 헤더 */
    unsigned int                vsec_offset; /* MMIO 시작 주소 (바이트) */
    /* vsec_offset = VSEC Address + cap_offset(KB) * 1024 */
};

/* CPU↔PCI 토폴로지 매핑 헤더 (TPMI_INFO_ID=0x81에서 읽음) */
struct tpmi_info_header {
    u64 fn:3;         /* PCI Function 번호 */
    u64 dev:5;        /* PCI Device 번호 */
    u64 bus:8;        /* PCI Bus 번호 */
    u64 pkg:8;        /* CPU Package ID */
    u64 reserved:40;
} __packed;

/* Feature 드라이버가 사용하는 TPMI API (include/linux/intel_tpmi.h) */
struct intel_tpmi_plat_info *tpmi_get_platform_data(
    struct auxiliary_device *adev);     /* 플랫폼 정보 반환 */
int tpmi_get_resource_count(
    struct auxiliary_device *adev);     /* MMIO 인스턴스 수 반환 */
struct resource *tpmi_get_resource_at_index(
    struct auxiliary_device *adev,
    int index);                          /* 인덱스별 MMIO resource 반환 */
int tpmi_get_feature_status(
    struct auxiliary_device *adev,
    int feature_id,
    bool *read_blocked,
    bool *write_blocked);               /* 기능 잠금/비활성 상태 확인 */

RAPL over TPMI (intel_rapl_tpmi.c)

Meteor Lake+에서 RAPL 레지스터는 MSR 대신 TPMI MMIO를 통해 접근합니다. intel_rapl_tpmi 드라이버는 TPMI 코어에서 RAPL 기능(ID=0)의 MMIO 영역을 받아, 기존 intel_rapl_common의 powercap 프레임워크에 MMIO 백엔드로 등록합니다. 각 RAPL 도메인의 MMIO 블록 크기는 128바이트(TPMI_RAPL_DOMAIN_SIZE)이며, 각 Power Limit이 개별 레지스터를 가집니다(기존 MSR은 PL1+PL2가 하나의 64비트 MSR에 패킹).

등록 흐름: ① TPMI 코어가 PFS에서 TPMI_ID_RAPL=0 발견 → ② auxiliary 디바이스 intel_vsec.tpmi-rapl.N 생성 → ③ intel_rapl_tpmi probe → ④ tpmi_get_resource_at_index()로 MMIO 매핑 → ⑤ rapl_add_package()로 powercap zone 등록 → ⑥ /sys/class/powercap/intel-rapl:* 노출

/* intel_rapl_tpmi.c — MMIO 기반 RAPL 백엔드 */

/* TPMI RAPL MMIO 레지스터 오프셋 (MSR 주소 대신 MMIO 오프셋 사용) */
#define TPMI_RAPL_REG_HEADER          0x00
#define TPMI_RAPL_REG_UNIT            0x08   /* 에너지/전력/시간 단위 */
#define TPMI_RAPL_REG_PL1             0x10   /* Package Power Limit 1 */
#define TPMI_RAPL_REG_PL2             0x18   /* Package Power Limit 2 */
#define TPMI_RAPL_REG_PL4             0x20   /* Package Power Limit 4 */
#define TPMI_RAPL_REG_ENERGY_STATUS   0x28   /* 에너지 카운터 */
#define TPMI_RAPL_REG_PERF_STATUS    0x30   /* 성능 스로틀 상태 */
#define TPMI_RAPL_REG_POWER_INFO     0x38   /* TDP, min/max 전력 */

/* 디바이스별 RAPL TPMI 패키지 구조체 */
struct tpmi_rapl_package {
    struct rapl_if_priv          priv;       /* RAPL 인터페이스 private */
    struct intel_tpmi_plat_info *tpmi_info; /* TPMI 플랫폼 정보 */
    struct rapl_package         *rp;        /* RAPL 패키지 포인터 */
    void __iomem               *base;      /* MMIO 베이스 주소 */
};

/* MMIO 기반 읽기 — IPI 없이 직접 접근 */
static int tpmi_rapl_read_raw(int id, struct reg_action *ra)
{
    ra->value = readq(base + ra->reg.mmio_offset);
    ra->value &= ra->mask;   /* 마스크 적용 */
    return 0;
}

/* MMIO 기반 쓰기 — read-modify-write 패턴 */
static int tpmi_rapl_write_raw(int id, struct reg_action *ra)
{
    u64 val;
    val = readq(base + ra->reg.mmio_offset);
    val &= ~ra->mask;                 /* 대상 비트 클리어 */
    val |= ra->value & ra->mask;      /* 새 값 삽입 */
    writeq(val, base + ra->reg.mmio_offset);
    return 0;
}

/* rapl_if_priv — intel_rapl_common에 TPMI 백엔드 등록 */
static struct rapl_if_priv tpmi_rapl_priv = {
    .type           = RAPL_IF_TPMI,
    .read_raw       = tpmi_rapl_read_raw,
    .write_raw      = tpmi_rapl_write_raw,
    .control_type   = NULL,    /* powercap에서 설정 */
    .reg_unit       = { .mmio_offset = TPMI_RAPL_REG_UNIT },
    .regs           = {       /* 도메인별 레지스터 매핑 */
        [RAPL_DOMAIN_PACKAGE] = {
            .pl1    = { .mmio_offset = TPMI_RAPL_REG_PL1 },
            .pl2    = { .mmio_offset = TPMI_RAPL_REG_PL2 },
            .pl4    = { .mmio_offset = TPMI_RAPL_REG_PL4 },
            .energy = { .mmio_offset = TPMI_RAPL_REG_ENERGY_STATUS },
            .info   = { .mmio_offset = TPMI_RAPL_REG_POWER_INFO },
        },
    },
};
투명한 전환: TPMI 기반 RAPL은 동일한 intel_rapl_common 프레임워크를 사용하므로, 사용자 공간에서는 기존과 동일한 /sys/class/powercap/intel-rapl:* 경로로 접근합니다. MSR→TPMI 전환은 커널 내부에서 투명하게 처리됩니다.

SST (Speed Select Technology) over TPMI

Intel Speed Select Technology(SST)는 동일 CPU 내에서 코어별 차등 성능 프로파일을 제공합니다. Meteor Lake+에서 SST는 TPMI(Feature ID=5)를 통해 접근합니다.

SST 기능설명사용 사례
SST-PPPerformance Profile — 미리 정의된 주파수/TDP 프로파일 전환워크로드에 따라 코어 수 vs 주파수 트레이드오프
SST-BFBase Frequency — 특정 코어의 기본 주파수를 상향지연시간에 민감한 코어에 높은 보장 주파수 할당
SST-TFTurbo Frequency — 특정 코어에 터보 주파수 우선 배분고성능 요구 스레드에 터보 주파수 집중
SST-CPCore Power — 코어별 전력 우선순위 설정중요 코어에 전력 예산 우선 배정
# intel-speed-select CLI 도구로 SST 상태 확인
intel-speed-select --info
intel-speed-select perf-profile info        # SST-PP 프로파일 정보
intel-speed-select base-freq info           # SST-BF 지원 코어 확인
intel-speed-select turbo-freq info          # SST-TF 상태
intel-speed-select core-power info          # SST-CP 우선순위

# SST-CP로 특정 코어에 높은 우선순위 부여
intel-speed-select core-power assoc --clos 0 --core 0,1,2,3   # 고성능 그룹
intel-speed-select core-power assoc --clos 3 --core 4,5,6,7   # 저전력 그룹

Uncore 주파수 제어 over TPMI

TPMI 이전에는 Uncore 주파수가 패키지/다이 단위로만 제어 가능했습니다. TPMI(Feature ID=2)는 패브릭 클러스터(fabric cluster) 단위의 세밀한 Uncore 주파수 제어를 지원합니다.

Uncore 주파수 토폴로지 계층 (TPMI 기반) Package → Die → Power Domain → Fabric Cluster 기존 per-die 인터페이스 (TPMI 이전) /sys/devices/system/cpu/intel_uncore_frequency/ package_00_die_00/ initial_max_freq_khz 초기 최대 주파수 (읽기 전용) initial_min_freq_khz 초기 최소 주파수 (읽기 전용) max_freq_khz 현재 최대 주파수 (쓰기 가능) min_freq_khz 현재 최소 주파수 (쓰기 가능) 패키지 전체 die 단위 제어 — 단일 주파수 TPMI 추가: 클러스터 레벨 제어 /sys/devices/system/cpu/intel_uncore_frequency/ uncore00/ (Fabric Cluster 0) package_id 소켓(패키지) ID domain_id 전력 도메인 ID fabric_cluster_id 패브릭 클러스터 ID current_freq_khz 현재 실제 주파수 (읽기 전용) max_freq_khz 최대 주파수 (쓰기 가능) min_freq_khz 최소 주파수 (쓰기 가능) Fabric Cluster 단위 세밀한 제어 — Meteor Lake+ TPMI 확장 TPMI Uncore 토폴로지 계층 Package (소켓) Die (다이) Power Domain (전력 도메인) cluster 0 cluster 1 ... cluster N 개별 주파수 제어
활용 예시: 멀티 다이 Xeon 6 서버에서 메모리 집약적 워크로드가 특정 다이에 집중된 경우, 해당 다이의 패브릭 클러스터 Uncore 주파수를 높이고 나머지를 낮추어 전력 효율을 최적화할 수 있습니다.

PLR (Performance Limit Reasons) over TPMI

PLR(Feature ID=8)은 CPU 성능이 제한(스로틀링)되는 원인을 실시간으로 보고합니다. TPMI를 통해 debugfs에 노출되며, 성능 문제 진단에 활용됩니다.

# PLR 상태 확인 (debugfs)
ls /sys/kernel/debug/tpmi-plr/
# die0/  die1/  ...

cat /sys/kernel/debug/tpmi-plr/die0/status
# 각 비트가 스로틀링 원인을 나타냄:
# - thermal: 열 제한
# - power_limit_pl1: PL1(장기 전력) 초과
# - power_limit_pl2: PL2(단기 전력) 초과
# - electrical_design_point: 전류 한계 도달
# - turbo_transition_attenuation: 터보 전환 감쇠
# - prochot: 외부 PROCHOT# 신호

# PLR 스티키 비트 클리어 (해당 파일에 0 쓰기)
echo 0 > /sys/kernel/debug/tpmi-plr/die0/status
주의: PLR은 진단 전용 인터페이스입니다. 스티키 비트는 마지막 클리어 이후 발생한 모든 스로틀링 원인을 누적하므로, 주기적으로 클리어하면서 모니터링해야 정확한 시점을 파악할 수 있습니다.

TPMI 커널 설정

# TPMI 관련 Kconfig 옵션
CONFIG_INTEL_VSEC=m            # Intel Vendor Specific Extended Capabilities (필수)
CONFIG_INTEL_TPMI=m            # TPMI 코어 드라이버
CONFIG_INTEL_RAPL_TPMI=m       # RAPL over TPMI 백엔드
CONFIG_INTEL_UNCORE_FREQ_TPMI=m  # Uncore 주파수 제어 over TPMI
CONFIG_INTEL_SPEED_SELECT_INTERFACE=m  # SST over TPMI

# 로드된 TPMI 모듈 확인
lsmod | grep tpmi
# intel_rapl_tpmi        16384  0
# intel_uncore_freq_tpmi 16384  0
# isst_tpmi              20480  0
# intel_tpmi             24576  3 intel_rapl_tpmi,intel_uncore_freq_tpmi,isst_tpmi
# intel_vsec             16384  1 intel_tpmi

# TPMI 디바이스 확인 (PCI VSEC)
lspci -d 8086: -vvv | grep -A5 "Vendor Specific"

TPMI 소스 트리 구조

파일역할
include/linux/intel_tpmi.hTPMI API 헤더 — Feature ID 상수, 플랫폼 정보 구조체, 헬퍼 함수
drivers/platform/x86/intel/vsec.cPCI VSEC 드라이버 — TPMI 타입 감지 및 코어 디바이스 생성
drivers/platform/x86/intel/tpmi.cTPMI 코어 — PFS 파싱, MMIO 매핑, auxiliary 디바이스 생성, debugfs (커널 6.13+에서 vsec_tpmi.c로 개명)
drivers/powercap/intel_rapl_tpmi.cRAPL TPMI 백엔드 — MMIO 기반 에너지/전력 레지스터 접근
drivers/platform/x86/intel/uncore-frequency/Uncore 주파수 제어 (TPMI + MSR 백엔드)
drivers/platform/x86/intel/speed_select_if/SST 인터페이스 (TPMI + MMIO + MSR 백엔드)

TPMI debugfs 인터페이스

TPMI 코어 드라이버는 debugfs를 통해 PFS 테이블 덤프와 Feature별 MMIO 원시 읽기/쓰기를 제공합니다. 주로 디버깅과 펌웨어 설정 확인에 사용됩니다.

# TPMI debugfs 구조
/sys/kernel/debug/tpmi-<N>/
    ├── pfs_dump                     # PFS 테이블 전체 엔트리 출력
    ├── tpmi-id-<feature_id>/
    │   ├── mem_dump                 # Feature MMIO 영역 원시 덤프 (읽기 전용)
    │   └── mem_write                # 특정 오프셋에 MMIO 쓰기 (디버그용)
    └── ...

# PFS 엔트리 확인 (어떤 PM 기능이 지원되는지)
cat /sys/kernel/debug/tpmi-0/pfs_dump

# RAPL MMIO 레지스터 원시 값 확인
cat /sys/kernel/debug/tpmi-0/tpmi-id-0/mem_dump

TPMI 커널 머지 타임라인

커널 버전TPMI 마일스톤
6.3TPMI 기본 열거 드라이버 병합 (tpmi.c)
6.4RAPL TPMI 드라이버 (intel_rapl_tpmi.c) 병합
6.5Uncore 주파수 TPMI 지원, SST via TPMI
6.5~6.6TPMI debugfs, 기능 잠금 상태 인터페이스
6.6+CPU 토폴로지/도메인 매핑, 클러스터 레벨 제어
6.13드라이버 tpmi.cvsec_tpmi.c 개명, Clearwater Forest ID 추가

AMD RAPL 지원

AMD는 Zen 아키텍처(Family 17h, Ryzen 1000/EPYC 7001) 이후로 RAPL 호환 MSR을 제공합니다. 커널 intel_rapl_msr 드라이버가 AMD CPU도 지원하여 동일한 powercap sysfs 인터페이스로 접근 가능합니다.

항목Intel RAPLAMD RAPL
지원 시작Sandy Bridge (2세대, 2011)Zen (Family 17h, 2017)
도메인package, core, uncore, dram, psyspackage, core (Zen 2+에서 확장)
MSR 주소606h, 610h, 611h, 619h, 641h 등C001_0299h (core), C001_029Ah (pkg) 등
전력 제한 쓰기PL1/PL2 쓰기 가능읽기 전용 (에너지 측정만, 전력 제한 설정 불가)
커널 드라이버intel_rapl_msr / intel_rapl_tpmiintel_rapl_msr (AMD 지원 포함)
perf 이벤트power/energy-pkg,cores,ram/power/energy-pkg,cores/
참고: AMD의 RAPL MSR은 에너지 측정(energy counter)만 지원하며, Intel처럼 전력 상한(power limit)을 설정할 수 없습니다. AMD 시스템에서 전력 제한은 BIOS/UEFI의 PPT(Package Power Tracking) 설정이나 amd_pstate 드라이버의 EPP(Energy Performance Preference)를 통해 관리합니다.

perf 전력 이벤트 및 모니터링 도구

# RAPL 전력 측정 (perf) — 5초간 에너지 소비 측정
perf stat -e power/energy-pkg/,power/energy-cores/,power/energy-ram/ sleep 5

# 특정 프로세스의 전력 소비 프로파일링
perf stat -e power/energy-pkg/,power/energy-cores/ -- make -j$(nproc)

# turbostat — 실시간 전력/주파수/온도 모니터링
turbostat --show Package,Core,CPU,Avg_MHz,Busy%,PkgWatt,CorWatt,RAMWatt --interval 1

# powertop — 전력 소비 분석 + 절전 추천
powertop --auto-tune    # 자동 절전 최적화 적용
powertop --csv=report.csv --time=30   # 30초 측정 후 CSV 리포트

# powercap 에너지 직접 읽기 (커스텀 스크립트용)
E1=$(cat /sys/class/powercap/intel-rapl:0/energy_uj)
sleep 5
E2=$(cat /sys/class/powercap/intel-rapl:0/energy_uj)
echo "5초간 소비: $(( (E2 - E1) / 1000000 )) J, 평균: $(( (E2 - E1) / 5000000 )) W"

실전 예제: PL1 제한 효과 측정

전력 제한(PL1)을 적용했을 때 성능과 전력의 트레이드오프를 실제로 측정해봅니다.

예제 1: PL1 제한 전후 벤치마크

#!/bin/bash
# PL1 제한 효과 비교 스크립트

# 1. 기본 PL1 확인 및 저장
RAPL_PATH="/sys/class/powercap/intel-rapl:0"
ORIG_PL1=$(cat ${RAPL_PATH}/constraint_0_power_limit_uw)
echo "원래 PL1: $(( ORIG_PL1 / 1000000 )) W"

# 2. 제한 없음 (기본값) 테스트
echo "=== 기본 설정 테스트 ==="
perf stat -e power/energy-pkg/,power/energy-cores/ \
    stress-ng --cpu 8 --timeout 30s 2>&1 | grep energy

# 3. PL1 25W로 제한
echo 25000000 > ${RAPL_PATH}/constraint_0_power_limit_uw
echo "=== PL1 25W 제한 테스트 ==="
perf stat -e power/energy-pkg/,power/energy-cores/ \
    stress-ng --cpu 8 --timeout 30s 2>&1 | grep energy

# 4. PL1 15W로 강제 제한
echo 15000000 > ${RAPL_PATH}/constraint_0_power_limit_uw
echo "=== PL1 15W 제한 테스트 ==="
perf stat -e power/energy-pkg/,power/energy-cores/ \
    stress-ng --cpu 8 --timeout 30s 2>&1 | grep energy

# 5. 원래 설정 복원
echo ${ORIG_PL1} > ${RAPL_PATH}/constraint_0_power_limit_uw
echo "PL1 복원 완료"

예상 결과:

PL1 설정Package 에너지성능 (작업 완료)평균 전력효율
기본 (45W)~1350 J100% (기준)45W1.0×
25W 제한~900 J~85%25W1.4×
15W 제한~750 J~65%15W1.6×
실무 적용: 노트북/태블릿에서 배터리 수명을 늘리거나, 데이터센터에서 랙 단위 전력 예산을 맞출 때 PL1을 동적으로 조절합니다. 대부분의 워크로드는 25W 제한에서도 85% 이상 성능을 유지하므로, 에너지 효율이 크게 향상됩니다.

예제 2: 프로그램별 에너지 프로파일링

# 컴파일 vs 압축 vs 암호화 — 에너지 소비 비교

# 컴파일 (CPU intensive)
perf stat -e power/energy-pkg/,power/energy-cores/ -- \
    make -j$(nproc) clean all

# 압축 (메모리 대역폭 intensive)
perf stat -e power/energy-pkg/,power/energy-ram/ -- \
    tar -czf archive.tar.gz /usr/share/doc

# 암호화 (CPU + 일부 메모리)
perf stat -e power/energy-pkg/,power/energy-cores/ -- \
    openssl enc -aes-256-cbc -in largefile -out largefile.enc -k password

# 결과 비교 예시:
# 컴파일:  Package 2500J, Cores 1800J, RAM 200J  → CPU 중심
# 압축:    Package 1200J, Cores  600J, RAM 400J  → 메모리 대역폭 비중 큼
# 암호화:  Package 1800J, Cores 1500J, RAM 100J  → CPU 집약적

예제 3: turbostat으로 실시간 전력 추적

# turbostat으로 PL1 제한 효과 실시간 관찰
# 터미널 1: turbostat 실행
sudo turbostat --show Package,Core,CPU,Avg_MHz,Busy%,PkgWatt,CorWatt,GFXWatt --interval 1

# 터미널 2: 부하 적용 후 PL1 변경
stress-ng --cpu 8 --timeout 120s &
sleep 30
echo 25000000 > /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw
# → turbostat에서 PkgWatt가 즉시 25W 이하로 떨어지는 것 확인
# → Avg_MHz도 함께 감소 (스로틀링)

sleep 30
echo ${ORIG_PL1} > /sys/class/powercap/intel-rapl:0/constraint_0_power_limit_uw
# → PkgWatt와 Avg_MHz가 원래대로 복구
주의: PL1 제한은 즉시 적용되지만, 하드웨어가 시간 윈도우 내 평균 전력을 제어하므로 수 초간 초과할 수 있습니다. 또한 PL1을 너무 낮게 설정하면 시스템이 불안정해지거나 응답성이 크게 저하될 수 있으니, 최소 TDP의 50% 이상으로 유지하세요.

RAPL 정확도·보안·제한사항

보안 경고 — PLATYPUS 공격 (CVE-2020-8694, CVE-2020-8695): RAPL 에너지 카운터의 높은 해상도를 악용하여 비특권 프로세스가 AES 키 등 민감한 데이터를 추출할 수 있는 사이드 채널 공격이 2020년에 공개되었습니다. 이에 따라 Linux 커널 5.10+에서는 energy_uj 및 perf power 이벤트 접근에 CAP_SYS_RAWIO 또는 root 권한이 필요하도록 변경되었습니다.
항목설명
에너지 해상도약 15.3μJ (2-16 J × 에너지 단위). 실제 정확도는 ±5~10% 수준으로 절대 전력 측정보다는 상대 비교에 적합
카운터 오버플로32비트 에너지 카운터는 max_energy_range_uj 도달 시 0으로 랩어라운드. 고부하 서버에서 ~60초마다 발생 가능 — 폴링 간격 주의
접근 권한 (5.10+)/sys/class/powercap/*/energy_uj: root 또는 CAP_SYS_RAWIO. perf power 이벤트: perf_event_paranoid ≤ 0 또는 CAP_PERFMON
가상화 환경VM에서는 RAPL MSR 접근이 차단됨 (hypervisor가 trap). KVM -cpu host로 패스스루 가능하나 보안상 비권장
컨테이너cgroup v2의 perf 이벤트 네임스페이스와 결합하여 컨테이너별 에너지 측정 가능 (Kepler 프로젝트 등 활용)
# 현재 perf 접근 권한 확인
cat /proc/sys/kernel/perf_event_paranoid
# 4: 모든 perf 이벤트 제한 (기본값, 일부 배포판)
# 2: 커널 이벤트 제한 (기본값)
# 1: CPU 이벤트 제한
# 0: 제한 없음
# -1: 모든 접근 허용

# RAPL 에너지 읽기가 Permission denied인 경우
sudo sysctl kernel.perf_event_paranoid=0  # 임시 해제 (재부팅 시 초기화)

# 오버플로 범위 확인
cat /sys/class/powercap/intel-rapl:0/max_energy_range_uj
# 예: 262143328850 (≈262 kJ, 150W 시 ~29분마다 오버플로)