On 21-07-2026 14:07, Raag Jadav wrote:
On Mon, Jul 20, 2026 at 01:52:11PM +0530, Riana Tauro wrote:
When an interrupt is received indicating that error counter has crossed
its threshold, read the current counter value and deliver a drm_ras error
event to userspace for each affected component.

To avoid sending duplicate events when the same component appears multiple
times in the response. Send the error-event once per component.
...

+void xe_drm_ras_event(struct xe_device *xe, u8 component, u8 severity, u32 
value)
+{
+       struct xe_drm_ras *ras = &xe->ras;
+       struct xe_drm_ras_counter *info;
+       struct drm_ras_node *node;
+       int ret;
+
+       /* Event is supported only if drm_ras is enabled */
+       if (!xe->info.has_drm_ras)
+               return;
+
+       if (component >= DRM_XE_RAS_ERR_COMP_MAX) {
IIUC this is error_id and should be validated against first/last counter
range in drm_ras layer (similar to registration code).

This should be done before because we are accessing the nodes here.
The nodes anyway won't be available in xe_drm_ras if not registered with drm_ras.




+               drm_warn(&xe->drm, "unsupported component %u\n", component);
+               return;
+       }
+
+       if (severity >= DRM_XE_RAS_ERR_SEV_MAX) {
+               drm_warn(&xe->drm, "unsupported severity %u\n", severity);
+               return;
+       }
+
+       node = &ras->node[severity];
+       info = ras->info[severity];
+
+       if (!info || !info[component].name)
+               return;
+
+       ret = drm_ras_nl_error_event(node, component, info[component].name, 
value);
+       if (ret)
+               drm_err_ratelimited(&xe->drm, "drm_ras error-event failed: %d for %s 
%s\n", ret,
+                                   info[component].name, 
error_severity[severity]);
+}
...

+static void ras_send_error_event(struct xe_device *xe, u8 severity, u8 
component)
+{
+       struct xe_ras_error_class counter = {0};
+       u8 drm_severity, drm_component;
+       u32 value;
+       int ret;
+
+       counter.common.severity = severity;
+       counter.common.component = component;
+
+       ret = get_counter(xe, &counter, &value);
+       if (ret)
+               return;
+
+       drm_severity = xe_to_drm_ras_severity(severity);
+       drm_component = xe_to_drm_ras_component(component);
+
+       xe_drm_ras_event(xe, drm_component, drm_severity, value);
+}
This entire function can be dropped. See below.

We don't need to drop function. It's cleaner to have it in the function
than repeating it twice.


  static u8 handle_core_compute_errors(struct xe_ras_error_array *arr)
  {
        struct xe_ras_compute_error *error_info = (void *)arr->details;
@@ -312,8 +364,10 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,
        struct xe_ras_threshold_crossed *pending = (void *)&response->data;
        struct xe_ras_error_class *errors = pending->counters;
        u32 id, ncounters = pending->ncounters;
+       u8 sent = 0;
BUILD_BUG_ON(sizeof(response->data) < sizeof(*pending));
+       BUILD_BUG_ON(BITS_PER_TYPE(sent) < XE_RAS_COMP_MAX);
        xe_device_assert_mem_access(xe);
if (!ncounters || ncounters > XE_RAS_NUM_COUNTERS)
@@ -327,8 +381,21 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe,
                severity = errors[id].common.severity;
                component = errors[id].common.component;
+ if (severity != XE_RAS_SEV_CORRECTABLE) {
+                       xe_warn(xe, "sysctrl: unexpected severity %s (%u)\n", 
sev_to_str(severity),
+                               severity);
Sanity checks are good, but I think this needs to be extended a bit.
I have something[1] more robust, feel free to reuse.

[1] 
https://lore.kernel.org/intel-xe/[email protected]

Agreed. I'll drop the checks. We can merge [1] first.
We can drop the drm checks above also if [1] is merged.

Will remove all checks and resend a new version.


+                       continue;
+               }
+
                xe_warn(xe, "[RAS]: %s %s detected\n",
                        comp_to_str(component), sev_to_str(severity));
+
+               /* Send event once per component */
+               if (sent & BIT(component))
+                       continue;
+               sent |= BIT(component);
With [1] in place you can just get_counter(&counter) and drm_ras_event()
directly.

Same as above. Better to retain function.

Thanks
Riana



Raag

+               ras_send_error_event(xe, severity, component);
        }
  }
--
2.47.1

Reply via email to