On 5/15/2026 1:58 AM, Raag Jadav wrote:
cleanup_node_param() is not registered in case of counter allocation
failure, which results in stale memory of previous node that isn't
cleaned up on unwind.
It is registered.
ret = assign_node_params(xe, node, i);
if (ret)
cleanup_node_param(ras, i);
Add per node cleanup action which guarantees
cleanup on unwind and also simplifies the cleanup logic.
Fixes: b40db12b542f ("drm/xe/xe_drm_ras: Add support for XE DRM RAS")
Signed-off-by: Raag Jadav <[email protected]>
---
drivers/gpu/drm/xe/xe_drm_ras.c | 42 +++++++++++++--------------------
1 file changed, 17 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_drm_ras.c b/drivers/gpu/drm/xe/xe_drm_ras.c
index 89640ffb1c33..40abde29a26f 100644
--- a/drivers/gpu/drm/xe/xe_drm_ras.c
+++ b/drivers/gpu/drm/xe/xe_drm_ras.c
@@ -131,14 +131,20 @@ static int assign_node_params(struct xe_device *xe,
struct drm_ras_node *node,
return 0;
}
-static void cleanup_node_param(struct xe_drm_ras *ras, const enum drm_xe_ras_error_severity severity)
+static void cleanup_node_param(struct drm_ras_node *node)
{
- struct drm_ras_node *node = &ras->node[severity];
-
kfree(node->device_name);
node->device_name = NULL;
}
+static void cleanup_node(struct drm_device *drm, void *arg)
+{
+ struct drm_ras_node *node = arg;
+
+ drm_ras_node_unregister(node);
+ cleanup_node_param(node);
+}
+
static int register_nodes(struct xe_device *xe)
{
struct xe_drm_ras *ras = &xe->ras;
@@ -150,13 +156,19 @@ static int register_nodes(struct xe_device *xe)
ret = assign_node_params(xe, node, i);
if (ret) {
- cleanup_node_param(ras, i);
+ cleanup_node_param(node);
At this point drm_ras node is not registered.
return ret;
}
ret = drm_ras_node_register(node);
if (ret) {
- cleanup_node_param(ras, i);
+ cleanup_node_param(node);
Ditto
Thanks
Riana
+ return ret;
+ }
+
+ ret = drmm_add_action_or_reset(&xe->drm, cleanup_node, node);
+ if (ret) {
+ cleanup_node(&xe->drm, node);
return ret;
}
}
@@ -164,20 +176,6 @@ static int register_nodes(struct xe_device *xe)
return 0;
}
-static void xe_drm_ras_unregister_nodes(struct drm_device *device, void *arg)
-{
- struct xe_device *xe = arg;
- struct xe_drm_ras *ras = &xe->ras;
- int i;
-
- for_each_error_severity(i) {
- struct drm_ras_node *node = &ras->node[i];
-
- drm_ras_node_unregister(node);
- cleanup_node_param(ras, i);
- }
-}
-
/**
* xe_drm_ras_init() - Initialize DRM RAS
* @xe: xe device instance
@@ -204,11 +202,5 @@ int xe_drm_ras_init(struct xe_device *xe)
return err;
}
- err = drmm_add_action_or_reset(&xe->drm, xe_drm_ras_unregister_nodes, xe);
- if (err) {
- drm_err(&xe->drm, "Failed to add action for Xe DRM RAS
(%pe)\n", ERR_PTR(err));
- return err;
- }
-
return 0;
}