From: "David E. Box" <david.e.box@linux.intel.com>
To: corbet@lwn.net, bhelgaas@google.com, kuurtb@gmail.com,
hdegoede@redhat.com, ilpo.jarvinen@linux.intel.com,
vkoul@kernel.org, yung-chuan.liao@linux.intel.com,
pierre-louis.bossart@linux.dev, sanyog.r.kale@intel.com,
gregkh@linuxfoundation.org, rafael@kernel.org, dakr@kernel.org,
david.e.box@linux.intel.com, dan.j.williams@intel.com,
andriy.shevchenko@linux.intel.com
Cc: linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-pci@vger.kernel.org, platform-driver-x86@vger.kernel.org,
Dell.Client.Kernel@dell.com, linux-sound@vger.kernel.org
Subject: [PATCH 3/7] docs: sysfs.rst: document additional attribute group macros
Date: Wed, 23 Apr 2025 10:50:33 -0700 [thread overview]
Message-ID: <20250423175040.784680-4-david.e.box@linux.intel.com> (raw)
In-Reply-To: <20250423175040.784680-1-david.e.box@linux.intel.com>
Add documentation to Documentation/filesystems/sysfs.rst for several sysfs
helper macros, including recently introduced and previously undocumented
helpers.
Document the following macros:
__ATTR_IGNORE_LOCKDEP
DEFINE_SYSFS_GROUP_VISIBILITY
DEFINE_SYSFS_BIN_GROUP_VISIBILITY
DEFINE_SYSFS_BIN_GROUP_COMBO_VISIBILITY
ATTRIBUTE_GROUPS
BIN_ATTRIBUTE_GROUPS
NAMED_ATTRIBUTE_GROUP_VISIBLE
NAMED_ATTRIBUTE_GROUPS_VISIBLE
NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE
NAMED_ATTRIBUTE_GROUPS_COMBO_VISIBLE
Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: David E. Box <david.e.box@linux.intel.com>
---
Documentation/filesystems/sysfs.rst | 244 ++++++++++++++++++++++++++++
1 file changed, 244 insertions(+)
diff --git a/Documentation/filesystems/sysfs.rst b/Documentation/filesystems/sysfs.rst
index c32993bc83c7..16bcc3e7c80c 100644
--- a/Documentation/filesystems/sysfs.rst
+++ b/Documentation/filesystems/sysfs.rst
@@ -147,6 +147,250 @@ __ATTR_RW(name):
__ATTR_NULL:
which sets the name to NULL and is used as end of list
indicator (see: kernel/workqueue.c)
+__ATTR_IGNORE_LOCKDEP(name, mode, show, store):
+ like __ATTR() but disables lockdep checks; used in cases
+ where lockdep may emit false positives
+
+Additional Attribute Helpers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ATTRIBUTE_GROUPS(name):
+ Convenience macro to create an array of attribute group pointers.
+
+Example::
+
+ static struct attribute *foo_attrs[] = {
+ &attr1.attr,
+ &attr2.attr,
+ NULL
+ };
+ ATTRIBUTE_GROUPS(foo);
+
+BIN_ATTRIBUTE_GROUPS(name):
+ Same as ATTRIBUTE_GROUPS(), but for bin_attribute_group structures.
+
+Example::
+
+ static struct bin_attribute *foo_attrs[] = {
+ &bin_attr1.attr,
+ &bin_attr2.attr,
+ NULL
+ };
+ BIN_ATTRIBUTE_GROUPS(bin_foo);
+
+DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(name):
+ A helper macro to pair with the assignment of
+
+ ".is_visible = SYSFS_GROUP_VISIBLE(name)",
+
+ that arranges for the directory associated with a named attribute_group
+ to optionally be hidden. This allows for static declaration of
+ attribute_groups, and the simplification of attribute visibility
+ lifetime that implies, without polluting sysfs with empty attribute
+ directories.
+
+Example::
+
+ static umode_t example_attr_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+ {
+ if (example_attr_condition)
+ return 0;
+ if (ro_attr_condition)
+ return 0444;
+ return a->mode;
+ }
+
+ static bool example_group_visible(struct kobject *kobj)
+ {
+ if (example_group_condition)
+ return false;
+ return true;
+ }
+
+ DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(example);
+
+ static struct attribute_group example_group = {
+ .name = "example",
+ .is_visible = SYSFS_GROUP_VISIBLE(example),
+ .attrs = &example_attrs,
+ };
+
+Note that it expects <name>_attr_visible and <name>_group_visible to
+be defined. For cases where individual attributes do not need
+separate visibility consideration, only entire group visibility at
+once, see DEFINE_SYSFS_GROUP_VISIBILITY().
+
+DEFINE_SYSFS_GROUP_VISIBILITY(name):
+ A helper macro to pair with SYSFS_GROUP_VISIBLE() that, like
+ DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(), controls group visibility, but
+ does not require the implementation of a per-attribute visibility
+ callback.
+
+Example::
+
+ static bool example_group_visible(struct kobject *kobj)
+ {
+ if (example_group_condition)
+ return false;
+ return true;
+ }
+
+ DEFINE_SYSFS_GROUP_VISIBILITY(example);
+
+ static struct attribute_group example_group = {
+ .name = "example",
+ .is_visible = SYSFS_GROUP_VISIBLE(example),
+ .attrs = &example_attrs,
+ };
+
+DEFINE_SYSFS_BIN_GROUP_COMBO_VISIBILITY(name):
+DEFINE_SYSFS_BIN_GROUP_VISIBILITY(name):
+ Same as DEFINE_SYSFS_GROUP_VISIBILITY(), but for groups with only binary
+ attributes. If an attribute_group defines both text and binary
+ attributes, the group visibility is determined by the function
+ specified to is_visible() not is_bin_visible().
+
+Named Attribute Group Macros (with visibility)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+These macros define struct attribute_group objects with a static name and
+visibility function(s). They are useful for creating named directories in sysfs
+where individual attributes can be conditionally exposed.
+
+NAMED_ATTRIBUTE_GROUP_VISIBLE(name):
+ Defines an attribute group with a fixed directory name (matching name)
+ with a group visibility function. Expects an attribute array
+ <name>_attrs. The macro automatically defines the visibility function.
+
+Example::
+
+ static ssize_t foo_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+ ...
+ }
+
+ static ssize_t foo_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ ...
+ }
+ static DEVICE_ATTR_RW(foo);
+
+ static bool bar_group_visible(struct kobject *kobj)
+ {
+ if (bar_group_condition)
+ return false;
+ return true;
+ }
+
+ static struct attribute *bar_attrs[] = {
+ &dev_attr_foo.attr,
+ NULL
+ };
+ NAMED_ATTRIBUTE_GROUP_VISIBLE(bar);
+
+Creates::
+
+ static const struct attribute_group bar_group = {
+ .name = "bar",
+ .attrs = bar_attrs,
+ .is_visible = SYSFS_GROUP_VISIBLE(bar),
+ };
+
+ /*
+ * Where SYSFS_GROUP_VISIBLE(bar) is a function created by
+ * DEFINE_SYSFS_GROUP_VISIBILITY(bar) that calls bar_group_visible().
+ */
+
+NAMED_ATTRIBUTE_GROUPS_VISIBLE(name):
+ Like NAMED_ATTRIBUTE_GROUP_VISIBLE(), defines the visible attribute
+ group but also creates the group list <name>_groups[].
+
+Example::
+
+ ...
+
+ static struct attribute *bar_attrs[] = {
+ &attr1.attr,
+ &attr2.attr,
+ NULL
+ };
+ NAMED_ATTRIBUTE_GROUPS_VISIBLE(bar);
+
+Creates::
+
+ static const struct attribute_group bar_group = {
+ .name = "bar",
+ .attrs = bar_attrs,
+ .is_visible = SYSFS_GROUP_VISIBLE(bar),
+ };
+
+ static const struct attribute_group *bar_groups[] = {
+ &bar_group,
+ NULL
+ };
+
+NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE(name):
+ Same as NAMED_ATTRIBUTE_GROUP_VISIBLE(), but uses the "combo" visibility
+ variant to support both group and per-attribute visibility control.
+ Automatically generates the combo visibility boilerplate.
+
+Example::
+
+ static ssize_t foo_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+ {
+ ...
+ }
+
+ static ssize_t foo_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+ {
+ ...
+ }
+ static DEVICE_ATTR_RW(foo);
+
+ static umode_t foo_attr_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+ {
+ if (example_attr_condition)
+ return 0;
+ return attr->mode;
+ }
+
+ static bool foo_group_visible(struct kobject *kobj)
+ {
+ if (foo_group_condition)
+ return false;
+ return true;
+ }
+
+ static struct attribute *foo_attrs[] = {
+ &dev_attr_foo.attr,
+ NULL
+ };
+ NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE(foo);
+
+Creates::
+
+ static const struct attribute_group foo_group = {
+ .name = "foo",
+ .attrs = foo_attrs,
+ .is_visible = SYSFS_GROUP_VISIBLE(foo),
+ };
+
+ /*
+ * Where SYSFS_GROUP_VISIBLE(foo) is a function created by
+ * DEFINE_SYSFS_GROUP_COMBO_VISIBILITY(foo) that calls foo_group_visible()
+ * and foo_attr_visible().
+ */
+
+NAMED_ATTRIBUTE_GROUPS_COMBO_VISIBLE(name):
+ Like NAMED_ATTRIBUTE_GROUP_COMBO_VISIBLE() defines the attribute group,
+ supporting both group and per-attribute visibility control, but also
+ creates the group list <name>_groups[].
Subsystem-Specific Callbacks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
--
2.43.0
next prev parent reply other threads:[~2025-04-23 17:50 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-23 17:50 [PATCH 0/7] sysfs: Introduce macros for attribute groups with visibility control David E. Box
2025-04-23 17:50 ` [PATCH 1/7] sysfs: Rename attribute group visibility macros David E. Box
2025-04-24 1:26 ` Dan Williams
2025-04-23 17:50 ` [PATCH 2/7] sysfs: Introduce macros to simplify creation of visible attribute groups David E. Box
2025-04-24 1:32 ` Dan Williams
2025-04-23 17:50 ` David E. Box [this message]
2025-04-24 1:34 ` [PATCH 3/7] docs: sysfs.rst: document additional attribute group macros Dan Williams
2025-04-23 17:50 ` [PATCH 4/7] pci: doe: Replace sysfs visibility macro David E. Box
2025-04-24 1:35 ` Dan Williams
2025-04-25 10:57 ` Ilpo Järvinen
2025-04-25 18:13 ` David E. Box
2025-04-26 13:06 ` Ilpo Järvinen
2025-04-23 17:50 ` [PATCH 5/7] soundwire: sysfs: Use ATTRIBUTE_GROUP_VISIBLE() David E. Box
2025-04-24 1:37 ` Dan Williams
2025-04-23 17:50 ` [PATCH 6/7] platform/x86/dell: alienware-wmi: update sysfs visibility macros David E. Box
2025-04-23 18:31 ` Kurt Borja
2025-04-24 3:01 ` Dan Williams
2025-04-23 17:50 ` [PATCH 7/7] sysfs: Remove transitional attribute group alias macros David E. Box
2025-04-24 3:02 ` Dan Williams
2025-05-07 7:07 ` kernel test robot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250423175040.784680-4-david.e.box@linux.intel.com \
--to=david.e.box@linux.intel.com \
--cc=Dell.Client.Kernel@dell.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bhelgaas@google.com \
--cc=corbet@lwn.net \
--cc=dakr@kernel.org \
--cc=dan.j.williams@intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=hdegoede@redhat.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=kuurtb@gmail.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=pierre-louis.bossart@linux.dev \
--cc=platform-driver-x86@vger.kernel.org \
--cc=rafael@kernel.org \
--cc=sanyog.r.kale@intel.com \
--cc=vkoul@kernel.org \
--cc=yung-chuan.liao@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.