[PATCH v25 01/10] drivers/base: refactor cpu.c to use .is_visible()

From: Eric DeVolder
Date: Thu Jun 29 2023 - 15:24:09 EST


Greg Kroah-Hartman requested that this file use the .is_visible()
method instead of #ifdefs for the attributes in cpu.c.

static struct attribute *cpu_root_attrs[] = {
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
&dev_attr_probe.attr,
&dev_attr_release.attr,
#endif
&cpu_attrs[0].attr.attr,
&cpu_attrs[1].attr.attr,
&cpu_attrs[2].attr.attr,
&dev_attr_kernel_max.attr,
&dev_attr_offline.attr,
&dev_attr_isolated.attr,
#ifdef CONFIG_NO_HZ_FULL
&dev_attr_nohz_full.attr,
#endif
#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
&dev_attr_modalias.attr,
#endif
NULL
};

To that end:
- the .is_visible() method is implemented, and IS_ENABLED(), rather
than #ifdef, is used to determine the visibility of the attribute.
- the DEVICE_ATTR() attributes are moved outside of #ifdefs, so that
those structs are always present for the cpu_root_attrs[].
- the function body of the callback functions are now wrapped with
IS_ENABLED(); as the callback function must exist now that the
attribute is always compiled-in (though not necessarily visible).

No functionality change intended.

Signed-off-by: Eric DeVolder <eric.devolder@xxxxxxxxxx>
---
drivers/base/cpu.c | 125 +++++++++++++++++++++++++++----------------
include/linux/tick.h | 2 +-
2 files changed, 81 insertions(+), 46 deletions(-)

diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index c1815b9dae68..2455cbcebc87 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -82,24 +82,27 @@ void unregister_cpu(struct cpu *cpu)
per_cpu(cpu_sys_devices, logical_cpu) = NULL;
return;
}
+#endif /* CONFIG_HOTPLUG_CPU */

-#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
static ssize_t cpu_probe_store(struct device *dev,
struct device_attribute *attr,
const char *buf,
size_t count)
{
- ssize_t cnt;
- int ret;
+ if (IS_ENABLED(CONFIG_ARCH_CPU_PROBE_RELEASE)) {
+ ssize_t cnt;
+ int ret;

- ret = lock_device_hotplug_sysfs();
- if (ret)
- return ret;
+ ret = lock_device_hotplug_sysfs();
+ if (ret)
+ return ret;

- cnt = arch_cpu_probe(buf, count);
+ cnt = arch_cpu_probe(buf, count);

- unlock_device_hotplug();
- return cnt;
+ unlock_device_hotplug();
+ return cnt;
+ }
+ return 0;
}

static ssize_t cpu_release_store(struct device *dev,
@@ -107,23 +110,24 @@ static ssize_t cpu_release_store(struct device *dev,
const char *buf,
size_t count)
{
- ssize_t cnt;
- int ret;
+ if (IS_ENABLED(CONFIG_ARCH_CPU_PROBE_RELEASE)) {
+ ssize_t cnt;
+ int ret;

- ret = lock_device_hotplug_sysfs();
- if (ret)
- return ret;
+ ret = lock_device_hotplug_sysfs();
+ if (ret)
+ return ret;

- cnt = arch_cpu_release(buf, count);
+ cnt = arch_cpu_release(buf, count);

- unlock_device_hotplug();
- return cnt;
+ unlock_device_hotplug();
+ return cnt;
+ }
+ return 0;
}

static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
-#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
-#endif /* CONFIG_HOTPLUG_CPU */

#ifdef CONFIG_KEXEC
#include <linux/kexec.h>
@@ -273,14 +277,14 @@ static ssize_t print_cpus_isolated(struct device *dev,
}
static DEVICE_ATTR(isolated, 0444, print_cpus_isolated, NULL);

-#ifdef CONFIG_NO_HZ_FULL
static ssize_t print_cpus_nohz_full(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask));
+ if (IS_ENABLED(CONFIG_NO_HZ_FULL))
+ return sysfs_emit(buf, "%*pbl\n", cpumask_pr_args(tick_nohz_full_mask));
+ return 0;
}
static DEVICE_ATTR(nohz_full, 0444, print_cpus_nohz_full, NULL);
-#endif

static void cpu_device_release(struct device *dev)
{
@@ -301,30 +305,32 @@ static void cpu_device_release(struct device *dev)
*/
}

