Re: [PATCH RFC] gpio: sim: access sysfs attributes as const
From: Thomas Weißschuh
Date: Fri Oct 16 2026 - 05:08:10 EST
Hi Bartosz!
On Fri, Oct 16, 2026 at 10:13:50AM +0200, Bartosz Golaszewski wrote:
> Use the const variant of constainer_of() to access struct
> gpio_sim_attribute which wraps the dynamically allocated sysfs
> attributes for value and pull of simulated GPIO lines in line with the
> currently preferred approach.
>
> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxxxxxxxx>
> ---
> Following your talk, I'm sending a patch for the GPIO simulator module
> that attempts to constify the sysfs attributes. Please tell me if this
> is all I need here as the attributes are part of another struct that's
> allocated dynamically. I'm not sure if there's anything more to do here.
> ---
> drivers/gpio/gpio-sim.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c
> index 0c73bec042670fc5706b4a93700e652cbaf3605e..e0ae586cd08d8adbb3c16918607074fce116654e 100644
> --- a/drivers/gpio/gpio-sim.c
> +++ b/drivers/gpio/gpio-sim.c
> @@ -59,10 +59,10 @@ struct gpio_sim_attribute {
> unsigned int offset;
> };
>
> -static struct gpio_sim_attribute *
> +static const struct gpio_sim_attribute *
> to_gpio_sim_attr(struct device_attribute *dev_attr)
> {
> - return container_of(dev_attr, struct gpio_sim_attribute, dev_attr);
> + return container_of_const(dev_attr, struct gpio_sim_attribute, dev_attr);
> }
>
> static int gpio_sim_apply_pull(struct gpio_sim_chip *chip,
> @@ -272,7 +272,7 @@ static void gpio_sim_dbg_show(struct seq_file *seq, struct gpio_chip *gc)
> static ssize_t gpio_sim_sysfs_val_show(struct device *dev,
> struct device_attribute *attr, char *buf)
> {
> - struct gpio_sim_attribute *line_attr = to_gpio_sim_attr(attr);
> + const struct gpio_sim_attribute *line_attr = to_gpio_sim_attr(attr);
> struct gpio_sim_chip *chip = dev_get_drvdata(dev);
> int val;
>
> @@ -302,7 +302,7 @@ static ssize_t gpio_sim_sysfs_pull_show(struct device *dev,
> struct device_attribute *attr,
> char *buf)
> {
> - struct gpio_sim_attribute *line_attr = to_gpio_sim_attr(attr);
> + const struct gpio_sim_attribute *line_attr = to_gpio_sim_attr(attr);
> struct gpio_sim_chip *chip = dev_get_drvdata(dev);
> int pull;
>
> @@ -316,7 +316,7 @@ static ssize_t gpio_sim_sysfs_pull_store(struct device *dev,
> struct device_attribute *attr,
> const char *buf, size_t len)
> {
> - struct gpio_sim_attribute *line_attr = to_gpio_sim_attr(attr);
> + const struct gpio_sim_attribute *line_attr = to_gpio_sim_attr(attr);
> struct gpio_sim_chip *chip = dev_get_drvdata(dev);
> int ret, pull;
You should also use the _const APIs for the dynamically allocated attributes.
While does not improve security here, it makes it clearer that the callbacks
are not supposed to change these structures and will allow us to remove the
non-const variants later. See below:
diff --git a/drivers/gpio/gpio-sim.c b/drivers/gpio/gpio-sim.c
index e0ae586cd08d..34b45d0d3575 100644
--- a/drivers/gpio/gpio-sim.c
+++ b/drivers/gpio/gpio-sim.c
@@ -60,7 +60,7 @@ struct gpio_sim_attribute {
};
static const struct gpio_sim_attribute *
-to_gpio_sim_attr(struct device_attribute *dev_attr)
+to_gpio_sim_attr(const struct device_attribute *dev_attr)
{
return container_of_const(dev_attr, struct gpio_sim_attribute, dev_attr);
}
@@ -270,7 +270,7 @@ static void gpio_sim_dbg_show(struct seq_file *seq, struct gpio_chip *gc)
}
static ssize_t gpio_sim_sysfs_val_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ const struct device_attribute *attr, char *buf)
{
const struct gpio_sim_attribute *line_attr = to_gpio_sim_attr(attr);
struct gpio_sim_chip *chip = dev_get_drvdata(dev);
@@ -283,7 +283,7 @@ static ssize_t gpio_sim_sysfs_val_show(struct device *dev,
}
static ssize_t gpio_sim_sysfs_val_store(struct device *dev,
- struct device_attribute *attr,
+ const struct device_attribute *attr,
const char *buf, size_t count)
{
/*
@@ -299,7 +299,7 @@ static const char *const gpio_sim_sysfs_pull_strings[] = {
};
static ssize_t gpio_sim_sysfs_pull_show(struct device *dev,
- struct device_attribute *attr,
+ const struct device_attribute *attr,
char *buf)
{
const struct gpio_sim_attribute *line_attr = to_gpio_sim_attr(attr);
@@ -313,7 +313,7 @@ static ssize_t gpio_sim_sysfs_pull_show(struct device *dev,
}
static ssize_t gpio_sim_sysfs_pull_store(struct device *dev,
- struct device_attribute *attr,
+ const struct device_attribute *attr,
const char *buf, size_t len)
{
const struct gpio_sim_attribute *line_attr = to_gpio_sim_attr(attr);
@@ -361,7 +361,7 @@ static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip)
unsigned int num_lines = chip->gc.ngpio;
struct device *dev = chip->gc.parent;
struct attribute_group *attr_group;
- struct attribute **attrs;
+ const struct attribute **attrs;
int i, ret;
chip->attr_groups = devm_kcalloc(dev, sizeof(*chip->attr_groups),
@@ -396,15 +396,15 @@ static int gpio_sim_setup_sysfs(struct gpio_sim_chip *chip)
val_dev_attr->attr.mode = pull_dev_attr->attr.mode = 0644;
- val_dev_attr->show = gpio_sim_sysfs_val_show;
- val_dev_attr->store = gpio_sim_sysfs_val_store;
- pull_dev_attr->show = gpio_sim_sysfs_pull_show;
- pull_dev_attr->store = gpio_sim_sysfs_pull_store;
+ val_dev_attr->show_const = gpio_sim_sysfs_val_show;
+ val_dev_attr->store_const = gpio_sim_sysfs_val_store;
+ pull_dev_attr->show_const = gpio_sim_sysfs_pull_show;
+ pull_dev_attr->store_const = gpio_sim_sysfs_pull_store;
attrs[0] = &val_dev_attr->attr;
attrs[1] = &pull_dev_attr->attr;
- attr_group->attrs = attrs;
+ attr_group->attrs_const = attrs;
chip->attr_groups[i] = attr_group;
}
As you are touching this file anyways, you could also prepare it for the
constification of configfs attributes. See the example below, the same for the
other instances in the file. The necessary infrastructure will be part of the
next merge window.
@@ -1505,7 +1505,7 @@ static const struct configfs_group_operations gpio_sim_bank_config_group_ops = {
static const struct config_item_type gpio_sim_bank_config_group_type = {
.ct_item_ops = &gpio_sim_bank_config_item_ops,
.ct_group_ops = &gpio_sim_bank_config_group_ops,
- .ct_attrs = gpio_sim_bank_config_attrs,
+ .ct_attrs_const = gpio_sim_bank_config_attrs,
.ct_owner = THIS_MODULE,
};
@@ -1154,7 +1154,7 @@ gpio_sim_bank_config_num_lines_store(struct config_item *item,
CONFIGFS_ATTR(gpio_sim_bank_config_, num_lines);
-static struct configfs_attribute *gpio_sim_bank_config_attrs[] = {
+static const struct configfs_attribute *const gpio_sim_bank_config_attrs[] = {
&gpio_sim_bank_config_attr_chip_name,
&gpio_sim_bank_config_attr_label,
&gpio_sim_bank_config_attr_num_lines,