Commit 6bceea7a authored by Ricardo Neri's avatar Ricardo Neri Committed by Rafael J. Wysocki
Browse files

arch_topology: Relocate cpu_scale to topology.[h|c]



arch_topology.c provides functionality to parse and scale CPU capacity.
It also provides a corresponding sysfs interface. Some architectures
parse and scale CPU capacity differently as per their own needs. On
Intel processors, for instance, it is responsibility of the Intel
P-state driver.

Relocate the implementation of that interface to a common location in
topology.c. Architectures can use the interface and populate it using
their own mechanisms.

An alternative approach would be to compile arch_topology.c even if
not needed only to get this interface. This approach would create
duplicated and conflicting functionality and data structures.

Signed-off-by: default avatarRicardo Neri <ricardo.neri-calderon@linux.intel.com>
Tested-by: default avatarChristian Loehle <christian.loehle@arm.com>
Link: https://patch.msgid.link/20250419025504.9760-2-ricardo.neri-calderon@linux.intel.com


Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 4854649b
Loading
Loading
Loading
Loading
+0 −52
Original line number Diff line number Diff line
@@ -154,14 +154,6 @@ void topology_set_freq_scale(const struct cpumask *cpus, unsigned long cur_freq,
		per_cpu(arch_freq_scale, i) = scale;
}

DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
EXPORT_PER_CPU_SYMBOL_GPL(cpu_scale);

void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity)
{
	per_cpu(cpu_scale, cpu) = capacity;
}

DEFINE_PER_CPU(unsigned long, hw_pressure);

/**
@@ -207,53 +199,9 @@ void topology_update_hw_pressure(const struct cpumask *cpus,
}
EXPORT_SYMBOL_GPL(topology_update_hw_pressure);

static ssize_t cpu_capacity_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
{
	struct cpu *cpu = container_of(dev, struct cpu, dev);

	return sysfs_emit(buf, "%lu\n", topology_get_cpu_scale(cpu->dev.id));
}

static void update_topology_flags_workfn(struct work_struct *work);
static DECLARE_WORK(update_topology_flags_work, update_topology_flags_workfn);

static DEVICE_ATTR_RO(cpu_capacity);

static int cpu_capacity_sysctl_add(unsigned int cpu)
{
	struct device *cpu_dev = get_cpu_device(cpu);

	if (!cpu_dev)
		return -ENOENT;

	device_create_file(cpu_dev, &dev_attr_cpu_capacity);

	return 0;
}

static int cpu_capacity_sysctl_remove(unsigned int cpu)
{
	struct device *cpu_dev = get_cpu_device(cpu);

	if (!cpu_dev)
		return -ENOENT;

	device_remove_file(cpu_dev, &dev_attr_cpu_capacity);

	return 0;
}

static int register_cpu_capacity_sysctl(void)
{
	cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "topology/cpu-capacity",
			  cpu_capacity_sysctl_add, cpu_capacity_sysctl_remove);

	return 0;
}
subsys_initcall(register_cpu_capacity_sysctl);

static int update_topology;

int topology_update_cpu_topology(void)
+52 −0
Original line number Diff line number Diff line
@@ -208,3 +208,55 @@ static int __init topology_sysfs_init(void)
}

device_initcall(topology_sysfs_init);

DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
EXPORT_PER_CPU_SYMBOL_GPL(cpu_scale);

void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity)
{
	per_cpu(cpu_scale, cpu) = capacity;
}

static ssize_t cpu_capacity_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
{
	struct cpu *cpu = container_of(dev, struct cpu, dev);

	return sysfs_emit(buf, "%lu\n", topology_get_cpu_scale(cpu->dev.id));
}

static DEVICE_ATTR_RO(cpu_capacity);

static int cpu_capacity_sysctl_add(unsigned int cpu)
{
	struct device *cpu_dev = get_cpu_device(cpu);

	if (!cpu_dev)
		return -ENOENT;

	device_create_file(cpu_dev, &dev_attr_cpu_capacity);

	return 0;
}

static int cpu_capacity_sysctl_remove(unsigned int cpu)
{
	struct device *cpu_dev = get_cpu_device(cpu);

	if (!cpu_dev)
		return -ENOENT;

	device_remove_file(cpu_dev, &dev_attr_cpu_capacity);

	return 0;
}

static int register_cpu_capacity_sysctl(void)
{
	cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "topology/cpu-capacity",
			  cpu_capacity_sysctl_add, cpu_capacity_sysctl_remove);

	return 0;
}
subsys_initcall(register_cpu_capacity_sysctl);
+0 −8
Original line number Diff line number Diff line
@@ -14,14 +14,6 @@ int topology_update_cpu_topology(void);
struct device_node;
bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu);

DECLARE_PER_CPU(unsigned long, cpu_scale);

static inline unsigned long topology_get_cpu_scale(int cpu)
{
	return per_cpu(cpu_scale, cpu);
}

void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity);

DECLARE_PER_CPU(unsigned long, capacity_freq_ref);

+9 −0
Original line number Diff line number Diff line
@@ -332,4 +332,13 @@ sched_numa_hop_mask(unsigned int node, unsigned int hops)
	     !IS_ERR_OR_NULL(mask);					       \
	     __hops++)

DECLARE_PER_CPU(unsigned long, cpu_scale);

static inline unsigned long topology_get_cpu_scale(int cpu)
{
	return per_cpu(cpu_scale, cpu);
}

void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity);

#endif /* _LINUX_TOPOLOGY_H */