-#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
static ssize_t print_cpu_modalias(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int len = 0;
- u32 i;
-
- len += sysfs_emit_at(buf, len,
- "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
- CPU_FEATURE_TYPEVAL);
-
- for (i = 0; i < MAX_CPU_FEATURES; i++)
- if (cpu_have_feature(i)) {
- if (len + sizeof(",XXXX\n") >= PAGE_SIZE) {
- WARN(1, "CPU features overflow page\n");
- break;
+ if (IS_ENABLED(CONFIG_GENERIC_CPU_AUTOPROBE)) {
+ u32 i;
+
+ len += sysfs_emit_at(buf, len,
+ "cpu:type:" CPU_FEATURE_TYPEFMT ":feature:",
+ CPU_FEATURE_TYPEVAL);
+
+ for (i = 0; i < MAX_CPU_FEATURES; i++)
+ if (cpu_have_feature(i)) {
+ if (len + sizeof(",XXXX\n") >= PAGE_SIZE) {
+ WARN(1, "CPU features overflow page\n");
+ break;
+ }
+ len += sysfs_emit_at(buf, len, ",%04X", i);
}
- len += sysfs_emit_at(buf, len, ",%04X", i);
- }
- len += sysfs_emit_at(buf, len, "\n");
+ len += sysfs_emit_at(buf, len, "\n");
+ }
return len;
}

+#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
static int cpu_uevent(const struct device *dev, struct kobj_uevent_env *env)
{
char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
@@ -451,32 +457,61 @@ struct device *cpu_device_create(struct device *parent, void *drvdata,
}
EXPORT_SYMBOL_GPL(cpu_device_create);

-#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL);
-#endif

static struct attribute *cpu_root_attrs[] = {
-#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
&dev_attr_probe.attr,
&dev_attr_release.attr,
-#endif
&cpu_attrs[0].attr.attr,
&cpu_attrs[1].attr.attr,
&cpu_attrs[2].attr.attr,
&dev_attr_kernel_max.attr,
&dev_attr_offline.attr,
&dev_attr_isolated.attr,
-#ifdef CONFIG_NO_HZ_FULL
&dev_attr_nohz_full.attr,
-#endif
-#ifdef CONFIG_GENERIC_CPU_AUTOPROBE
&dev_attr_modalias.attr,
-#endif
NULL
};

+static umode_t
+cpu_root_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int unused)
+{
+ umode_t mode = attr->mode;
+
+ if (IS_ENABLED(CONFIG_ARCH_CPU_PROBE_RELEASE)) {
+ if (attr == &dev_attr_probe.attr)
+ return mode;
+ if (attr == &dev_attr_release.attr)
+ return mode;
+ }
+ if (attr == &cpu_attrs[0].attr.attr)
+ return mode;
+ if (attr == &cpu_attrs[1].attr.attr)
+ return mode;
+ if (attr == &cpu_attrs[2].attr.attr)
+ return mode;
+ if (attr == &dev_attr_kernel_max.attr)
+ return mode;
+ if (attr == &dev_attr_offline.attr)
+ return mode;
+ if (attr == &dev_attr_isolated.attr)
+ return mode;
+ if (IS_ENABLED(CONFIG_NO_HZ_FULL)) {
+ if (attr == &dev_attr_nohz_full.attr)
+ return mode;
+ }
+ if (IS_ENABLED(CONFIG_GENERIC_CPU_AUTOPROBE)) {
+ if (attr == &dev_attr_modalias.attr)
+ return mode;
+ }
+
+ return 0;
+}
+
static const struct attribute_group cpu_root_attr_group = {
.attrs = cpu_root_attrs,
+ .is_visible = cpu_root_attr_is_visible,
};

static const struct attribute_group *cpu_root_attr_groups[] = {
diff --git a/include/linux/tick.h b/include/linux/tick.h
index 9459fef5b857..a05fdd4b21f4 100644
--- a/include/linux/tick.h
+++ b/include/linux/tick.h
@@ -174,9 +174,9 @@ static inline u64 get_cpu_iowait_time_us(int cpu, u64 *unused) { return -1; }
static inline void tick_nohz_idle_stop_tick_protected(void) { }
#endif /* !CONFIG_NO_HZ_COMMON */

+extern cpumask_var_t tick_nohz_full_mask;
#ifdef CONFIG_NO_HZ_FULL
extern bool tick_nohz_full_running;
-extern cpumask_var_t tick_nohz_full_mask;

static inline bool tick_nohz_full_enabled(void)
{
--
2.31.1