Skip to content

Commit bb20421

Browse files
Perry Yuanbp3tk0v
authored andcommitted
platform/x86: hfi: Add online and offline callback support
There are some firmware parameters that need to be configured when a CPU core is brought online or offline. When a CPU is online, it will initialize the workload classification parameters to CPU firmware which will trigger the workload class ID updating function. Once the CPU is going offline, it will need to disable the workload classification function and clear the history. Signed-off-by: Perry Yuan <[email protected]> Co-developed-by: Mario Limonciello <[email protected]> Signed-off-by: Mario Limonciello <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Reviewed-by: Gautham R. Shenoy <[email protected]> Acked-by: Ilpo Järvinen <[email protected]> Link: https://lore.kernel.org/[email protected]
1 parent b6ffe4d commit bb20421

File tree

1 file changed

+88
-0
lines changed
  • drivers/platform/x86/amd/hfi

1 file changed

+88
-0
lines changed

drivers/platform/x86/amd/hfi/hfi.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ struct amd_hfi_classes {
9292
* struct amd_hfi_cpuinfo - HFI workload class info per CPU
9393
* @cpu: CPU index
9494
* @apic_id: APIC id of the current CPU
95+
* @cpus: mask of CPUs associated with amd_hfi_cpuinfo
9596
* @class_index: workload class ID index
9697
* @nr_class: max number of workload class supported
9798
* @ipcc_scores: ipcc scores for each class
@@ -102,6 +103,7 @@ struct amd_hfi_classes {
102103
struct amd_hfi_cpuinfo {
103104
int cpu;
104105
u32 apic_id;
106+
cpumask_var_t cpus;
105107
s16 class_index;
106108
u8 nr_class;
107109
int *ipcc_scores;
@@ -110,6 +112,8 @@ struct amd_hfi_cpuinfo {
110112

111113
static DEFINE_PER_CPU(struct amd_hfi_cpuinfo, amd_hfi_cpuinfo) = {.class_index = -1};
112114

115+
static DEFINE_MUTEX(hfi_cpuinfo_lock);
116+
113117
static int find_cpu_index_by_apicid(unsigned int target_apicid)
114118
{
115119
int cpu_index;
@@ -237,6 +241,81 @@ static int amd_set_hfi_ipcc_score(struct amd_hfi_cpuinfo *hfi_cpuinfo, int cpu)
237241
return 0;
238242
}
239243

244+
static int amd_hfi_set_state(unsigned int cpu, bool state)
245+
{
246+
int ret;
247+
248+
ret = wrmsrq_on_cpu(cpu, MSR_AMD_WORKLOAD_CLASS_CONFIG, state ? 1 : 0);
249+
if (ret)
250+
return ret;
251+
252+
return wrmsrq_on_cpu(cpu, MSR_AMD_WORKLOAD_HRST, 0x1);
253+
}
254+
255+
/**
256+
* amd_hfi_online() - Enable workload classification on @cpu
257+
* @cpu: CPU in which the workload classification will be enabled
258+
*
259+
* Return: 0 on success, negative error code on failure.
260+
*/
261+
static int amd_hfi_online(unsigned int cpu)
262+
{
263+
struct amd_hfi_cpuinfo *hfi_info = per_cpu_ptr(&amd_hfi_cpuinfo, cpu);
264+
struct amd_hfi_classes *hfi_classes;
265+
int ret;
266+
267+
if (WARN_ON_ONCE(!hfi_info))
268+
return -EINVAL;
269+
270+
/*
271+
* Check if @cpu as an associated, initialized and ranking data must
272+
* be filled.
273+
*/
274+
hfi_classes = hfi_info->amd_hfi_classes;
275+
if (!hfi_classes)
276+
return -EINVAL;
277+
278+
guard(mutex)(&hfi_cpuinfo_lock);
279+
280+
if (!zalloc_cpumask_var(&hfi_info->cpus, GFP_KERNEL))
281+
return -ENOMEM;
282+
283+
cpumask_set_cpu(cpu, hfi_info->cpus);
284+
285+
ret = amd_hfi_set_state(cpu, true);
286+
if (ret)
287+
pr_err("WCT enable failed for CPU %u\n", cpu);
288+
289+
return ret;
290+
}
291+
292+
/**
293+
* amd_hfi_offline() - Disable workload classification on @cpu
294+
* @cpu: CPU in which the workload classification will be disabled
295+
*
296+
* Remove @cpu from those covered by its HFI instance.
297+
*
298+
* Return: 0 on success, negative error code on failure
299+
*/
300+
static int amd_hfi_offline(unsigned int cpu)
301+
{
302+
struct amd_hfi_cpuinfo *hfi_info = &per_cpu(amd_hfi_cpuinfo, cpu);
303+
int ret;
304+
305+
if (WARN_ON_ONCE(!hfi_info))
306+
return -EINVAL;
307+
308+
guard(mutex)(&hfi_cpuinfo_lock);
309+
310+
ret = amd_hfi_set_state(cpu, false);
311+
if (ret)
312+
pr_err("WCT disable failed for CPU %u\n", cpu);
313+
314+
free_cpumask_var(hfi_info->cpus);
315+
316+
return ret;
317+
}
318+
240319
static int update_hfi_ipcc_scores(void)
241320
{
242321
int cpu;
@@ -339,6 +418,15 @@ static int amd_hfi_probe(struct platform_device *pdev)
339418
if (ret)
340419
return ret;
341420

421+
/*
422+
* Tasks will already be running at the time this happens. This is
423+
* OK because rankings will be adjusted by the callbacks.
424+
*/
425+
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/amd_hfi:online",
426+
amd_hfi_online, amd_hfi_offline);
427+
if (ret < 0)
428+
return ret;
429+
342430
return 0;
343431
}
344432

0 commit comments

Comments
 (0)