netconsole: Introduce configfs helpers for sysdata features

This patch introduces a bitfield to store sysdata features in the
netconsole_target struct. It also adds configfs helpers to enable
or disable the CPU_NR feature, which populates the CPU number in
sysdata.

The patch provides the necessary infrastructure to set or unset the
CPU_NR feature, but does not modify the message itself.

Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Breno Leitao 2025-02-06 03:05:55 -08:00 committed by David S. Miller
parent 563fe939a8
commit 364f67837e

View File

@ -97,6 +97,15 @@ struct netconsole_target_stats {
struct u64_stats_sync syncp;
};
/* Features enabled in sysdata. Contrary to userdata, this data is populated by
* the kernel. The fields are designed as bitwise flags, allowing multiple
* features to be set in sysdata_fields.
*/
enum sysdata_feature {
/* Populate the CPU that sends the message */
CPU_NR = BIT(0),
};
/**
* struct netconsole_target - Represents a configured netconsole target.
* @list: Links this target into the target_list.
@ -104,6 +113,7 @@ struct netconsole_target_stats {
* @userdata_group: Links to the userdata configfs hierarchy
* @extradata_complete: Cached, formatted string of append
* @userdata_length: String length of usedata in extradata_complete.
* @sysdata_fields: Sysdata features enabled.
* @stats: Packet send stats for the target. Used for debugging.
* @enabled: On / off knob to enable / disable target.
* Visible from userspace (read-write).
@ -132,6 +142,8 @@ struct netconsole_target {
struct config_group userdata_group;
char extradata_complete[MAX_EXTRADATA_ENTRY_LEN * MAX_EXTRADATA_ITEMS];
size_t userdata_length;
/* bit-wise with sysdata_feature bits */
u32 sysdata_fields;
#endif
struct netconsole_target_stats stats;
bool enabled;
@ -399,6 +411,19 @@ static ssize_t transmit_errors_show(struct config_item *item, char *buf)
return sysfs_emit(buf, "%llu\n", xmit_drop_count + enomem_count);
}
/* configfs helper to display if cpu_nr sysdata feature is enabled */
static ssize_t sysdata_cpu_nr_enabled_show(struct config_item *item, char *buf)
{
struct netconsole_target *nt = to_target(item->ci_parent);
bool cpu_nr_enabled;
mutex_lock(&dynamic_netconsole_mutex);
cpu_nr_enabled = !!(nt->sysdata_fields & CPU_NR);
mutex_unlock(&dynamic_netconsole_mutex);
return sysfs_emit(buf, "%d\n", cpu_nr_enabled);
}
/*
* This one is special -- targets created through the configfs interface
* are not enabled (and the corresponding netpoll activated) by default.
@ -793,7 +818,62 @@ static ssize_t userdatum_value_store(struct config_item *item, const char *buf,
return ret;
}
/* disable_sysdata_feature - Disable sysdata feature and clean sysdata
* @nt: target that is disabling the feature
* @feature: feature being disabled
*/
static void disable_sysdata_feature(struct netconsole_target *nt,
enum sysdata_feature feature)
{
nt->sysdata_fields &= ~feature;
nt->extradata_complete[nt->userdata_length] = 0;
}
/* configfs helper to sysdata cpu_nr feature */
static ssize_t sysdata_cpu_nr_enabled_store(struct config_item *item,
const char *buf, size_t count)
{
struct netconsole_target *nt = to_target(item->ci_parent);
bool cpu_nr_enabled, curr;
ssize_t ret;
ret = kstrtobool(buf, &cpu_nr_enabled);
if (ret)
return ret;
mutex_lock(&dynamic_netconsole_mutex);
curr = nt->sysdata_fields & CPU_NR;
if (cpu_nr_enabled == curr)
/* no change requested */
goto unlock_ok;
if (cpu_nr_enabled &&
count_extradata_entries(nt) >= MAX_EXTRADATA_ITEMS) {
/* user wants the new feature, but there is no space in the
* buffer.
*/
ret = -ENOSPC;
goto unlock;
}
if (cpu_nr_enabled)
nt->sysdata_fields |= CPU_NR;
else
/* This is special because extradata_complete might have
* remaining data from previous sysdata, and it needs to be
* cleaned.
*/
disable_sysdata_feature(nt, CPU_NR);
unlock_ok:
ret = strnlen(buf, count);
unlock:
mutex_unlock(&dynamic_netconsole_mutex);
return ret;
}
CONFIGFS_ATTR(userdatum_, value);
CONFIGFS_ATTR(sysdata_, cpu_nr_enabled);
static struct configfs_attribute *userdatum_attrs[] = {
&userdatum_attr_value,
@ -853,6 +933,7 @@ static void userdatum_drop(struct config_group *group, struct config_item *item)
}
static struct configfs_attribute *userdata_attrs[] = {
&sysdata_attr_cpu_nr_enabled,
NULL,
};