Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/x86/events/intel/cstate.c
50949 views
1
/*
2
* Support cstate residency counters
3
*
4
* Copyright (C) 2015, Intel Corp.
5
* Author: Kan Liang ([email protected])
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Library General Public
9
* License as published by the Free Software Foundation; either
10
* version 2 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Library General Public License for more details.
16
*
17
*/
18
19
/*
20
* This file export cstate related free running (read-only) counters
21
* for perf. These counters may be use simultaneously by other tools,
22
* such as turbostat. However, it still make sense to implement them
23
* in perf. Because we can conveniently collect them together with
24
* other events, and allow to use them from tools without special MSR
25
* access code.
26
*
27
* The events only support system-wide mode counting. There is no
28
* sampling support because it is not supported by the hardware.
29
*
30
* According to counters' scope and category, two PMUs are registered
31
* with the perf_event core subsystem.
32
* - 'cstate_core': The counter is available for each physical core.
33
* The counters include CORE_C*_RESIDENCY.
34
* - 'cstate_pkg': The counter is available for each physical package.
35
* The counters include PKG_C*_RESIDENCY.
36
*
37
* All of these counters are specified in the IntelĀ® 64 and IA-32
38
* Architectures Software Developer.s Manual Vol3b.
39
*
40
* Model specific counters:
41
* MSR_CORE_C1_RES: CORE C1 Residency Counter
42
* perf code: 0x00
43
* Available model: SLM,AMT,GLM,CNL,ICX,TNT,ADL,RPL
44
* MTL,SRF,GRR,ARL,LNL,PTL,WCL,NVL
45
* Scope: Core (each processor core has a MSR)
46
* MSR_CORE_C3_RESIDENCY: CORE C3 Residency Counter
47
* perf code: 0x01
48
* Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,GLM,
49
* CNL,KBL,CML,TNT
50
* Scope: Core
51
* MSR_CORE_C6_RESIDENCY: CORE C6 Residency Counter
52
* perf code: 0x02
53
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
54
* SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
55
* TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF,
56
* GRR,ARL,LNL,PTL,WCL,NVL
57
* Scope: Core
58
* MSR_CORE_C7_RESIDENCY: CORE C7 Residency Counter
59
* perf code: 0x03
60
* Available model: SNB,IVB,HSW,BDW,SKL,CNL,KBL,CML,
61
* ICL,TGL,RKL,ADL,RPL,MTL,ARL,LNL,
62
* PTL,WCL,NVL
63
* Scope: Core
64
* MSR_PKG_C2_RESIDENCY: Package C2 Residency Counter.
65
* perf code: 0x00
66
* Available model: SNB,IVB,HSW,BDW,SKL,KNL,GLM,CNL,
67
* KBL,CML,ICL,ICX,TGL,TNT,RKL,ADL,
68
* RPL,SPR,MTL,ARL,LNL,SRF,PTL,WCL,
69
* NVL
70
* Scope: Package (physical package)
71
* MSR_PKG_C3_RESIDENCY: Package C3 Residency Counter.
72
* perf code: 0x01
73
* Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL,
74
* GLM,CNL,KBL,CML,ICL,TGL,TNT,RKL,
75
* ADL,RPL,MTL,ARL
76
* Scope: Package (physical package)
77
* MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter.
78
* perf code: 0x02
79
* Available model: SLM,AMT,NHM,WSM,SNB,IVB,HSW,BDW,
80
* SKL,KNL,GLM,CNL,KBL,CML,ICL,ICX,
81
* TGL,TNT,RKL,ADL,RPL,SPR,MTL,SRF,
82
* ARL,LNL,PTL,WCL,NVL
83
* Scope: Package (physical package)
84
* MSR_PKG_C7_RESIDENCY: Package C7 Residency Counter.
85
* perf code: 0x03
86
* Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,CNL,
87
* KBL,CML,ICL,TGL,RKL
88
* Scope: Package (physical package)
89
* MSR_PKG_C8_RESIDENCY: Package C8 Residency Counter.
90
* perf code: 0x04
91
* Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL,
92
* ADL,RPL,MTL,ARL
93
* Scope: Package (physical package)
94
* MSR_PKG_C9_RESIDENCY: Package C9 Residency Counter.
95
* perf code: 0x05
96
* Available model: HSW ULT,KBL,CNL,CML,ICL,TGL,RKL
97
* Scope: Package (physical package)
98
* MSR_PKG_C10_RESIDENCY: Package C10 Residency Counter.
99
* perf code: 0x06
100
* Available model: HSW ULT,KBL,GLM,CNL,CML,ICL,TGL,
101
* TNT,RKL,ADL,RPL,MTL,ARL,LNL,PTL,
102
* WCL,NVL
103
* Scope: Package (physical package)
104
* MSR_MODULE_C6_RES_MS: Module C6 Residency Counter.
105
* perf code: 0x00
106
* Available model: SRF,GRR,NVL
107
* Scope: A cluster of cores shared L2 cache
108
*
109
*/
110
111
#include <linux/module.h>
112
#include <linux/slab.h>
113
#include <linux/perf_event.h>
114
#include <linux/nospec.h>
115
#include <asm/cpu_device_id.h>
116
#include <asm/intel-family.h>
117
#include <asm/msr.h>
118
#include "../perf_event.h"
119
#include "../probe.h"
120
121
MODULE_DESCRIPTION("Support for Intel cstate performance events");
122
MODULE_LICENSE("GPL");
123
124
#define DEFINE_CSTATE_FORMAT_ATTR(_var, _name, _format) \
125
static ssize_t __cstate_##_var##_show(struct device *dev, \
126
struct device_attribute *attr, \
127
char *page) \
128
{ \
129
BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
130
return sprintf(page, _format "\n"); \
131
} \
132
static struct device_attribute format_attr_##_var = \
133
__ATTR(_name, 0444, __cstate_##_var##_show, NULL)
134
135
/* Model -> events mapping */
136
struct cstate_model {
137
unsigned long core_events;
138
unsigned long pkg_events;
139
unsigned long module_events;
140
unsigned long quirks;
141
};
142
143
/* Quirk flags */
144
#define SLM_PKG_C6_USE_C7_MSR (1UL << 0)
145
#define KNL_CORE_C6_MSR (1UL << 1)
146
147
/* cstate_core PMU */
148
static struct pmu cstate_core_pmu;
149
static bool has_cstate_core;
150
151
enum perf_cstate_core_events {
152
PERF_CSTATE_CORE_C1_RES = 0,
153
PERF_CSTATE_CORE_C3_RES,
154
PERF_CSTATE_CORE_C6_RES,
155
PERF_CSTATE_CORE_C7_RES,
156
157
PERF_CSTATE_CORE_EVENT_MAX,
158
};
159
160
PMU_EVENT_ATTR_STRING(c1-residency, attr_cstate_core_c1, "event=0x00");
161
PMU_EVENT_ATTR_STRING(c3-residency, attr_cstate_core_c3, "event=0x01");
162
PMU_EVENT_ATTR_STRING(c6-residency, attr_cstate_core_c6, "event=0x02");
163
PMU_EVENT_ATTR_STRING(c7-residency, attr_cstate_core_c7, "event=0x03");
164
165
static unsigned long core_msr_mask;
166
167
PMU_EVENT_GROUP(events, cstate_core_c1);
168
PMU_EVENT_GROUP(events, cstate_core_c3);
169
PMU_EVENT_GROUP(events, cstate_core_c6);
170
PMU_EVENT_GROUP(events, cstate_core_c7);
171
172
static bool test_msr(int idx, void *data)
173
{
174
return test_bit(idx, (unsigned long *) data);
175
}
176
177
static struct perf_msr core_msr[] = {
178
[PERF_CSTATE_CORE_C1_RES] = { MSR_CORE_C1_RES, &group_cstate_core_c1, test_msr },
179
[PERF_CSTATE_CORE_C3_RES] = { MSR_CORE_C3_RESIDENCY, &group_cstate_core_c3, test_msr },
180
[PERF_CSTATE_CORE_C6_RES] = { MSR_CORE_C6_RESIDENCY, &group_cstate_core_c6, test_msr },
181
[PERF_CSTATE_CORE_C7_RES] = { MSR_CORE_C7_RESIDENCY, &group_cstate_core_c7, test_msr },
182
};
183
184
static struct attribute *attrs_empty[] = {
185
NULL,
186
};
187
188
/*
189
* There are no default events, but we need to create
190
* "events" group (with empty attrs) before updating
191
* it with detected events.
192
*/
193
static struct attribute_group cstate_events_attr_group = {
194
.name = "events",
195
.attrs = attrs_empty,
196
};
197
198
DEFINE_CSTATE_FORMAT_ATTR(cstate_event, event, "config:0-63");
199
static struct attribute *cstate_format_attrs[] = {
200
&format_attr_cstate_event.attr,
201
NULL,
202
};
203
204
static struct attribute_group cstate_format_attr_group = {
205
.name = "format",
206
.attrs = cstate_format_attrs,
207
};
208
209
static const struct attribute_group *cstate_attr_groups[] = {
210
&cstate_events_attr_group,
211
&cstate_format_attr_group,
212
NULL,
213
};
214
215
/* cstate_pkg PMU */
216
static struct pmu cstate_pkg_pmu;
217
static bool has_cstate_pkg;
218
219
enum perf_cstate_pkg_events {
220
PERF_CSTATE_PKG_C2_RES = 0,
221
PERF_CSTATE_PKG_C3_RES,
222
PERF_CSTATE_PKG_C6_RES,
223
PERF_CSTATE_PKG_C7_RES,
224
PERF_CSTATE_PKG_C8_RES,
225
PERF_CSTATE_PKG_C9_RES,
226
PERF_CSTATE_PKG_C10_RES,
227
228
PERF_CSTATE_PKG_EVENT_MAX,
229
};
230
231
PMU_EVENT_ATTR_STRING(c2-residency, attr_cstate_pkg_c2, "event=0x00");
232
PMU_EVENT_ATTR_STRING(c3-residency, attr_cstate_pkg_c3, "event=0x01");
233
PMU_EVENT_ATTR_STRING(c6-residency, attr_cstate_pkg_c6, "event=0x02");
234
PMU_EVENT_ATTR_STRING(c7-residency, attr_cstate_pkg_c7, "event=0x03");
235
PMU_EVENT_ATTR_STRING(c8-residency, attr_cstate_pkg_c8, "event=0x04");
236
PMU_EVENT_ATTR_STRING(c9-residency, attr_cstate_pkg_c9, "event=0x05");
237
PMU_EVENT_ATTR_STRING(c10-residency, attr_cstate_pkg_c10, "event=0x06");
238
239
static unsigned long pkg_msr_mask;
240
241
PMU_EVENT_GROUP(events, cstate_pkg_c2);
242
PMU_EVENT_GROUP(events, cstate_pkg_c3);
243
PMU_EVENT_GROUP(events, cstate_pkg_c6);
244
PMU_EVENT_GROUP(events, cstate_pkg_c7);
245
PMU_EVENT_GROUP(events, cstate_pkg_c8);
246
PMU_EVENT_GROUP(events, cstate_pkg_c9);
247
PMU_EVENT_GROUP(events, cstate_pkg_c10);
248
249
static struct perf_msr pkg_msr[] = {
250
[PERF_CSTATE_PKG_C2_RES] = { MSR_PKG_C2_RESIDENCY, &group_cstate_pkg_c2, test_msr },
251
[PERF_CSTATE_PKG_C3_RES] = { MSR_PKG_C3_RESIDENCY, &group_cstate_pkg_c3, test_msr },
252
[PERF_CSTATE_PKG_C6_RES] = { MSR_PKG_C6_RESIDENCY, &group_cstate_pkg_c6, test_msr },
253
[PERF_CSTATE_PKG_C7_RES] = { MSR_PKG_C7_RESIDENCY, &group_cstate_pkg_c7, test_msr },
254
[PERF_CSTATE_PKG_C8_RES] = { MSR_PKG_C8_RESIDENCY, &group_cstate_pkg_c8, test_msr },
255
[PERF_CSTATE_PKG_C9_RES] = { MSR_PKG_C9_RESIDENCY, &group_cstate_pkg_c9, test_msr },
256
[PERF_CSTATE_PKG_C10_RES] = { MSR_PKG_C10_RESIDENCY, &group_cstate_pkg_c10, test_msr },
257
};
258
259
/* cstate_module PMU */
260
static struct pmu cstate_module_pmu;
261
static bool has_cstate_module;
262
263
enum perf_cstate_module_events {
264
PERF_CSTATE_MODULE_C6_RES = 0,
265
266
PERF_CSTATE_MODULE_EVENT_MAX,
267
};
268
269
PMU_EVENT_ATTR_STRING(c6-residency, attr_cstate_module_c6, "event=0x00");
270
271
static unsigned long module_msr_mask;
272
273
PMU_EVENT_GROUP(events, cstate_module_c6);
274
275
static struct perf_msr module_msr[] = {
276
[PERF_CSTATE_MODULE_C6_RES] = { MSR_MODULE_C6_RES_MS, &group_cstate_module_c6, test_msr },
277
};
278
279
static int cstate_pmu_event_init(struct perf_event *event)
280
{
281
u64 cfg = event->attr.config;
282
283
if (event->attr.type != event->pmu->type)
284
return -ENOENT;
285
286
/* unsupported modes and filters */
287
if (event->attr.sample_period) /* no sampling */
288
return -EINVAL;
289
290
if (event->cpu < 0)
291
return -EINVAL;
292
293
if (event->pmu == &cstate_core_pmu) {
294
if (cfg >= PERF_CSTATE_CORE_EVENT_MAX)
295
return -EINVAL;
296
cfg = array_index_nospec((unsigned long)cfg, PERF_CSTATE_CORE_EVENT_MAX);
297
if (!(core_msr_mask & (1 << cfg)))
298
return -EINVAL;
299
event->hw.event_base = core_msr[cfg].msr;
300
} else if (event->pmu == &cstate_pkg_pmu) {
301
if (cfg >= PERF_CSTATE_PKG_EVENT_MAX)
302
return -EINVAL;
303
cfg = array_index_nospec((unsigned long)cfg, PERF_CSTATE_PKG_EVENT_MAX);
304
if (!(pkg_msr_mask & (1 << cfg)))
305
return -EINVAL;
306
event->hw.event_base = pkg_msr[cfg].msr;
307
} else if (event->pmu == &cstate_module_pmu) {
308
if (cfg >= PERF_CSTATE_MODULE_EVENT_MAX)
309
return -EINVAL;
310
cfg = array_index_nospec((unsigned long)cfg, PERF_CSTATE_MODULE_EVENT_MAX);
311
if (!(module_msr_mask & (1 << cfg)))
312
return -EINVAL;
313
event->hw.event_base = module_msr[cfg].msr;
314
} else {
315
return -ENOENT;
316
}
317
318
event->hw.config = cfg;
319
event->hw.idx = -1;
320
return 0;
321
}
322
323
static inline u64 cstate_pmu_read_counter(struct perf_event *event)
324
{
325
u64 val;
326
327
rdmsrq(event->hw.event_base, val);
328
return val;
329
}
330
331
static void cstate_pmu_event_update(struct perf_event *event)
332
{
333
struct hw_perf_event *hwc = &event->hw;
334
u64 prev_raw_count, new_raw_count;
335
336
prev_raw_count = local64_read(&hwc->prev_count);
337
do {
338
new_raw_count = cstate_pmu_read_counter(event);
339
} while (!local64_try_cmpxchg(&hwc->prev_count,
340
&prev_raw_count, new_raw_count));
341
342
local64_add(new_raw_count - prev_raw_count, &event->count);
343
}
344
345
static void cstate_pmu_event_start(struct perf_event *event, int mode)
346
{
347
local64_set(&event->hw.prev_count, cstate_pmu_read_counter(event));
348
}
349
350
static void cstate_pmu_event_stop(struct perf_event *event, int mode)
351
{
352
cstate_pmu_event_update(event);
353
}
354
355
static void cstate_pmu_event_del(struct perf_event *event, int mode)
356
{
357
cstate_pmu_event_stop(event, PERF_EF_UPDATE);
358
}
359
360
static int cstate_pmu_event_add(struct perf_event *event, int mode)
361
{
362
if (mode & PERF_EF_START)
363
cstate_pmu_event_start(event, mode);
364
365
return 0;
366
}
367
368
static const struct attribute_group *core_attr_update[] = {
369
&group_cstate_core_c1,
370
&group_cstate_core_c3,
371
&group_cstate_core_c6,
372
&group_cstate_core_c7,
373
NULL,
374
};
375
376
static const struct attribute_group *pkg_attr_update[] = {
377
&group_cstate_pkg_c2,
378
&group_cstate_pkg_c3,
379
&group_cstate_pkg_c6,
380
&group_cstate_pkg_c7,
381
&group_cstate_pkg_c8,
382
&group_cstate_pkg_c9,
383
&group_cstate_pkg_c10,
384
NULL,
385
};
386
387
static const struct attribute_group *module_attr_update[] = {
388
&group_cstate_module_c6,
389
NULL
390
};
391
392
static struct pmu cstate_core_pmu = {
393
.attr_groups = cstate_attr_groups,
394
.attr_update = core_attr_update,
395
.name = "cstate_core",
396
.task_ctx_nr = perf_invalid_context,
397
.event_init = cstate_pmu_event_init,
398
.add = cstate_pmu_event_add,
399
.del = cstate_pmu_event_del,
400
.start = cstate_pmu_event_start,
401
.stop = cstate_pmu_event_stop,
402
.read = cstate_pmu_event_update,
403
.capabilities = PERF_PMU_CAP_NO_INTERRUPT | PERF_PMU_CAP_NO_EXCLUDE,
404
.scope = PERF_PMU_SCOPE_CORE,
405
.module = THIS_MODULE,
406
};
407
408
static struct pmu cstate_pkg_pmu = {
409
.attr_groups = cstate_attr_groups,
410
.attr_update = pkg_attr_update,
411
.name = "cstate_pkg",
412
.task_ctx_nr = perf_invalid_context,
413
.event_init = cstate_pmu_event_init,
414
.add = cstate_pmu_event_add,
415
.del = cstate_pmu_event_del,
416
.start = cstate_pmu_event_start,
417
.stop = cstate_pmu_event_stop,
418
.read = cstate_pmu_event_update,
419
.capabilities = PERF_PMU_CAP_NO_INTERRUPT | PERF_PMU_CAP_NO_EXCLUDE,
420
.scope = PERF_PMU_SCOPE_PKG,
421
.module = THIS_MODULE,
422
};
423
424
static struct pmu cstate_module_pmu = {
425
.attr_groups = cstate_attr_groups,
426
.attr_update = module_attr_update,
427
.name = "cstate_module",
428
.task_ctx_nr = perf_invalid_context,
429
.event_init = cstate_pmu_event_init,
430
.add = cstate_pmu_event_add,
431
.del = cstate_pmu_event_del,
432
.start = cstate_pmu_event_start,
433
.stop = cstate_pmu_event_stop,
434
.read = cstate_pmu_event_update,
435
.capabilities = PERF_PMU_CAP_NO_INTERRUPT | PERF_PMU_CAP_NO_EXCLUDE,
436
.scope = PERF_PMU_SCOPE_CLUSTER,
437
.module = THIS_MODULE,
438
};
439
440
static const struct cstate_model nhm_cstates __initconst = {
441
.core_events = BIT(PERF_CSTATE_CORE_C3_RES) |
442
BIT(PERF_CSTATE_CORE_C6_RES),
443
444
.pkg_events = BIT(PERF_CSTATE_PKG_C3_RES) |
445
BIT(PERF_CSTATE_PKG_C6_RES) |
446
BIT(PERF_CSTATE_PKG_C7_RES),
447
};
448
449
static const struct cstate_model snb_cstates __initconst = {
450
.core_events = BIT(PERF_CSTATE_CORE_C3_RES) |
451
BIT(PERF_CSTATE_CORE_C6_RES) |
452
BIT(PERF_CSTATE_CORE_C7_RES),
453
454
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
455
BIT(PERF_CSTATE_PKG_C3_RES) |
456
BIT(PERF_CSTATE_PKG_C6_RES) |
457
BIT(PERF_CSTATE_PKG_C7_RES),
458
};
459
460
static const struct cstate_model hswult_cstates __initconst = {
461
.core_events = BIT(PERF_CSTATE_CORE_C3_RES) |
462
BIT(PERF_CSTATE_CORE_C6_RES) |
463
BIT(PERF_CSTATE_CORE_C7_RES),
464
465
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
466
BIT(PERF_CSTATE_PKG_C3_RES) |
467
BIT(PERF_CSTATE_PKG_C6_RES) |
468
BIT(PERF_CSTATE_PKG_C7_RES) |
469
BIT(PERF_CSTATE_PKG_C8_RES) |
470
BIT(PERF_CSTATE_PKG_C9_RES) |
471
BIT(PERF_CSTATE_PKG_C10_RES),
472
};
473
474
static const struct cstate_model cnl_cstates __initconst = {
475
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
476
BIT(PERF_CSTATE_CORE_C3_RES) |
477
BIT(PERF_CSTATE_CORE_C6_RES) |
478
BIT(PERF_CSTATE_CORE_C7_RES),
479
480
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
481
BIT(PERF_CSTATE_PKG_C3_RES) |
482
BIT(PERF_CSTATE_PKG_C6_RES) |
483
BIT(PERF_CSTATE_PKG_C7_RES) |
484
BIT(PERF_CSTATE_PKG_C8_RES) |
485
BIT(PERF_CSTATE_PKG_C9_RES) |
486
BIT(PERF_CSTATE_PKG_C10_RES),
487
};
488
489
static const struct cstate_model icl_cstates __initconst = {
490
.core_events = BIT(PERF_CSTATE_CORE_C6_RES) |
491
BIT(PERF_CSTATE_CORE_C7_RES),
492
493
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
494
BIT(PERF_CSTATE_PKG_C3_RES) |
495
BIT(PERF_CSTATE_PKG_C6_RES) |
496
BIT(PERF_CSTATE_PKG_C7_RES) |
497
BIT(PERF_CSTATE_PKG_C8_RES) |
498
BIT(PERF_CSTATE_PKG_C9_RES) |
499
BIT(PERF_CSTATE_PKG_C10_RES),
500
};
501
502
static const struct cstate_model icx_cstates __initconst = {
503
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
504
BIT(PERF_CSTATE_CORE_C6_RES),
505
506
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
507
BIT(PERF_CSTATE_PKG_C6_RES),
508
};
509
510
static const struct cstate_model adl_cstates __initconst = {
511
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
512
BIT(PERF_CSTATE_CORE_C6_RES) |
513
BIT(PERF_CSTATE_CORE_C7_RES),
514
515
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
516
BIT(PERF_CSTATE_PKG_C3_RES) |
517
BIT(PERF_CSTATE_PKG_C6_RES) |
518
BIT(PERF_CSTATE_PKG_C8_RES) |
519
BIT(PERF_CSTATE_PKG_C10_RES),
520
};
521
522
static const struct cstate_model lnl_cstates __initconst = {
523
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
524
BIT(PERF_CSTATE_CORE_C6_RES) |
525
BIT(PERF_CSTATE_CORE_C7_RES),
526
527
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
528
BIT(PERF_CSTATE_PKG_C6_RES) |
529
BIT(PERF_CSTATE_PKG_C10_RES),
530
};
531
532
static const struct cstate_model nvl_cstates __initconst = {
533
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
534
BIT(PERF_CSTATE_CORE_C6_RES) |
535
BIT(PERF_CSTATE_CORE_C7_RES),
536
537
.module_events = BIT(PERF_CSTATE_MODULE_C6_RES),
538
539
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
540
BIT(PERF_CSTATE_PKG_C6_RES) |
541
BIT(PERF_CSTATE_PKG_C10_RES),
542
};
543
544
static const struct cstate_model slm_cstates __initconst = {
545
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
546
BIT(PERF_CSTATE_CORE_C6_RES),
547
548
.pkg_events = BIT(PERF_CSTATE_PKG_C6_RES),
549
.quirks = SLM_PKG_C6_USE_C7_MSR,
550
};
551
552
553
static const struct cstate_model knl_cstates __initconst = {
554
.core_events = BIT(PERF_CSTATE_CORE_C6_RES),
555
556
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
557
BIT(PERF_CSTATE_PKG_C3_RES) |
558
BIT(PERF_CSTATE_PKG_C6_RES),
559
.quirks = KNL_CORE_C6_MSR,
560
};
561
562
563
static const struct cstate_model glm_cstates __initconst = {
564
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
565
BIT(PERF_CSTATE_CORE_C3_RES) |
566
BIT(PERF_CSTATE_CORE_C6_RES),
567
568
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
569
BIT(PERF_CSTATE_PKG_C3_RES) |
570
BIT(PERF_CSTATE_PKG_C6_RES) |
571
BIT(PERF_CSTATE_PKG_C10_RES),
572
};
573
574
static const struct cstate_model grr_cstates __initconst = {
575
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
576
BIT(PERF_CSTATE_CORE_C6_RES),
577
578
.module_events = BIT(PERF_CSTATE_MODULE_C6_RES),
579
};
580
581
static const struct cstate_model srf_cstates __initconst = {
582
.core_events = BIT(PERF_CSTATE_CORE_C1_RES) |
583
BIT(PERF_CSTATE_CORE_C6_RES),
584
585
.pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) |
586
BIT(PERF_CSTATE_PKG_C6_RES),
587
588
.module_events = BIT(PERF_CSTATE_MODULE_C6_RES),
589
};
590
591
592
static const struct x86_cpu_id intel_cstates_match[] __initconst = {
593
X86_MATCH_VFM(INTEL_NEHALEM, &nhm_cstates),
594
X86_MATCH_VFM(INTEL_NEHALEM_EP, &nhm_cstates),
595
X86_MATCH_VFM(INTEL_NEHALEM_EX, &nhm_cstates),
596
597
X86_MATCH_VFM(INTEL_WESTMERE, &nhm_cstates),
598
X86_MATCH_VFM(INTEL_WESTMERE_EP, &nhm_cstates),
599
X86_MATCH_VFM(INTEL_WESTMERE_EX, &nhm_cstates),
600
601
X86_MATCH_VFM(INTEL_SANDYBRIDGE, &snb_cstates),
602
X86_MATCH_VFM(INTEL_SANDYBRIDGE_X, &snb_cstates),
603
604
X86_MATCH_VFM(INTEL_IVYBRIDGE, &snb_cstates),
605
X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &snb_cstates),
606
607
X86_MATCH_VFM(INTEL_HASWELL, &snb_cstates),
608
X86_MATCH_VFM(INTEL_HASWELL_X, &snb_cstates),
609
X86_MATCH_VFM(INTEL_HASWELL_G, &snb_cstates),
610
611
X86_MATCH_VFM(INTEL_HASWELL_L, &hswult_cstates),
612
613
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, &slm_cstates),
614
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_D, &slm_cstates),
615
X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &slm_cstates),
616
X86_MATCH_VFM(INTEL_ATOM_AIRMONT_NP, &slm_cstates),
617
618
X86_MATCH_VFM(INTEL_BROADWELL, &snb_cstates),
619
X86_MATCH_VFM(INTEL_BROADWELL_D, &snb_cstates),
620
X86_MATCH_VFM(INTEL_BROADWELL_G, &snb_cstates),
621
X86_MATCH_VFM(INTEL_BROADWELL_X, &snb_cstates),
622
623
X86_MATCH_VFM(INTEL_SKYLAKE_L, &snb_cstates),
624
X86_MATCH_VFM(INTEL_SKYLAKE, &snb_cstates),
625
X86_MATCH_VFM(INTEL_SKYLAKE_X, &snb_cstates),
626
627
X86_MATCH_VFM(INTEL_KABYLAKE_L, &hswult_cstates),
628
X86_MATCH_VFM(INTEL_KABYLAKE, &hswult_cstates),
629
X86_MATCH_VFM(INTEL_COMETLAKE_L, &hswult_cstates),
630
X86_MATCH_VFM(INTEL_COMETLAKE, &hswult_cstates),
631
632
X86_MATCH_VFM(INTEL_CANNONLAKE_L, &cnl_cstates),
633
634
X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &knl_cstates),
635
X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &knl_cstates),
636
637
X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &glm_cstates),
638
X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D, &glm_cstates),
639
X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS, &glm_cstates),
640
X86_MATCH_VFM(INTEL_ATOM_TREMONT_D, &glm_cstates),
641
X86_MATCH_VFM(INTEL_ATOM_TREMONT, &glm_cstates),
642
X86_MATCH_VFM(INTEL_ATOM_TREMONT_L, &glm_cstates),
643
X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &adl_cstates),
644
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X, &srf_cstates),
645
X86_MATCH_VFM(INTEL_ATOM_CRESTMONT, &grr_cstates),
646
X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X, &srf_cstates),
647
648
X86_MATCH_VFM(INTEL_ICELAKE_L, &icl_cstates),
649
X86_MATCH_VFM(INTEL_ICELAKE, &icl_cstates),
650
X86_MATCH_VFM(INTEL_ICELAKE_X, &icx_cstates),
651
X86_MATCH_VFM(INTEL_ICELAKE_D, &icx_cstates),
652
X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &icx_cstates),
653
X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &icx_cstates),
654
X86_MATCH_VFM(INTEL_GRANITERAPIDS_X, &icx_cstates),
655
X86_MATCH_VFM(INTEL_GRANITERAPIDS_D, &icx_cstates),
656
X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X, &srf_cstates),
657
658
X86_MATCH_VFM(INTEL_TIGERLAKE_L, &icl_cstates),
659
X86_MATCH_VFM(INTEL_TIGERLAKE, &icl_cstates),
660
X86_MATCH_VFM(INTEL_ROCKETLAKE, &icl_cstates),
661
X86_MATCH_VFM(INTEL_ALDERLAKE, &adl_cstates),
662
X86_MATCH_VFM(INTEL_ALDERLAKE_L, &adl_cstates),
663
X86_MATCH_VFM(INTEL_RAPTORLAKE, &adl_cstates),
664
X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &adl_cstates),
665
X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &adl_cstates),
666
X86_MATCH_VFM(INTEL_METEORLAKE, &adl_cstates),
667
X86_MATCH_VFM(INTEL_METEORLAKE_L, &adl_cstates),
668
X86_MATCH_VFM(INTEL_ARROWLAKE, &adl_cstates),
669
X86_MATCH_VFM(INTEL_ARROWLAKE_H, &adl_cstates),
670
X86_MATCH_VFM(INTEL_ARROWLAKE_U, &adl_cstates),
671
X86_MATCH_VFM(INTEL_LUNARLAKE_M, &lnl_cstates),
672
X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &lnl_cstates),
673
X86_MATCH_VFM(INTEL_WILDCATLAKE_L, &lnl_cstates),
674
X86_MATCH_VFM(INTEL_NOVALAKE, &nvl_cstates),
675
X86_MATCH_VFM(INTEL_NOVALAKE_L, &nvl_cstates),
676
{ },
677
};
678
MODULE_DEVICE_TABLE(x86cpu, intel_cstates_match);
679
680
static int __init cstate_probe(const struct cstate_model *cm)
681
{
682
/* SLM has different MSR for PKG C6 */
683
if (cm->quirks & SLM_PKG_C6_USE_C7_MSR)
684
pkg_msr[PERF_CSTATE_PKG_C6_RES].msr = MSR_PKG_C7_RESIDENCY;
685
686
/* KNL has different MSR for CORE C6 */
687
if (cm->quirks & KNL_CORE_C6_MSR)
688
pkg_msr[PERF_CSTATE_CORE_C6_RES].msr = MSR_KNL_CORE_C6_RESIDENCY;
689
690
691
core_msr_mask = perf_msr_probe(core_msr, PERF_CSTATE_CORE_EVENT_MAX,
692
true, (void *) &cm->core_events);
693
694
pkg_msr_mask = perf_msr_probe(pkg_msr, PERF_CSTATE_PKG_EVENT_MAX,
695
true, (void *) &cm->pkg_events);
696
697
module_msr_mask = perf_msr_probe(module_msr, PERF_CSTATE_MODULE_EVENT_MAX,
698
true, (void *) &cm->module_events);
699
700
has_cstate_core = !!core_msr_mask;
701
has_cstate_pkg = !!pkg_msr_mask;
702
has_cstate_module = !!module_msr_mask;
703
704
return (has_cstate_core || has_cstate_pkg || has_cstate_module) ? 0 : -ENODEV;
705
}
706
707
static inline void cstate_cleanup(void)
708
{
709
if (has_cstate_core)
710
perf_pmu_unregister(&cstate_core_pmu);
711
712
if (has_cstate_pkg)
713
perf_pmu_unregister(&cstate_pkg_pmu);
714
715
if (has_cstate_module)
716
perf_pmu_unregister(&cstate_module_pmu);
717
}
718
719
static int __init cstate_init(void)
720
{
721
int err;
722
723
if (has_cstate_core) {
724
err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1);
725
if (err) {
726
has_cstate_core = false;
727
pr_info("Failed to register cstate core pmu\n");
728
cstate_cleanup();
729
return err;
730
}
731
}
732
733
if (has_cstate_pkg) {
734
if (topology_max_dies_per_package() > 1) {
735
/* CLX-AP is multi-die and the cstate is die-scope */
736
cstate_pkg_pmu.scope = PERF_PMU_SCOPE_DIE;
737
err = perf_pmu_register(&cstate_pkg_pmu,
738
"cstate_die", -1);
739
} else {
740
err = perf_pmu_register(&cstate_pkg_pmu,
741
cstate_pkg_pmu.name, -1);
742
}
743
if (err) {
744
has_cstate_pkg = false;
745
pr_info("Failed to register cstate pkg pmu\n");
746
cstate_cleanup();
747
return err;
748
}
749
}
750
751
if (has_cstate_module) {
752
err = perf_pmu_register(&cstate_module_pmu, cstate_module_pmu.name, -1);
753
if (err) {
754
has_cstate_module = false;
755
pr_info("Failed to register cstate cluster pmu\n");
756
cstate_cleanup();
757
return err;
758
}
759
}
760
return 0;
761
}
762
763
static int __init cstate_pmu_init(void)
764
{
765
const struct x86_cpu_id *id;
766
int err;
767
768
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
769
return -ENODEV;
770
771
id = x86_match_cpu(intel_cstates_match);
772
if (!id)
773
return -ENODEV;
774
775
err = cstate_probe((const struct cstate_model *) id->driver_data);
776
if (err)
777
return err;
778
779
return cstate_init();
780
}
781
module_init(cstate_pmu_init);
782
783
static void __exit cstate_pmu_exit(void)
784
{
785
cstate_cleanup();
786
}
787
module_exit(cstate_pmu_exit);
788
789