[PATCH v3 1/3] drm/xe: Add configfs to enable survivability mode
Upadhyay, Tejas
tejas.upadhyay at intel.com
Thu Apr 3 13:15:06 UTC 2025
> -----Original Message-----
> From: Intel-xe <intel-xe-bounces at lists.freedesktop.org> On Behalf Of Riana
> Tauro
> Sent: 03 April 2025 15:56
> To: intel-xe at lists.freedesktop.org
> Cc: Tauro, Riana <riana.tauro at intel.com>; Gupta, Anshuman
> <anshuman.gupta at intel.com>; Vivi, Rodrigo <rodrigo.vivi at intel.com>; De
> Marchi, Lucas <lucas.demarchi at intel.com>; Roper, Matthew D
> <matthew.d.roper at intel.com>; aravind.iddamsetty at linux.intel.com
> Subject: [PATCH v3 1/3] drm/xe: Add configfs to enable survivability mode
>
> Registers a configfs subsystem called 'xe' that creates a directory in the
> mounted configfs directory (/sys/kernel/config) Userspace can then create the
I see xe_configfs module itself is generating pci device directory under /sys/kernel/config/xe/, then what do we mean by "Userspace can create the device" which Userspace we are referring ?
Tejas
> device that has to be configured under the xe directory
>
> mkdir /sys/kernel/config/xe/0000:03:00.0
>
> The device created will have the following attributes to be configured
>
> /sys/kernel/config/xe/
> .. 0000:03:00.0/
> ... survivability_mode
>
> v2: fix kernel-doc
> fix return value (Lucas)
>
> Signed-off-by: Riana Tauro <riana.tauro at intel.com>
> ---
> Documentation/gpu/xe/index.rst | 1 +
> Documentation/gpu/xe/xe_configfs.rst | 10 ++
> drivers/gpu/drm/xe/Makefile | 1 +
> drivers/gpu/drm/xe/xe_configfs.c | 190 +++++++++++++++++++++++++++
> drivers/gpu/drm/xe/xe_configfs.h | 16 +++
> drivers/gpu/drm/xe/xe_module.c | 5 +
> 6 files changed, 223 insertions(+)
> create mode 100644 Documentation/gpu/xe/xe_configfs.rst
> create mode 100644 drivers/gpu/drm/xe/xe_configfs.c create mode 100644
> drivers/gpu/drm/xe/xe_configfs.h
>
> diff --git a/Documentation/gpu/xe/index.rst
> b/Documentation/gpu/xe/index.rst index 92cfb25e64d3..b2369561f24e
> 100644
> --- a/Documentation/gpu/xe/index.rst
> +++ b/Documentation/gpu/xe/index.rst
> @@ -25,3 +25,4 @@ DG2, etc is provided to prototype the driver.
> xe_debugging
> xe_devcoredump
> xe-drm-usage-stats.rst
> + xe_configfs
> diff --git a/Documentation/gpu/xe/xe_configfs.rst
> b/Documentation/gpu/xe/xe_configfs.rst
> new file mode 100644
> index 000000000000..9b9d941eb20e
> --- /dev/null
> +++ b/Documentation/gpu/xe/xe_configfs.rst
> @@ -0,0 +1,10 @@
> +.. SPDX-License-Identifier: GPL-2.0+
> +
> +.. _xe_configfs:
> +
> +============
> +Xe Configfs
> +============
> +
> +.. kernel-doc:: drivers/gpu/drm/xe/xe_configfs.c
> + :doc: Xe Configfs
> diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile index
> 72eaadc4cbee..c5d6681645ed 100644
> --- a/drivers/gpu/drm/xe/Makefile
> +++ b/drivers/gpu/drm/xe/Makefile
> @@ -131,6 +131,7 @@ xe-$(CONFIG_DRM_XE_GPUSVM) += xe_svm.o
> xe-$(CONFIG_HWMON) += xe_hwmon.o
>
> xe-$(CONFIG_PERF_EVENTS) += xe_pmu.o
> +xe-$(CONFIG_CONFIGFS_FS) += xe_configfs.o
>
> # graphics virtualization (SR-IOV) support xe-y += \ diff --git
> a/drivers/gpu/drm/xe/xe_configfs.c b/drivers/gpu/drm/xe/xe_configfs.c
> new file mode 100644
> index 000000000000..548468d2bda0
> --- /dev/null
> +++ b/drivers/gpu/drm/xe/xe_configfs.c
> @@ -0,0 +1,190 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2025 Intel Corporation
> + */
> +
> +#include <linux/configfs.h>
> +#include <linux/init.h>
> +#include <linux/module.h>
> +#include <linux/pci.h>
> +
> +#include "xe_configfs.h"
> +#include "xe_module.h"
> +
> +/**
> + * DOC: Xe Configfs
> + *
> + * Overview
> + * =========
> + *
> + * Configfs is a filesystem-based manager of kernel objects. XE KMD
> +registers a
> + * configfs subsystem called ``'xe'`` that creates a directory in the
> +mounted configfs directory
> + * The user can create devices under this directory and configure them
> +as necessary
> + * See Documentation/filesystems/configfs.rst for more information about
> how configfs works.
> + *
> + * Create devices
> + * ===============
> + *
> + * In order to create a device, the user has to create a directory
> +inside ``'xe'``
> + * ::
> + *
> + * mkdir /sys/kernel/config/xe/0000:03:00.0/
> + *
> + * Every device created will have the following entries that can be
> +used to configure it
> + * ::
> + *
> + * /sys/kernel/config/xe/
> + * .. 0000:03:00.0/
> + * ... survivability_mode
> + *
> + * Configure Attributes
> + * ====================
> + *
> + * Survivability mode:
> + * -------------------
> + *
> + * To enable survivability mode using configfs on supported cards,
> +follow the
> + * below steps ::
> + *
> + * # echo 1 > /sys/kernel/config/xe/0000:03:00.0/survivability_mode
> + * # echo 0000:03:00.0 > /sys/bus/pci/drivers/xe/bind (Enters
> survivability mode if supported)
> + *
> + * Remove devices
> + * ==============
> + *
> + * The created device directories can be removed using ``rmdir``
> + * ::
> + *
> + * rmdir /sys/kernel/config/xe/0000:03:00.0/
> + */
> +
> +struct xe_config_device {
> + struct config_group group;
> +
> + bool survivability_mode;
> +
> + /* protects attributes */
> + struct mutex lock;
> +};
> +
> +static struct xe_config_device *to_xe_config_device(struct config_item
> +*item) {
> + return container_of(to_config_group(item), struct xe_config_device,
> +group); }
> +
> +static ssize_t survivability_mode_show(struct config_item *item, char
> +*page) {
> + struct xe_config_device *dev = to_xe_config_device(item);
> +
> + return sprintf(page, "%d\n", dev->survivability_mode); }
> +
> +static ssize_t survivability_mode_store(struct config_item *item, const
> +char *page, size_t len) {
> + struct xe_config_device *dev = to_xe_config_device(item);
> + bool survivability_mode;
> + int ret;
> +
> + ret = kstrtobool(page, &survivability_mode);
> + if (ret)
> + return ret;
> +
> + mutex_lock(&dev->lock);
> + dev->survivability_mode = survivability_mode;
> + mutex_unlock(&dev->lock);
> +
> + return len;
> +}
> +
> +CONFIGFS_ATTR(, survivability_mode);
> +
> +static struct configfs_attribute *xe_config_device_attrs[] = {
> + &attr_survivability_mode,
> + NULL,
> +};
> +
> +static void xe_config_device_release(struct config_item *item) {
> + struct xe_config_device *dev = to_xe_config_device(item);
> +
> + mutex_destroy(&dev->lock);
> + kfree(dev);
> +}
> +
> +static struct configfs_item_operations xe_config_device_ops = {
> + .release = xe_config_device_release,
> +};
> +
> +static const struct config_item_type xe_config_device_type = {
> + .ct_item_ops = &xe_config_device_ops,
> + .ct_attrs = xe_config_device_attrs,
> + .ct_owner = THIS_MODULE,
> +};
> +
> +static struct config_group *xe_config_make_device_group(struct
> config_group *group,
> + const char *name)
> +{
> + unsigned int domain, bus, slot, function;
> + struct xe_config_device *dev;
> + struct pci_dev *pdev;
> + int ret;
> +
> + ret = sscanf(name, "%04x:%02x:%02x.%x", &domain, &bus, &slot,
> &function);
> + if (ret != 4)
> + return ERR_PTR(-EINVAL);
> +
> + pdev = pci_get_domain_bus_and_slot(domain, bus, PCI_DEVFN(slot,
> function));
> + if (!pdev)
> + return ERR_PTR(-EINVAL);
> +
> + dev = kzalloc(sizeof(*dev), GFP_KERNEL);
> + if (!dev)
> + return ERR_PTR(-ENOMEM);
> +
> + config_group_init_type_name(&dev->group, name,
> +&xe_config_device_type);
> +
> + mutex_init(&dev->lock);
> +
> + return &dev->group;
> +}
> +
> +static struct configfs_group_operations xe_config_device_group_ops = {
> + .make_group = xe_config_make_device_group,
> +};
> +
> +static const struct config_item_type xe_configfs_type = {
> + .ct_group_ops = &xe_config_device_group_ops,
> + .ct_owner = THIS_MODULE,
> +};
> +
> +static struct configfs_subsystem xe_configfs = {
> + .su_group = {
> + .cg_item = {
> + .ci_namebuf = "xe",
> + .ci_type = &xe_configfs_type,
> + },
> + },
> +};
> +
> +int __init xe_configfs_init(void)
> +{
> + struct config_group *root = &xe_configfs.su_group;
> + int ret;
> +
> + config_group_init(root);
> + mutex_init(&xe_configfs.su_mutex);
> + ret = configfs_register_subsystem(&xe_configfs);
> + if (ret) {
> + pr_err("Error %d while registering %s subsystem\n",
> + ret, root->cg_item.ci_namebuf);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +void __exit xe_configfs_exit(void)
> +{
> + configfs_unregister_subsystem(&xe_configfs);
> +}
> +
> diff --git a/drivers/gpu/drm/xe/xe_configfs.h
> b/drivers/gpu/drm/xe/xe_configfs.h
> new file mode 100644
> index 000000000000..5532320818e4
> --- /dev/null
> +++ b/drivers/gpu/drm/xe/xe_configfs.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2025 Intel Corporation
> + */
> +#ifndef _XE_CONFIGFS_H_
> +#define _XE_CONFIGFS_H_
> +
> +#if IS_ENABLED(CONFIG_CONFIGFS_FS)
> +int xe_configfs_init(void);
> +void xe_configfs_exit(void);
> +#else
> +static inline int xe_configfs_init(void) { return 0; }; static inline
> +void xe_configfs_exit(void) {}; #endif
> +
> +#endif
> diff --git a/drivers/gpu/drm/xe/xe_module.c
> b/drivers/gpu/drm/xe/xe_module.c index 475acdba2b55..15b3cf22193c
> 100644
> --- a/drivers/gpu/drm/xe/xe_module.c
> +++ b/drivers/gpu/drm/xe/xe_module.c
> @@ -11,6 +11,7 @@
> #include <drm/drm_module.h>
>
> #include "xe_drv.h"
> +#include "xe_configfs.h"
> #include "xe_hw_fence.h"
> #include "xe_pci.h"
> #include "xe_pm.h"
> @@ -91,6 +92,10 @@ static const struct init_funcs init_funcs[] = {
> {
> .init = xe_check_nomodeset,
> },
> + {
> + .init = xe_configfs_init,
> + .exit = xe_configfs_exit,
> + },
> {
> .init = xe_hw_fence_module_init,
> .exit = xe_hw_fence_module_exit,
> --
> 2.47.1
More information about the Intel-xe
mailing list