* [PATCH v4 0/3] Add drm_ras netlink error event support
@ 2026-07-01 9:44 Riana Tauro
2026-07-01 9:44 ` [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event Riana Tauro
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Riana Tauro @ 2026-07-01 9:44 UTC (permalink / raw)
To: intel-xe, dri-devel, netdev
Cc: aravind.iddamsetty, anshuman.gupta, rodrigo.vivi, joonas.lahtinen,
kuba, simona.vetter, airlied, pratik.bari, joshua.santosh.ranjan,
ashwin.kumar.kulkarni, shubham.kumar, ravi.kishore.koppuravuri,
raag.jadav, maarten.lankhorst, mallesh.koujalagi, soham.purkait,
Riana Tauro
Define a new netlink event 'error-event' and a new multicast group
'error-report' in drm_ras. Each event contains device name, node and
error information to identify the error triggering the event.
Add drm_ras_nl_error_event() to trigger an event from the driver.
Wire this support to xe drm_ras to notify userspace whenever a GT or
SoC error occurs in PVC. Also add support for correctable errors in
CRI.
$ sudo ynl --family drm_ras --output-json --subscribe error-report
{
"name": "error-event",
"msg": {
"device-name": "0000:03:00.0",
"node-id": 1,
"node-name": "uncorrectable-errors",
"error-id": 1,
"error-name": "core-compute",
"error-value": 1
}
}
Rev2: use ynl in document and commit message
fix cosmetic review comments
simplify caller
Rev3: replace error-event with error-report
had has_drm_ras check
add support for correctable errors in CRI
Rev4: send an event at most once per component for each interrupt
add xe_warn for unexpected values from firmware
fix sashiko reported issues
Riana Tauro (3):
drm/drm_ras: Add drm_ras netlink error event
drm/xe/xe_drm_ras: Add error-event support for PVC
drm/xe/xe_ras: Add error-event support for CRI
Documentation/gpu/drm-ras.rst | 21 ++++++
Documentation/netlink/specs/drm_ras.yaml | 48 +++++++++++++
drivers/gpu/drm/drm_ras.c | 87 ++++++++++++++++++++++++
drivers/gpu/drm/drm_ras_nl.c | 6 ++
drivers/gpu/drm/drm_ras_nl.h | 4 ++
drivers/gpu/drm/xe/xe_drm_ras.c | 32 +++++++++
drivers/gpu/drm/xe/xe_drm_ras.h | 3 +
drivers/gpu/drm/xe/xe_hw_error.c | 5 +-
drivers/gpu/drm/xe/xe_ras.c | 75 ++++++++++++++++++++
include/drm/drm_ras.h | 5 ++
include/uapi/drm/drm_ras.h | 15 ++++
11 files changed, 300 insertions(+), 1 deletion(-)
--
2.47.1
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event 2026-07-01 9:44 [PATCH v4 0/3] Add drm_ras netlink error event support Riana Tauro @ 2026-07-01 9:44 ` Riana Tauro 2026-07-07 6:32 ` Tauro, Riana 2026-07-01 9:44 ` [PATCH v4 2/3] drm/xe/xe_drm_ras: Add error-event support for PVC Riana Tauro 2026-07-01 9:44 ` [PATCH v4 3/3] drm/xe/xe_ras: Add error-event support for CRI Riana Tauro 2 siblings, 1 reply; 9+ messages in thread From: Riana Tauro @ 2026-07-01 9:44 UTC (permalink / raw) To: intel-xe, dri-devel, netdev Cc: aravind.iddamsetty, anshuman.gupta, rodrigo.vivi, joonas.lahtinen, kuba, simona.vetter, airlied, pratik.bari, joshua.santosh.ranjan, ashwin.kumar.kulkarni, shubham.kumar, ravi.kishore.koppuravuri, raag.jadav, maarten.lankhorst, mallesh.koujalagi, soham.purkait, Riana Tauro, Zack McKevitt, Lijo Lazar, Hawking Zhang, David S. Miller, Paolo Abeni, Eric Dumazet Define a new netlink event 'error-event' and a new multicast group 'error-report' in drm_ras. Each event contains device name, node and error information to identify the error triggering the event. Add drm_ras_nl_error_event() to trigger an event from the driver. Userspace must subscribe to 'error-report' to receive 'error-event' notifications. Usage: $ sudo ynl --family drm_ras --subscribe error-report Cc: Jakub Kicinski <kuba@kernel.org> Cc: Zack McKevitt <zachary.mckevitt@oss.qualcomm.com> Cc: Lijo Lazar <lijo.lazar@amd.com> Cc: Hawking Zhang <Hawking.Zhang@amd.com> Cc: David S. Miller <davem@davemloft.net> Cc: Paolo Abeni <pabeni@redhat.com> Cc: Eric Dumazet <edumazet@google.com> Signed-off-by: Riana Tauro <riana.tauro@intel.com> Reviewed-by: Raag Jadav <raag.jadav@intel.com> --- v2: remove redundant initialization remove unnecessary space use ynl in commit message and doc (Raag) simplify doc for error-event attrs v3: rename error-notify to error-report Replace notify with report across the file (Raag) --- Documentation/gpu/drm-ras.rst | 21 ++++++ Documentation/netlink/specs/drm_ras.yaml | 48 +++++++++++++ drivers/gpu/drm/drm_ras.c | 87 ++++++++++++++++++++++++ drivers/gpu/drm/drm_ras_nl.c | 6 ++ drivers/gpu/drm/drm_ras_nl.h | 4 ++ include/drm/drm_ras.h | 5 ++ include/uapi/drm/drm_ras.h | 15 ++++ 7 files changed, 186 insertions(+) diff --git a/Documentation/gpu/drm-ras.rst b/Documentation/gpu/drm-ras.rst index 83c21853b74b..406e4c49bac1 100644 --- a/Documentation/gpu/drm-ras.rst +++ b/Documentation/gpu/drm-ras.rst @@ -56,6 +56,7 @@ User space tools can: ``node-id`` and ``error-id`` as parameters. * Clear specific error counters with the ``clear-error-counter`` command, using both ``node-id`` and ``error-id`` as parameters. +* Subscribe to the ``error-report`` multicast group to receive ``error-event``. YAML-based Interface -------------------- @@ -111,3 +112,23 @@ Example: Clear an error counter for a given node sudo ynl --family drm_ras --do clear-error-counter --json '{"node-id":0, "error-id":1}' None + +Example: Subscribe to ``error-report`` multicast group + +.. code-block:: bash + + sudo ynl --family drm_ras --output-json --subscribe error-report + +.. code-block:: json + + { + "name": "error-event", + "msg": { + "device-name": "0000:03:00.0", + "node-id": 1, + "node-name": "uncorrectable-errors", + "error-id": 1, + "error-name": "error_name1", + "error-value": 1 + } + } diff --git a/Documentation/netlink/specs/drm_ras.yaml b/Documentation/netlink/specs/drm_ras.yaml index e113056f8c01..8aed3d4515e5 100644 --- a/Documentation/netlink/specs/drm_ras.yaml +++ b/Documentation/netlink/specs/drm_ras.yaml @@ -69,6 +69,33 @@ attribute-sets: name: error-value type: u32 doc: Current value of the requested error counter. + - + name: error-event-attrs + attributes: + - + name: device-name + type: string + doc: Device (PCI BDF, UUID) that reported the error. + - + name: node-id + type: u32 + doc: ID of the node that reported the error. + - + name: node-name + type: string + doc: Name of the node that reported the error. + - + name: error-id + type: u32 + doc: ID of the error counter. + - + name: error-name + type: string + doc: Name of the error. + - + name: error-value + type: u32 + doc: Current value of the error counter. operations: list: @@ -124,3 +151,24 @@ operations: do: request: attributes: *id-attrs + - + name: error-event + doc: >- + Report an error event to userspace. + The event includes the device, node and error information + of the error that triggered the event. + attribute-set: error-event-attrs + mcgrp: error-report + event: + attributes: + - device-name + - node-id + - node-name + - error-id + - error-name + - error-value + +mcast-groups: + list: + - + name: error-report diff --git a/drivers/gpu/drm/drm_ras.c b/drivers/gpu/drm/drm_ras.c index d6eab29a1394..77f912a4d101 100644 --- a/drivers/gpu/drm/drm_ras.c +++ b/drivers/gpu/drm/drm_ras.c @@ -41,6 +41,11 @@ * Userspace must provide Node ID, Error ID. * Clears specific error counter of a node if supported. * + * 4. ERROR_REPORT: Subscribe to this multicast group to receive error events + * + * 5. ERROR_EVENT: Report an error event to userspace. The event contains device, node + * and error information that triggered the event. + * * Node registration: * * - drm_ras_node_register(): Registers a new node and assigns @@ -186,6 +191,34 @@ static int msg_reply_value(struct sk_buff *msg, u32 error_id, value); } +static int msg_put_error_event_attrs(struct sk_buff *msg, struct drm_ras_node *node, + u32 error_id, const char *error_name, u32 value) +{ + int ret; + + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME, node->device_name); + if (ret) + return ret; + + ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, node->id); + if (ret) + return ret; + + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, node->node_name); + if (ret) + return ret; + + ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, error_id); + if (ret) + return ret; + + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, error_name); + if (ret) + return ret; + + return nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, value); +} + static int doit_reply_value(struct genl_info *info, u32 node_id, u32 error_id) { @@ -222,6 +255,60 @@ static int doit_reply_value(struct genl_info *info, u32 node_id, return genlmsg_reply(msg, info); } +/** + * drm_ras_nl_error_event() - Report an error event + * @node: Node structure + * @error_id: ID of the error + * @error_name: Name of the error + * @value: Value associated with the error + * @flags: GFP flags for memory allocation + * + * Report an error-event to userspace using the error-report multicast group. + * + * Return: 0 on success, or negative errno on failure. + */ +int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name, + u32 value, gfp_t flags) +{ + struct genl_info info; + struct sk_buff *msg; + struct nlattr *hdr; + int ret; + + if (!error_name) + return -EINVAL; + + if (!genl_has_listeners(&drm_ras_nl_family, &init_net, DRM_RAS_NLGRP_ERROR_REPORT)) + return 0; + + genl_info_init_ntf(&info, &drm_ras_nl_family, DRM_RAS_CMD_ERROR_EVENT); + + msg = genlmsg_new(NLMSG_GOODSIZE, flags); + if (!msg) + return -ENOMEM; + + hdr = genlmsg_iput(msg, &info); + if (!hdr) { + ret = -EMSGSIZE; + goto free_msg; + } + + ret = msg_put_error_event_attrs(msg, node, error_id, error_name, value); + if (ret) + goto cancel_msg; + + genlmsg_end(msg, hdr); + genlmsg_multicast(&drm_ras_nl_family, msg, 0, DRM_RAS_NLGRP_ERROR_REPORT, flags); + return 0; + +cancel_msg: + genlmsg_cancel(msg, hdr); +free_msg: + nlmsg_free(msg); + return ret; +} +EXPORT_SYMBOL(drm_ras_nl_error_event); + /** * drm_ras_nl_get_error_counter_dumpit() - Dump all Error Counters * @skb: Netlink message buffer diff --git a/drivers/gpu/drm/drm_ras_nl.c b/drivers/gpu/drm/drm_ras_nl.c index dea1c1b2494e..9d3123cc9f9c 100644 --- a/drivers/gpu/drm/drm_ras_nl.c +++ b/drivers/gpu/drm/drm_ras_nl.c @@ -58,6 +58,10 @@ static const struct genl_split_ops drm_ras_nl_ops[] = { }, }; +static const struct genl_multicast_group drm_ras_nl_mcgrps[] = { + [DRM_RAS_NLGRP_ERROR_REPORT] = { "error-report", }, +}; + struct genl_family drm_ras_nl_family __ro_after_init = { .name = DRM_RAS_FAMILY_NAME, .version = DRM_RAS_FAMILY_VERSION, @@ -66,4 +70,6 @@ struct genl_family drm_ras_nl_family __ro_after_init = { .module = THIS_MODULE, .split_ops = drm_ras_nl_ops, .n_split_ops = ARRAY_SIZE(drm_ras_nl_ops), + .mcgrps = drm_ras_nl_mcgrps, + .n_mcgrps = ARRAY_SIZE(drm_ras_nl_mcgrps), }; diff --git a/drivers/gpu/drm/drm_ras_nl.h b/drivers/gpu/drm/drm_ras_nl.h index a398643572a5..03ec275aca92 100644 --- a/drivers/gpu/drm/drm_ras_nl.h +++ b/drivers/gpu/drm/drm_ras_nl.h @@ -21,6 +21,10 @@ int drm_ras_nl_get_error_counter_dumpit(struct sk_buff *skb, int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb, struct genl_info *info); +enum { + DRM_RAS_NLGRP_ERROR_REPORT, +}; + extern struct genl_family drm_ras_nl_family; #endif /* _LINUX_DRM_RAS_GEN_H */ diff --git a/include/drm/drm_ras.h b/include/drm/drm_ras.h index 0beede3ddc4e..8abfb7d2077b 100644 --- a/include/drm/drm_ras.h +++ b/include/drm/drm_ras.h @@ -80,9 +80,14 @@ struct drm_device; #if IS_ENABLED(CONFIG_DRM_RAS) int drm_ras_node_register(struct drm_ras_node *node); void drm_ras_node_unregister(struct drm_ras_node *node); +int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name, + u32 value, gfp_t flags); #else static inline int drm_ras_node_register(struct drm_ras_node *node) { return 0; } static inline void drm_ras_node_unregister(struct drm_ras_node *node) { } +static inline int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, + const char *error_name, u32 value, gfp_t flags) +{ return 0; } #endif #endif diff --git a/include/uapi/drm/drm_ras.h b/include/uapi/drm/drm_ras.h index 218a3ee86805..eab8231aa87c 100644 --- a/include/uapi/drm/drm_ras.h +++ b/include/uapi/drm/drm_ras.h @@ -38,13 +38,28 @@ enum { DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX = (__DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX - 1) }; +enum { + DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME = 1, + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, + + __DRM_RAS_A_ERROR_EVENT_ATTRS_MAX, + DRM_RAS_A_ERROR_EVENT_ATTRS_MAX = (__DRM_RAS_A_ERROR_EVENT_ATTRS_MAX - 1) +}; + enum { DRM_RAS_CMD_LIST_NODES = 1, DRM_RAS_CMD_GET_ERROR_COUNTER, DRM_RAS_CMD_CLEAR_ERROR_COUNTER, + DRM_RAS_CMD_ERROR_EVENT, __DRM_RAS_CMD_MAX, DRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1) }; +#define DRM_RAS_MCGRP_ERROR_REPORT "error-report" + #endif /* _UAPI_LINUX_DRM_RAS_H */ -- 2.47.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event 2026-07-01 9:44 ` [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event Riana Tauro @ 2026-07-07 6:32 ` Tauro, Riana 2026-07-08 20:21 ` Rodrigo Vivi 0 siblings, 1 reply; 9+ messages in thread From: Tauro, Riana @ 2026-07-07 6:32 UTC (permalink / raw) To: intel-xe, aravind.iddamsetty, kuba, rodrigo.vivi Cc: anshuman.gupta, joonas.lahtinen, simona.vetter, airlied, pratik.bari, joshua.santosh.ranjan, ashwin.kumar.kulkarni, shubham.kumar, ravi.kishore.koppuravuri, raag.jadav, maarten.lankhorst, mallesh.koujalagi, soham.purkait, Zack McKevitt, Lijo Lazar, Hawking Zhang, David S. Miller, Paolo Abeni, Eric Dumazet, dri-devel, netdev Hi Rodrigo/Jakub/Aravind Please let me know if you have any feedback for this patch or can you please ack this if it looks good to you. Thanks Riana On 01-07-2026 15:14, Riana Tauro wrote: > Define a new netlink event 'error-event' and a new multicast group > 'error-report' in drm_ras. Each event contains device name, node and > error information to identify the error triggering the event. > > Add drm_ras_nl_error_event() to trigger an event from the driver. > Userspace must subscribe to 'error-report' to receive 'error-event' > notifications. > > Usage: > > $ sudo ynl --family drm_ras --subscribe error-report > > Cc: Jakub Kicinski <kuba@kernel.org> > Cc: Zack McKevitt <zachary.mckevitt@oss.qualcomm.com> > Cc: Lijo Lazar <lijo.lazar@amd.com> > Cc: Hawking Zhang <Hawking.Zhang@amd.com> > Cc: David S. Miller <davem@davemloft.net> > Cc: Paolo Abeni <pabeni@redhat.com> > Cc: Eric Dumazet <edumazet@google.com> > Signed-off-by: Riana Tauro <riana.tauro@intel.com> > Reviewed-by: Raag Jadav <raag.jadav@intel.com> > --- > v2: remove redundant initialization > remove unnecessary space > use ynl in commit message and doc (Raag) > simplify doc for error-event attrs > > v3: rename error-notify to error-report > Replace notify with report across the file (Raag) > --- > Documentation/gpu/drm-ras.rst | 21 ++++++ > Documentation/netlink/specs/drm_ras.yaml | 48 +++++++++++++ > drivers/gpu/drm/drm_ras.c | 87 ++++++++++++++++++++++++ > drivers/gpu/drm/drm_ras_nl.c | 6 ++ > drivers/gpu/drm/drm_ras_nl.h | 4 ++ > include/drm/drm_ras.h | 5 ++ > include/uapi/drm/drm_ras.h | 15 ++++ > 7 files changed, 186 insertions(+) > > diff --git a/Documentation/gpu/drm-ras.rst b/Documentation/gpu/drm-ras.rst > index 83c21853b74b..406e4c49bac1 100644 > --- a/Documentation/gpu/drm-ras.rst > +++ b/Documentation/gpu/drm-ras.rst > @@ -56,6 +56,7 @@ User space tools can: > ``node-id`` and ``error-id`` as parameters. > * Clear specific error counters with the ``clear-error-counter`` command, using both > ``node-id`` and ``error-id`` as parameters. > +* Subscribe to the ``error-report`` multicast group to receive ``error-event``. > > YAML-based Interface > -------------------- > @@ -111,3 +112,23 @@ Example: Clear an error counter for a given node > > sudo ynl --family drm_ras --do clear-error-counter --json '{"node-id":0, "error-id":1}' > None > + > +Example: Subscribe to ``error-report`` multicast group > + > +.. code-block:: bash > + > + sudo ynl --family drm_ras --output-json --subscribe error-report > + > +.. code-block:: json > + > + { > + "name": "error-event", > + "msg": { > + "device-name": "0000:03:00.0", > + "node-id": 1, > + "node-name": "uncorrectable-errors", > + "error-id": 1, > + "error-name": "error_name1", > + "error-value": 1 > + } > + } > diff --git a/Documentation/netlink/specs/drm_ras.yaml b/Documentation/netlink/specs/drm_ras.yaml > index e113056f8c01..8aed3d4515e5 100644 > --- a/Documentation/netlink/specs/drm_ras.yaml > +++ b/Documentation/netlink/specs/drm_ras.yaml > @@ -69,6 +69,33 @@ attribute-sets: > name: error-value > type: u32 > doc: Current value of the requested error counter. > + - > + name: error-event-attrs > + attributes: > + - > + name: device-name > + type: string > + doc: Device (PCI BDF, UUID) that reported the error. > + - > + name: node-id > + type: u32 > + doc: ID of the node that reported the error. > + - > + name: node-name > + type: string > + doc: Name of the node that reported the error. > + - > + name: error-id > + type: u32 > + doc: ID of the error counter. > + - > + name: error-name > + type: string > + doc: Name of the error. > + - > + name: error-value > + type: u32 > + doc: Current value of the error counter. > > operations: > list: > @@ -124,3 +151,24 @@ operations: > do: > request: > attributes: *id-attrs > + - > + name: error-event > + doc: >- > + Report an error event to userspace. > + The event includes the device, node and error information > + of the error that triggered the event. > + attribute-set: error-event-attrs > + mcgrp: error-report > + event: > + attributes: > + - device-name > + - node-id > + - node-name > + - error-id > + - error-name > + - error-value > + > +mcast-groups: > + list: > + - > + name: error-report > diff --git a/drivers/gpu/drm/drm_ras.c b/drivers/gpu/drm/drm_ras.c > index d6eab29a1394..77f912a4d101 100644 > --- a/drivers/gpu/drm/drm_ras.c > +++ b/drivers/gpu/drm/drm_ras.c > @@ -41,6 +41,11 @@ > * Userspace must provide Node ID, Error ID. > * Clears specific error counter of a node if supported. > * > + * 4. ERROR_REPORT: Subscribe to this multicast group to receive error events > + * > + * 5. ERROR_EVENT: Report an error event to userspace. The event contains device, node > + * and error information that triggered the event. > + * > * Node registration: > * > * - drm_ras_node_register(): Registers a new node and assigns > @@ -186,6 +191,34 @@ static int msg_reply_value(struct sk_buff *msg, u32 error_id, > value); > } > > +static int msg_put_error_event_attrs(struct sk_buff *msg, struct drm_ras_node *node, > + u32 error_id, const char *error_name, u32 value) > +{ > + int ret; > + > + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME, node->device_name); > + if (ret) > + return ret; > + > + ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, node->id); > + if (ret) > + return ret; > + > + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, node->node_name); > + if (ret) > + return ret; > + > + ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, error_id); > + if (ret) > + return ret; > + > + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, error_name); > + if (ret) > + return ret; > + > + return nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, value); > +} > + > static int doit_reply_value(struct genl_info *info, u32 node_id, > u32 error_id) > { > @@ -222,6 +255,60 @@ static int doit_reply_value(struct genl_info *info, u32 node_id, > return genlmsg_reply(msg, info); > } > > +/** > + * drm_ras_nl_error_event() - Report an error event > + * @node: Node structure > + * @error_id: ID of the error > + * @error_name: Name of the error > + * @value: Value associated with the error > + * @flags: GFP flags for memory allocation > + * > + * Report an error-event to userspace using the error-report multicast group. > + * > + * Return: 0 on success, or negative errno on failure. > + */ > +int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name, > + u32 value, gfp_t flags) > +{ > + struct genl_info info; > + struct sk_buff *msg; > + struct nlattr *hdr; > + int ret; > + > + if (!error_name) > + return -EINVAL; > + > + if (!genl_has_listeners(&drm_ras_nl_family, &init_net, DRM_RAS_NLGRP_ERROR_REPORT)) > + return 0; > + > + genl_info_init_ntf(&info, &drm_ras_nl_family, DRM_RAS_CMD_ERROR_EVENT); > + > + msg = genlmsg_new(NLMSG_GOODSIZE, flags); > + if (!msg) > + return -ENOMEM; > + > + hdr = genlmsg_iput(msg, &info); > + if (!hdr) { > + ret = -EMSGSIZE; > + goto free_msg; > + } > + > + ret = msg_put_error_event_attrs(msg, node, error_id, error_name, value); > + if (ret) > + goto cancel_msg; > + > + genlmsg_end(msg, hdr); > + genlmsg_multicast(&drm_ras_nl_family, msg, 0, DRM_RAS_NLGRP_ERROR_REPORT, flags); > + return 0; > + > +cancel_msg: > + genlmsg_cancel(msg, hdr); > +free_msg: > + nlmsg_free(msg); > + return ret; > +} > +EXPORT_SYMBOL(drm_ras_nl_error_event); > + > /** > * drm_ras_nl_get_error_counter_dumpit() - Dump all Error Counters > * @skb: Netlink message buffer > diff --git a/drivers/gpu/drm/drm_ras_nl.c b/drivers/gpu/drm/drm_ras_nl.c > index dea1c1b2494e..9d3123cc9f9c 100644 > --- a/drivers/gpu/drm/drm_ras_nl.c > +++ b/drivers/gpu/drm/drm_ras_nl.c > @@ -58,6 +58,10 @@ static const struct genl_split_ops drm_ras_nl_ops[] = { > }, > }; > > +static const struct genl_multicast_group drm_ras_nl_mcgrps[] = { > + [DRM_RAS_NLGRP_ERROR_REPORT] = { "error-report", }, > +}; > + > struct genl_family drm_ras_nl_family __ro_after_init = { > .name = DRM_RAS_FAMILY_NAME, > .version = DRM_RAS_FAMILY_VERSION, > @@ -66,4 +70,6 @@ struct genl_family drm_ras_nl_family __ro_after_init = { > .module = THIS_MODULE, > .split_ops = drm_ras_nl_ops, > .n_split_ops = ARRAY_SIZE(drm_ras_nl_ops), > + .mcgrps = drm_ras_nl_mcgrps, > + .n_mcgrps = ARRAY_SIZE(drm_ras_nl_mcgrps), > }; > diff --git a/drivers/gpu/drm/drm_ras_nl.h b/drivers/gpu/drm/drm_ras_nl.h > index a398643572a5..03ec275aca92 100644 > --- a/drivers/gpu/drm/drm_ras_nl.h > +++ b/drivers/gpu/drm/drm_ras_nl.h > @@ -21,6 +21,10 @@ int drm_ras_nl_get_error_counter_dumpit(struct sk_buff *skb, > int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb, > struct genl_info *info); > > +enum { > + DRM_RAS_NLGRP_ERROR_REPORT, > +}; > + > extern struct genl_family drm_ras_nl_family; > > #endif /* _LINUX_DRM_RAS_GEN_H */ > diff --git a/include/drm/drm_ras.h b/include/drm/drm_ras.h > index 0beede3ddc4e..8abfb7d2077b 100644 > --- a/include/drm/drm_ras.h > +++ b/include/drm/drm_ras.h > @@ -80,9 +80,14 @@ struct drm_device; > #if IS_ENABLED(CONFIG_DRM_RAS) > int drm_ras_node_register(struct drm_ras_node *node); > void drm_ras_node_unregister(struct drm_ras_node *node); > +int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name, > + u32 value, gfp_t flags); > #else > static inline int drm_ras_node_register(struct drm_ras_node *node) { return 0; } > static inline void drm_ras_node_unregister(struct drm_ras_node *node) { } > +static inline int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, > + const char *error_name, u32 value, gfp_t flags) > +{ return 0; } > #endif > > #endif > diff --git a/include/uapi/drm/drm_ras.h b/include/uapi/drm/drm_ras.h > index 218a3ee86805..eab8231aa87c 100644 > --- a/include/uapi/drm/drm_ras.h > +++ b/include/uapi/drm/drm_ras.h > @@ -38,13 +38,28 @@ enum { > DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX = (__DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX - 1) > }; > > +enum { > + DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME = 1, > + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, > + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, > + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, > + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, > + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, > + > + __DRM_RAS_A_ERROR_EVENT_ATTRS_MAX, > + DRM_RAS_A_ERROR_EVENT_ATTRS_MAX = (__DRM_RAS_A_ERROR_EVENT_ATTRS_MAX - 1) > +}; > + > enum { > DRM_RAS_CMD_LIST_NODES = 1, > DRM_RAS_CMD_GET_ERROR_COUNTER, > DRM_RAS_CMD_CLEAR_ERROR_COUNTER, > + DRM_RAS_CMD_ERROR_EVENT, > > __DRM_RAS_CMD_MAX, > DRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1) > }; > > +#define DRM_RAS_MCGRP_ERROR_REPORT "error-report" > + > #endif /* _UAPI_LINUX_DRM_RAS_H */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event 2026-07-07 6:32 ` Tauro, Riana @ 2026-07-08 20:21 ` Rodrigo Vivi 2026-07-09 5:15 ` Tauro, Riana 0 siblings, 1 reply; 9+ messages in thread From: Rodrigo Vivi @ 2026-07-08 20:21 UTC (permalink / raw) To: Tauro, Riana Cc: intel-xe, aravind.iddamsetty, kuba, anshuman.gupta, joonas.lahtinen, simona.vetter, airlied, pratik.bari, joshua.santosh.ranjan, ashwin.kumar.kulkarni, shubham.kumar, ravi.kishore.koppuravuri, raag.jadav, maarten.lankhorst, mallesh.koujalagi, soham.purkait, Zack McKevitt, Lijo Lazar, Hawking Zhang, David S. Miller, Paolo Abeni, Eric Dumazet, dri-devel, netdev On Tue, Jul 07, 2026 at 12:02:11PM +0530, Tauro, Riana wrote: > Hi Rodrigo/Jakub/Aravind > > Please let me know if you have any feedback for this patch or can you please > ack this if it looks good to you. I looks good to me, but could you please double check the sashiko's comments? Patch 3 still needs review I believe, then we get Jakub and drm maintainers acks to get this through drm-xe-next. Thanks, Rodrigo. > > Thanks > Riana > > On 01-07-2026 15:14, Riana Tauro wrote: > > Define a new netlink event 'error-event' and a new multicast group > > 'error-report' in drm_ras. Each event contains device name, node and > > error information to identify the error triggering the event. > > > > Add drm_ras_nl_error_event() to trigger an event from the driver. > > Userspace must subscribe to 'error-report' to receive 'error-event' > > notifications. > > > > Usage: > > > > $ sudo ynl --family drm_ras --subscribe error-report > > > > Cc: Jakub Kicinski <kuba@kernel.org> > > Cc: Zack McKevitt <zachary.mckevitt@oss.qualcomm.com> > > Cc: Lijo Lazar <lijo.lazar@amd.com> > > Cc: Hawking Zhang <Hawking.Zhang@amd.com> > > Cc: David S. Miller <davem@davemloft.net> > > Cc: Paolo Abeni <pabeni@redhat.com> > > Cc: Eric Dumazet <edumazet@google.com> > > Signed-off-by: Riana Tauro <riana.tauro@intel.com> > > Reviewed-by: Raag Jadav <raag.jadav@intel.com> > > --- > > v2: remove redundant initialization > > remove unnecessary space > > use ynl in commit message and doc (Raag) > > simplify doc for error-event attrs > > > > v3: rename error-notify to error-report > > Replace notify with report across the file (Raag) > > --- > > Documentation/gpu/drm-ras.rst | 21 ++++++ > > Documentation/netlink/specs/drm_ras.yaml | 48 +++++++++++++ > > drivers/gpu/drm/drm_ras.c | 87 ++++++++++++++++++++++++ > > drivers/gpu/drm/drm_ras_nl.c | 6 ++ > > drivers/gpu/drm/drm_ras_nl.h | 4 ++ > > include/drm/drm_ras.h | 5 ++ > > include/uapi/drm/drm_ras.h | 15 ++++ > > 7 files changed, 186 insertions(+) > > > > diff --git a/Documentation/gpu/drm-ras.rst b/Documentation/gpu/drm-ras.rst > > index 83c21853b74b..406e4c49bac1 100644 > > --- a/Documentation/gpu/drm-ras.rst > > +++ b/Documentation/gpu/drm-ras.rst > > @@ -56,6 +56,7 @@ User space tools can: > > ``node-id`` and ``error-id`` as parameters. > > * Clear specific error counters with the ``clear-error-counter`` command, using both > > ``node-id`` and ``error-id`` as parameters. > > +* Subscribe to the ``error-report`` multicast group to receive ``error-event``. > > YAML-based Interface > > -------------------- > > @@ -111,3 +112,23 @@ Example: Clear an error counter for a given node > > sudo ynl --family drm_ras --do clear-error-counter --json '{"node-id":0, "error-id":1}' > > None > > + > > +Example: Subscribe to ``error-report`` multicast group > > + > > +.. code-block:: bash > > + > > + sudo ynl --family drm_ras --output-json --subscribe error-report > > + > > +.. code-block:: json > > + > > + { > > + "name": "error-event", > > + "msg": { > > + "device-name": "0000:03:00.0", > > + "node-id": 1, > > + "node-name": "uncorrectable-errors", > > + "error-id": 1, > > + "error-name": "error_name1", > > + "error-value": 1 > > + } > > + } > > diff --git a/Documentation/netlink/specs/drm_ras.yaml b/Documentation/netlink/specs/drm_ras.yaml > > index e113056f8c01..8aed3d4515e5 100644 > > --- a/Documentation/netlink/specs/drm_ras.yaml > > +++ b/Documentation/netlink/specs/drm_ras.yaml > > @@ -69,6 +69,33 @@ attribute-sets: > > name: error-value > > type: u32 > > doc: Current value of the requested error counter. > > + - > > + name: error-event-attrs > > + attributes: > > + - > > + name: device-name > > + type: string > > + doc: Device (PCI BDF, UUID) that reported the error. > > + - > > + name: node-id > > + type: u32 > > + doc: ID of the node that reported the error. > > + - > > + name: node-name > > + type: string > > + doc: Name of the node that reported the error. > > + - > > + name: error-id > > + type: u32 > > + doc: ID of the error counter. > > + - > > + name: error-name > > + type: string > > + doc: Name of the error. > > + - > > + name: error-value > > + type: u32 > > + doc: Current value of the error counter. > > operations: > > list: > > @@ -124,3 +151,24 @@ operations: > > do: > > request: > > attributes: *id-attrs > > + - > > + name: error-event > > + doc: >- > > + Report an error event to userspace. > > + The event includes the device, node and error information > > + of the error that triggered the event. > > + attribute-set: error-event-attrs > > + mcgrp: error-report > > + event: > > + attributes: > > + - device-name > > + - node-id > > + - node-name > > + - error-id > > + - error-name > > + - error-value > > + > > +mcast-groups: > > + list: > > + - > > + name: error-report > > diff --git a/drivers/gpu/drm/drm_ras.c b/drivers/gpu/drm/drm_ras.c > > index d6eab29a1394..77f912a4d101 100644 > > --- a/drivers/gpu/drm/drm_ras.c > > +++ b/drivers/gpu/drm/drm_ras.c > > @@ -41,6 +41,11 @@ > > * Userspace must provide Node ID, Error ID. > > * Clears specific error counter of a node if supported. > > * > > + * 4. ERROR_REPORT: Subscribe to this multicast group to receive error events > > + * > > + * 5. ERROR_EVENT: Report an error event to userspace. The event contains device, node > > + * and error information that triggered the event. > > + * > > * Node registration: > > * > > * - drm_ras_node_register(): Registers a new node and assigns > > @@ -186,6 +191,34 @@ static int msg_reply_value(struct sk_buff *msg, u32 error_id, > > value); > > } > > +static int msg_put_error_event_attrs(struct sk_buff *msg, struct drm_ras_node *node, > > + u32 error_id, const char *error_name, u32 value) > > +{ > > + int ret; > > + > > + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME, node->device_name); > > + if (ret) > > + return ret; > > + > > + ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, node->id); > > + if (ret) > > + return ret; > > + > > + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, node->node_name); > > + if (ret) > > + return ret; > > + > > + ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, error_id); > > + if (ret) > > + return ret; > > + > > + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, error_name); > > + if (ret) > > + return ret; > > + > > + return nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, value); > > +} > > + > > static int doit_reply_value(struct genl_info *info, u32 node_id, > > u32 error_id) > > { > > @@ -222,6 +255,60 @@ static int doit_reply_value(struct genl_info *info, u32 node_id, > > return genlmsg_reply(msg, info); > > } > > +/** > > + * drm_ras_nl_error_event() - Report an error event > > + * @node: Node structure > > + * @error_id: ID of the error > > + * @error_name: Name of the error > > + * @value: Value associated with the error > > + * @flags: GFP flags for memory allocation > > + * > > + * Report an error-event to userspace using the error-report multicast group. > > + * > > + * Return: 0 on success, or negative errno on failure. > > + */ > > +int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name, > > + u32 value, gfp_t flags) > > +{ > > + struct genl_info info; > > + struct sk_buff *msg; > > + struct nlattr *hdr; > > + int ret; > > + > > + if (!error_name) > > + return -EINVAL; > > + > > + if (!genl_has_listeners(&drm_ras_nl_family, &init_net, DRM_RAS_NLGRP_ERROR_REPORT)) > > + return 0; > > + > > + genl_info_init_ntf(&info, &drm_ras_nl_family, DRM_RAS_CMD_ERROR_EVENT); > > + > > + msg = genlmsg_new(NLMSG_GOODSIZE, flags); > > + if (!msg) > > + return -ENOMEM; > > + > > + hdr = genlmsg_iput(msg, &info); > > + if (!hdr) { > > + ret = -EMSGSIZE; > > + goto free_msg; > > + } > > + > > + ret = msg_put_error_event_attrs(msg, node, error_id, error_name, value); > > + if (ret) > > + goto cancel_msg; > > + > > + genlmsg_end(msg, hdr); > > + genlmsg_multicast(&drm_ras_nl_family, msg, 0, DRM_RAS_NLGRP_ERROR_REPORT, flags); > > + return 0; > > + > > +cancel_msg: > > + genlmsg_cancel(msg, hdr); > > +free_msg: > > + nlmsg_free(msg); > > + return ret; > > +} > > +EXPORT_SYMBOL(drm_ras_nl_error_event); > > + > > /** > > * drm_ras_nl_get_error_counter_dumpit() - Dump all Error Counters > > * @skb: Netlink message buffer > > diff --git a/drivers/gpu/drm/drm_ras_nl.c b/drivers/gpu/drm/drm_ras_nl.c > > index dea1c1b2494e..9d3123cc9f9c 100644 > > --- a/drivers/gpu/drm/drm_ras_nl.c > > +++ b/drivers/gpu/drm/drm_ras_nl.c > > @@ -58,6 +58,10 @@ static const struct genl_split_ops drm_ras_nl_ops[] = { > > }, > > }; > > +static const struct genl_multicast_group drm_ras_nl_mcgrps[] = { > > + [DRM_RAS_NLGRP_ERROR_REPORT] = { "error-report", }, > > +}; > > + > > struct genl_family drm_ras_nl_family __ro_after_init = { > > .name = DRM_RAS_FAMILY_NAME, > > .version = DRM_RAS_FAMILY_VERSION, > > @@ -66,4 +70,6 @@ struct genl_family drm_ras_nl_family __ro_after_init = { > > .module = THIS_MODULE, > > .split_ops = drm_ras_nl_ops, > > .n_split_ops = ARRAY_SIZE(drm_ras_nl_ops), > > + .mcgrps = drm_ras_nl_mcgrps, > > + .n_mcgrps = ARRAY_SIZE(drm_ras_nl_mcgrps), > > }; > > diff --git a/drivers/gpu/drm/drm_ras_nl.h b/drivers/gpu/drm/drm_ras_nl.h > > index a398643572a5..03ec275aca92 100644 > > --- a/drivers/gpu/drm/drm_ras_nl.h > > +++ b/drivers/gpu/drm/drm_ras_nl.h > > @@ -21,6 +21,10 @@ int drm_ras_nl_get_error_counter_dumpit(struct sk_buff *skb, > > int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb, > > struct genl_info *info); > > +enum { > > + DRM_RAS_NLGRP_ERROR_REPORT, > > +}; > > + > > extern struct genl_family drm_ras_nl_family; > > #endif /* _LINUX_DRM_RAS_GEN_H */ > > diff --git a/include/drm/drm_ras.h b/include/drm/drm_ras.h > > index 0beede3ddc4e..8abfb7d2077b 100644 > > --- a/include/drm/drm_ras.h > > +++ b/include/drm/drm_ras.h > > @@ -80,9 +80,14 @@ struct drm_device; > > #if IS_ENABLED(CONFIG_DRM_RAS) > > int drm_ras_node_register(struct drm_ras_node *node); > > void drm_ras_node_unregister(struct drm_ras_node *node); > > +int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name, > > + u32 value, gfp_t flags); > > #else > > static inline int drm_ras_node_register(struct drm_ras_node *node) { return 0; } > > static inline void drm_ras_node_unregister(struct drm_ras_node *node) { } > > +static inline int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, > > + const char *error_name, u32 value, gfp_t flags) > > +{ return 0; } > > #endif > > #endif > > diff --git a/include/uapi/drm/drm_ras.h b/include/uapi/drm/drm_ras.h > > index 218a3ee86805..eab8231aa87c 100644 > > --- a/include/uapi/drm/drm_ras.h > > +++ b/include/uapi/drm/drm_ras.h > > @@ -38,13 +38,28 @@ enum { > > DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX = (__DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX - 1) > > }; > > +enum { > > + DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME = 1, > > + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, > > + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, > > + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, > > + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, > > + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, > > + > > + __DRM_RAS_A_ERROR_EVENT_ATTRS_MAX, > > + DRM_RAS_A_ERROR_EVENT_ATTRS_MAX = (__DRM_RAS_A_ERROR_EVENT_ATTRS_MAX - 1) > > +}; > > + > > enum { > > DRM_RAS_CMD_LIST_NODES = 1, > > DRM_RAS_CMD_GET_ERROR_COUNTER, > > DRM_RAS_CMD_CLEAR_ERROR_COUNTER, > > + DRM_RAS_CMD_ERROR_EVENT, > > __DRM_RAS_CMD_MAX, > > DRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1) > > }; > > +#define DRM_RAS_MCGRP_ERROR_REPORT "error-report" > > + > > #endif /* _UAPI_LINUX_DRM_RAS_H */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event 2026-07-08 20:21 ` Rodrigo Vivi @ 2026-07-09 5:15 ` Tauro, Riana 2026-07-09 9:22 ` Raag Jadav 0 siblings, 1 reply; 9+ messages in thread From: Tauro, Riana @ 2026-07-09 5:15 UTC (permalink / raw) To: Rodrigo Vivi, raag.jadav, kuba, aravind.iddamsetty Cc: intel-xe, anshuman.gupta, joonas.lahtinen, simona.vetter, airlied, pratik.bari, joshua.santosh.ranjan, ashwin.kumar.kulkarni, shubham.kumar, ravi.kishore.koppuravuri, maarten.lankhorst, mallesh.koujalagi, soham.purkait, Zack McKevitt, Lijo Lazar, Hawking Zhang, David S. Miller, Paolo Abeni, Eric Dumazet, dri-devel, netdev On 09-07-2026 01:51, Rodrigo Vivi wrote: > On Tue, Jul 07, 2026 at 12:02:11PM +0530, Tauro, Riana wrote: >> Hi Rodrigo/Jakub/Aravind >> >> Please let me know if you have any feedback for this patch or can you please >> ack this if it looks good to you. > I looks good to me, but could you please double check the sashiko's comments? Sashiko has a comment regarding namespaces [Severity: Medium]Since the generic netlink family explicitly supports multiple networknamespaces by setting .netnsok = true, will hardcoding init_net hereprevent listeners in non-init namespaces from receiving error events .netnsok = true is auto generated not explicitly added in code. But from what i see, drm device is present in the host and not replicated across namespaces and most of the non-network implementations use inet. (ex: Binder) If this really needs a fix, we can drop the has_listeners suggested by raag in previous patch. I don't think in an error path, allocating a new buffer would be a big overhead if listeners are not present. @Raag let me know your thoughts. The 3rd patch can be floated seperately, I can drop it before merging and resend if i can get an ack for this patch Thanks Riana > > Patch 3 still needs review I believe, then we get Jakub and drm maintainers acks > to get this through drm-xe-next. > > Thanks, > Rodrigo. > >> Thanks >> Riana >> >> On 01-07-2026 15:14, Riana Tauro wrote: >>> Define a new netlink event 'error-event' and a new multicast group >>> 'error-report' in drm_ras. Each event contains device name, node and >>> error information to identify the error triggering the event. >>> >>> Add drm_ras_nl_error_event() to trigger an event from the driver. >>> Userspace must subscribe to 'error-report' to receive 'error-event' >>> notifications. >>> >>> Usage: >>> >>> $ sudo ynl --family drm_ras --subscribe error-report >>> >>> Cc: Jakub Kicinski <kuba@kernel.org> >>> Cc: Zack McKevitt <zachary.mckevitt@oss.qualcomm.com> >>> Cc: Lijo Lazar <lijo.lazar@amd.com> >>> Cc: Hawking Zhang <Hawking.Zhang@amd.com> >>> Cc: David S. Miller <davem@davemloft.net> >>> Cc: Paolo Abeni <pabeni@redhat.com> >>> Cc: Eric Dumazet <edumazet@google.com> >>> Signed-off-by: Riana Tauro <riana.tauro@intel.com> >>> Reviewed-by: Raag Jadav <raag.jadav@intel.com> >>> --- >>> v2: remove redundant initialization >>> remove unnecessary space >>> use ynl in commit message and doc (Raag) >>> simplify doc for error-event attrs >>> >>> v3: rename error-notify to error-report >>> Replace notify with report across the file (Raag) >>> --- >>> Documentation/gpu/drm-ras.rst | 21 ++++++ >>> Documentation/netlink/specs/drm_ras.yaml | 48 +++++++++++++ >>> drivers/gpu/drm/drm_ras.c | 87 ++++++++++++++++++++++++ >>> drivers/gpu/drm/drm_ras_nl.c | 6 ++ >>> drivers/gpu/drm/drm_ras_nl.h | 4 ++ >>> include/drm/drm_ras.h | 5 ++ >>> include/uapi/drm/drm_ras.h | 15 ++++ >>> 7 files changed, 186 insertions(+) >>> >>> diff --git a/Documentation/gpu/drm-ras.rst b/Documentation/gpu/drm-ras.rst >>> index 83c21853b74b..406e4c49bac1 100644 >>> --- a/Documentation/gpu/drm-ras.rst >>> +++ b/Documentation/gpu/drm-ras.rst >>> @@ -56,6 +56,7 @@ User space tools can: >>> ``node-id`` and ``error-id`` as parameters. >>> * Clear specific error counters with the ``clear-error-counter`` command, using both >>> ``node-id`` and ``error-id`` as parameters. >>> +* Subscribe to the ``error-report`` multicast group to receive ``error-event``. >>> YAML-based Interface >>> -------------------- >>> @@ -111,3 +112,23 @@ Example: Clear an error counter for a given node >>> sudo ynl --family drm_ras --do clear-error-counter --json '{"node-id":0, "error-id":1}' >>> None >>> + >>> +Example: Subscribe to ``error-report`` multicast group >>> + >>> +.. code-block:: bash >>> + >>> + sudo ynl --family drm_ras --output-json --subscribe error-report >>> + >>> +.. code-block:: json >>> + >>> + { >>> + "name": "error-event", >>> + "msg": { >>> + "device-name": "0000:03:00.0", >>> + "node-id": 1, >>> + "node-name": "uncorrectable-errors", >>> + "error-id": 1, >>> + "error-name": "error_name1", >>> + "error-value": 1 >>> + } >>> + } >>> diff --git a/Documentation/netlink/specs/drm_ras.yaml b/Documentation/netlink/specs/drm_ras.yaml >>> index e113056f8c01..8aed3d4515e5 100644 >>> --- a/Documentation/netlink/specs/drm_ras.yaml >>> +++ b/Documentation/netlink/specs/drm_ras.yaml >>> @@ -69,6 +69,33 @@ attribute-sets: >>> name: error-value >>> type: u32 >>> doc: Current value of the requested error counter. >>> + - >>> + name: error-event-attrs >>> + attributes: >>> + - >>> + name: device-name >>> + type: string >>> + doc: Device (PCI BDF, UUID) that reported the error. >>> + - >>> + name: node-id >>> + type: u32 >>> + doc: ID of the node that reported the error. >>> + - >>> + name: node-name >>> + type: string >>> + doc: Name of the node that reported the error. >>> + - >>> + name: error-id >>> + type: u32 >>> + doc: ID of the error counter. >>> + - >>> + name: error-name >>> + type: string >>> + doc: Name of the error. >>> + - >>> + name: error-value >>> + type: u32 >>> + doc: Current value of the error counter. >>> operations: >>> list: >>> @@ -124,3 +151,24 @@ operations: >>> do: >>> request: >>> attributes: *id-attrs >>> + - >>> + name: error-event >>> + doc: >- >>> + Report an error event to userspace. >>> + The event includes the device, node and error information >>> + of the error that triggered the event. >>> + attribute-set: error-event-attrs >>> + mcgrp: error-report >>> + event: >>> + attributes: >>> + - device-name >>> + - node-id >>> + - node-name >>> + - error-id >>> + - error-name >>> + - error-value >>> + >>> +mcast-groups: >>> + list: >>> + - >>> + name: error-report >>> diff --git a/drivers/gpu/drm/drm_ras.c b/drivers/gpu/drm/drm_ras.c >>> index d6eab29a1394..77f912a4d101 100644 >>> --- a/drivers/gpu/drm/drm_ras.c >>> +++ b/drivers/gpu/drm/drm_ras.c >>> @@ -41,6 +41,11 @@ >>> * Userspace must provide Node ID, Error ID. >>> * Clears specific error counter of a node if supported. >>> * >>> + * 4. ERROR_REPORT: Subscribe to this multicast group to receive error events >>> + * >>> + * 5. ERROR_EVENT: Report an error event to userspace. The event contains device, node >>> + * and error information that triggered the event. >>> + * >>> * Node registration: >>> * >>> * - drm_ras_node_register(): Registers a new node and assigns >>> @@ -186,6 +191,34 @@ static int msg_reply_value(struct sk_buff *msg, u32 error_id, >>> value); >>> } >>> +static int msg_put_error_event_attrs(struct sk_buff *msg, struct drm_ras_node *node, >>> + u32 error_id, const char *error_name, u32 value) >>> +{ >>> + int ret; >>> + >>> + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME, node->device_name); >>> + if (ret) >>> + return ret; >>> + >>> + ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, node->id); >>> + if (ret) >>> + return ret; >>> + >>> + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, node->node_name); >>> + if (ret) >>> + return ret; >>> + >>> + ret = nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, error_id); >>> + if (ret) >>> + return ret; >>> + >>> + ret = nla_put_string(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, error_name); >>> + if (ret) >>> + return ret; >>> + >>> + return nla_put_u32(msg, DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, value); >>> +} >>> + >>> static int doit_reply_value(struct genl_info *info, u32 node_id, >>> u32 error_id) >>> { >>> @@ -222,6 +255,60 @@ static int doit_reply_value(struct genl_info *info, u32 node_id, >>> return genlmsg_reply(msg, info); >>> } >>> +/** >>> + * drm_ras_nl_error_event() - Report an error event >>> + * @node: Node structure >>> + * @error_id: ID of the error >>> + * @error_name: Name of the error >>> + * @value: Value associated with the error >>> + * @flags: GFP flags for memory allocation >>> + * >>> + * Report an error-event to userspace using the error-report multicast group. >>> + * >>> + * Return: 0 on success, or negative errno on failure. >>> + */ >>> +int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name, >>> + u32 value, gfp_t flags) >>> +{ >>> + struct genl_info info; >>> + struct sk_buff *msg; >>> + struct nlattr *hdr; >>> + int ret; >>> + >>> + if (!error_name) >>> + return -EINVAL; >>> + >>> + if (!genl_has_listeners(&drm_ras_nl_family, &init_net, DRM_RAS_NLGRP_ERROR_REPORT)) >>> + return 0; >>> + >>> + genl_info_init_ntf(&info, &drm_ras_nl_family, DRM_RAS_CMD_ERROR_EVENT); >>> + >>> + msg = genlmsg_new(NLMSG_GOODSIZE, flags); >>> + if (!msg) >>> + return -ENOMEM; >>> + >>> + hdr = genlmsg_iput(msg, &info); >>> + if (!hdr) { >>> + ret = -EMSGSIZE; >>> + goto free_msg; >>> + } >>> + >>> + ret = msg_put_error_event_attrs(msg, node, error_id, error_name, value); >>> + if (ret) >>> + goto cancel_msg; >>> + >>> + genlmsg_end(msg, hdr); >>> + genlmsg_multicast(&drm_ras_nl_family, msg, 0, DRM_RAS_NLGRP_ERROR_REPORT, flags); >>> + return 0; >>> + >>> +cancel_msg: >>> + genlmsg_cancel(msg, hdr); >>> +free_msg: >>> + nlmsg_free(msg); >>> + return ret; >>> +} >>> +EXPORT_SYMBOL(drm_ras_nl_error_event); >>> + >>> /** >>> * drm_ras_nl_get_error_counter_dumpit() - Dump all Error Counters >>> * @skb: Netlink message buffer >>> diff --git a/drivers/gpu/drm/drm_ras_nl.c b/drivers/gpu/drm/drm_ras_nl.c >>> index dea1c1b2494e..9d3123cc9f9c 100644 >>> --- a/drivers/gpu/drm/drm_ras_nl.c >>> +++ b/drivers/gpu/drm/drm_ras_nl.c >>> @@ -58,6 +58,10 @@ static const struct genl_split_ops drm_ras_nl_ops[] = { >>> }, >>> }; >>> +static const struct genl_multicast_group drm_ras_nl_mcgrps[] = { >>> + [DRM_RAS_NLGRP_ERROR_REPORT] = { "error-report", }, >>> +}; >>> + >>> struct genl_family drm_ras_nl_family __ro_after_init = { >>> .name = DRM_RAS_FAMILY_NAME, >>> .version = DRM_RAS_FAMILY_VERSION, >>> @@ -66,4 +70,6 @@ struct genl_family drm_ras_nl_family __ro_after_init = { >>> .module = THIS_MODULE, >>> .split_ops = drm_ras_nl_ops, >>> .n_split_ops = ARRAY_SIZE(drm_ras_nl_ops), >>> + .mcgrps = drm_ras_nl_mcgrps, >>> + .n_mcgrps = ARRAY_SIZE(drm_ras_nl_mcgrps), >>> }; >>> diff --git a/drivers/gpu/drm/drm_ras_nl.h b/drivers/gpu/drm/drm_ras_nl.h >>> index a398643572a5..03ec275aca92 100644 >>> --- a/drivers/gpu/drm/drm_ras_nl.h >>> +++ b/drivers/gpu/drm/drm_ras_nl.h >>> @@ -21,6 +21,10 @@ int drm_ras_nl_get_error_counter_dumpit(struct sk_buff *skb, >>> int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb, >>> struct genl_info *info); >>> +enum { >>> + DRM_RAS_NLGRP_ERROR_REPORT, >>> +}; >>> + >>> extern struct genl_family drm_ras_nl_family; >>> #endif /* _LINUX_DRM_RAS_GEN_H */ >>> diff --git a/include/drm/drm_ras.h b/include/drm/drm_ras.h >>> index 0beede3ddc4e..8abfb7d2077b 100644 >>> --- a/include/drm/drm_ras.h >>> +++ b/include/drm/drm_ras.h >>> @@ -80,9 +80,14 @@ struct drm_device; >>> #if IS_ENABLED(CONFIG_DRM_RAS) >>> int drm_ras_node_register(struct drm_ras_node *node); >>> void drm_ras_node_unregister(struct drm_ras_node *node); >>> +int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, const char *error_name, >>> + u32 value, gfp_t flags); >>> #else >>> static inline int drm_ras_node_register(struct drm_ras_node *node) { return 0; } >>> static inline void drm_ras_node_unregister(struct drm_ras_node *node) { } >>> +static inline int drm_ras_nl_error_event(struct drm_ras_node *node, u32 error_id, >>> + const char *error_name, u32 value, gfp_t flags) >>> +{ return 0; } >>> #endif >>> #endif >>> diff --git a/include/uapi/drm/drm_ras.h b/include/uapi/drm/drm_ras.h >>> index 218a3ee86805..eab8231aa87c 100644 >>> --- a/include/uapi/drm/drm_ras.h >>> +++ b/include/uapi/drm/drm_ras.h >>> @@ -38,13 +38,28 @@ enum { >>> DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX = (__DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX - 1) >>> }; >>> +enum { >>> + DRM_RAS_A_ERROR_EVENT_ATTRS_DEVICE_NAME = 1, >>> + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID, >>> + DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_NAME, >>> + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID, >>> + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_NAME, >>> + DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE, >>> + >>> + __DRM_RAS_A_ERROR_EVENT_ATTRS_MAX, >>> + DRM_RAS_A_ERROR_EVENT_ATTRS_MAX = (__DRM_RAS_A_ERROR_EVENT_ATTRS_MAX - 1) >>> +}; >>> + >>> enum { >>> DRM_RAS_CMD_LIST_NODES = 1, >>> DRM_RAS_CMD_GET_ERROR_COUNTER, >>> DRM_RAS_CMD_CLEAR_ERROR_COUNTER, >>> + DRM_RAS_CMD_ERROR_EVENT, >>> __DRM_RAS_CMD_MAX, >>> DRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1) >>> }; >>> +#define DRM_RAS_MCGRP_ERROR_REPORT "error-report" >>> + >>> #endif /* _UAPI_LINUX_DRM_RAS_H */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event 2026-07-09 5:15 ` Tauro, Riana @ 2026-07-09 9:22 ` Raag Jadav 0 siblings, 0 replies; 9+ messages in thread From: Raag Jadav @ 2026-07-09 9:22 UTC (permalink / raw) To: Tauro, Riana Cc: Rodrigo Vivi, kuba, aravind.iddamsetty, intel-xe, anshuman.gupta, joonas.lahtinen, simona.vetter, airlied, pratik.bari, joshua.santosh.ranjan, ashwin.kumar.kulkarni, shubham.kumar, ravi.kishore.koppuravuri, maarten.lankhorst, mallesh.koujalagi, soham.purkait, Zack McKevitt, Lijo Lazar, Hawking Zhang, David S. Miller, Paolo Abeni, Eric Dumazet, dri-devel, netdev On Thu, Jul 09, 2026 at 10:45:27AM +0530, Tauro, Riana wrote: > On 09-07-2026 01:51, Rodrigo Vivi wrote: > > On Tue, Jul 07, 2026 at 12:02:11PM +0530, Tauro, Riana wrote: > > > Hi Rodrigo/Jakub/Aravind > > > > > > Please let me know if you have any feedback for this patch or can you please > > > ack this if it looks good to you. > > I looks good to me, but could you please double check the sashiko's comments? > > Sashiko has a comment regarding namespaces > > [Severity: Medium]Since the generic netlink family explicitly supports > multiple networknamespaces by setting .netnsok = true, > will hardcoding init_net hereprevent listeners in non-init namespaces from > receiving error events > > .netnsok = true is auto generated not explicitly added in code. Because that's what ynl_gen_c.py does without it being parsed from anywhere. > But from what i see, drm device is present in the host and not replicated > across namespaces > and most of the non-network implementations use inet. (ex: Binder) > If this really needs a fix, we can drop the has_listeners suggested by raag > in previous patch. > I don't think in an error path, allocating a new buffer would be a big > overhead if listeners are not present. I don't know enough about namespaces to comment on this. I'll rely on Jakub's disposition if netnsok is relevant here, or needed at all for our usecase. Raag ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v4 2/3] drm/xe/xe_drm_ras: Add error-event support for PVC 2026-07-01 9:44 [PATCH v4 0/3] Add drm_ras netlink error event support Riana Tauro 2026-07-01 9:44 ` [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event Riana Tauro @ 2026-07-01 9:44 ` Riana Tauro 2026-07-01 9:44 ` [PATCH v4 3/3] drm/xe/xe_ras: Add error-event support for CRI Riana Tauro 2 siblings, 0 replies; 9+ messages in thread From: Riana Tauro @ 2026-07-01 9:44 UTC (permalink / raw) To: intel-xe, dri-devel, netdev Cc: aravind.iddamsetty, anshuman.gupta, rodrigo.vivi, joonas.lahtinen, kuba, simona.vetter, airlied, pratik.bari, joshua.santosh.ranjan, ashwin.kumar.kulkarni, shubham.kumar, ravi.kishore.koppuravuri, raag.jadav, maarten.lankhorst, mallesh.koujalagi, soham.purkait, Riana Tauro Report drm_ras error event to userspace when an error occurs. Add support for core-compute and SoC errors in PVC. $ sudo ynl --family drm_ras --output-json --subscribe error-report { "name": "error-event", "msg": { "device-name": "0000:03:00.0", "node-id": 1, "node-name": "uncorrectable-errors", "error-id": 1, "error-name": "core-compute", "error-value": 1 } } Signed-off-by: Riana Tauro <riana.tauro@intel.com> Reviewed-by: Raag Jadav <raag.jadav@intel.com> --- v2: use ynl (Raag) use value as function parameter move error event call to hw_error_source_handler v3: add has_drm_ras check v4: use drm_err_ratelimited initialize node post drm_ras check (Sashiko) --- drivers/gpu/drm/xe/xe_drm_ras.c | 32 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_drm_ras.h | 3 +++ drivers/gpu/drm/xe/xe_hw_error.c | 5 ++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/xe_drm_ras.c b/drivers/gpu/drm/xe/xe_drm_ras.c index 7937d8ba0ed9..8e247a8139b1 100644 --- a/drivers/gpu/drm/xe/xe_drm_ras.c +++ b/drivers/gpu/drm/xe/xe_drm_ras.c @@ -185,6 +185,38 @@ static int register_nodes(struct xe_device *xe) return ret; } +/** + * xe_drm_ras_event() - Report drm_ras error event to userspace + * @xe: xe device structure + * @component: error component (see &enum drm_xe_ras_error_component) + * @severity: error severity (see &enum drm_xe_ras_error_severity) + * @value: value of error counter + * @flags: flags for allocation + * + * Report an error-event to userspace. + */ +void xe_drm_ras_event(struct xe_device *xe, u32 component, u32 severity, u32 value, gfp_t flags) +{ + struct xe_drm_ras *ras = &xe->ras; + struct xe_drm_ras_counter *info = ras->info[severity]; + struct drm_ras_node *node; + int ret; + + /* Event is supported only if drm_ras is enabled */ + if (!xe->info.has_drm_ras) + return; + + node = &ras->node[severity]; + + if (!info || !info[component].name) + return; + + ret = drm_ras_nl_error_event(node, component, info[component].name, value, flags); + if (ret) + drm_err_ratelimited(&xe->drm, "drm_ras error-event failed: %d for %s %s\n", ret, + info[component].name, error_severity[severity]); +} + /** * xe_drm_ras_init() - Initialize DRM RAS * @xe: xe device instance diff --git a/drivers/gpu/drm/xe/xe_drm_ras.h b/drivers/gpu/drm/xe/xe_drm_ras.h index 365c70e93e82..2a694bf69478 100644 --- a/drivers/gpu/drm/xe/xe_drm_ras.h +++ b/drivers/gpu/drm/xe/xe_drm_ras.h @@ -5,11 +5,14 @@ #ifndef _XE_DRM_RAS_H_ #define _XE_DRM_RAS_H_ +#include <linux/types.h> + struct xe_device; #define for_each_error_severity(i) \ for (i = 0; i < DRM_XE_RAS_ERR_SEV_MAX; i++) int xe_drm_ras_init(struct xe_device *xe); +void xe_drm_ras_event(struct xe_device *xe, u32 component, u32 severity, u32 value, gfp_t flags); #endif diff --git a/drivers/gpu/drm/xe/xe_hw_error.c b/drivers/gpu/drm/xe/xe_hw_error.c index 4a4b363fc844..a833cecc74ec 100644 --- a/drivers/gpu/drm/xe/xe_hw_error.c +++ b/drivers/gpu/drm/xe/xe_hw_error.c @@ -432,7 +432,7 @@ static void hw_error_source_handler(struct xe_tile *tile, const enum hardware_er struct xe_drm_ras *ras = &xe->ras; struct xe_drm_ras_counter *info = ras->info[severity]; unsigned long flags, err_src; - u32 err_bit; + u32 err_bit, value; if (!IS_DGFX(xe)) return; @@ -495,6 +495,9 @@ static void hw_error_source_handler(struct xe_tile *tile, const enum hardware_er gt_hw_error_handler(tile, hw_err, error_id); if (err_bit == XE_SOC_ERROR) soc_hw_error_handler(tile, hw_err, error_id); + + value = atomic_read(&info[error_id].counter); + xe_drm_ras_event(xe, error_id, severity, value, GFP_ATOMIC); } clear_reg: -- 2.47.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v4 3/3] drm/xe/xe_ras: Add error-event support for CRI 2026-07-01 9:44 [PATCH v4 0/3] Add drm_ras netlink error event support Riana Tauro 2026-07-01 9:44 ` [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event Riana Tauro 2026-07-01 9:44 ` [PATCH v4 2/3] drm/xe/xe_drm_ras: Add error-event support for PVC Riana Tauro @ 2026-07-01 9:44 ` Riana Tauro 2026-07-09 10:04 ` Raag Jadav 2 siblings, 1 reply; 9+ messages in thread From: Riana Tauro @ 2026-07-01 9:44 UTC (permalink / raw) To: intel-xe, dri-devel, netdev Cc: aravind.iddamsetty, anshuman.gupta, rodrigo.vivi, joonas.lahtinen, kuba, simona.vetter, airlied, pratik.bari, joshua.santosh.ranjan, ashwin.kumar.kulkarni, shubham.kumar, ravi.kishore.koppuravuri, raag.jadav, maarten.lankhorst, mallesh.koujalagi, soham.purkait, Riana Tauro, Michal Wajdeczko Add error-event support for Correctable errors in CRI. Report an error event to userspace for every component that has crossed the threshold on receiving an interrupt. Cc: Michal Wajdeczko <michal.wajdeczko@intel.com> Signed-off-by: Riana Tauro <riana.tauro@intel.com> --- v2: add warns for unexpected values from system controller (Michal) send an event at most once per component for each interrupt (Raag) use correct parameters for get_counter (Sashiko) --- drivers/gpu/drm/xe/xe_ras.c | 75 +++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_ras.c b/drivers/gpu/drm/xe/xe_ras.c index 44f4e1a3455b..b71d51285954 100644 --- a/drivers/gpu/drm/xe/xe_ras.c +++ b/drivers/gpu/drm/xe/xe_ras.c @@ -77,6 +77,18 @@ static u8 drm_to_xe_ras_severity(u8 severity) } } +static u8 xe_to_drm_ras_severity(u8 severity) +{ + switch (severity) { + case XE_RAS_SEV_CORRECTABLE: + return DRM_XE_RAS_ERR_SEV_CORRECTABLE; + case XE_RAS_SEV_UNCORRECTABLE: + return DRM_XE_RAS_ERR_SEV_UNCORRECTABLE; + default: + return DRM_XE_RAS_ERR_SEV_MAX; + } +} + static u8 drm_to_xe_ras_component(u8 component) { switch (component) { @@ -95,6 +107,24 @@ static u8 drm_to_xe_ras_component(u8 component) } } +static u8 xe_to_drm_ras_component(u8 component) +{ + switch (component) { + case XE_RAS_COMP_DEVICE_MEMORY: + return DRM_XE_RAS_ERR_COMP_DEVICE_MEMORY; + case XE_RAS_COMP_CORE_COMPUTE: + return DRM_XE_RAS_ERR_COMP_CORE_COMPUTE; + case XE_RAS_COMP_PCIE: + return DRM_XE_RAS_ERR_COMP_PCIE; + case XE_RAS_COMP_FABRIC: + return DRM_XE_RAS_ERR_COMP_FABRIC; + case XE_RAS_COMP_SOC_INTERNAL: + return DRM_XE_RAS_ERR_COMP_SOC_INTERNAL; + default: + return DRM_XE_RAS_ERR_COMP_MAX; + } +} + static int ras_status_to_errno(u32 status) { switch (status) { @@ -131,14 +161,41 @@ static inline const char *comp_to_str(u8 component) return xe_ras_components[component]; } +static void ras_send_error_event(struct xe_device *xe, u8 severity, u8 component) +{ + u8 drm_severity, drm_component; + u32 value; + int ret; + + drm_severity = xe_to_drm_ras_severity(severity); + if (drm_severity == DRM_XE_RAS_ERR_SEV_MAX) { + xe_warn(xe, "sysctrl: unexpected severity %u\n", severity); + return; + } + + drm_component = xe_to_drm_ras_component(component); + if (drm_component == DRM_XE_RAS_ERR_COMP_MAX) { + xe_warn(xe, "sysctrl: unexpected component %u\n", component); + return; + } + + ret = xe_ras_get_counter(xe, drm_severity, drm_component, &value); + if (ret) + return; + + xe_drm_ras_event(xe, drm_component, drm_severity, value, GFP_KERNEL); +} + void xe_ras_counter_threshold_crossed(struct xe_device *xe, struct xe_sysctrl_event_response *response) { 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(XE_RAS_COMP_MAX > (BITS_PER_BYTE * sizeof(sent))); xe_device_assert_mem_access(xe); if (!ncounters || ncounters > XE_RAS_NUM_COUNTERS) @@ -154,6 +211,24 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe, xe_warn(xe, "[RAS]: %s %s detected\n", comp_to_str(component), sev_to_str(severity)); + + if (severity != XE_RAS_SEV_CORRECTABLE) { + xe_warn(xe, "sysctrl: unexpected severity %s (%u)\n", sev_to_str(severity), + severity); + continue; + } + + if (component >= XE_RAS_COMP_MAX) { + xe_warn(xe, "sysctrl: unexpected component %u\n", component); + continue; + } + + /* Send event once per component */ + if (sent & BIT(component)) + continue; + sent |= BIT(component); + + ras_send_error_event(xe, severity, component); } } -- 2.47.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v4 3/3] drm/xe/xe_ras: Add error-event support for CRI 2026-07-01 9:44 ` [PATCH v4 3/3] drm/xe/xe_ras: Add error-event support for CRI Riana Tauro @ 2026-07-09 10:04 ` Raag Jadav 0 siblings, 0 replies; 9+ messages in thread From: Raag Jadav @ 2026-07-09 10:04 UTC (permalink / raw) To: Riana Tauro Cc: intel-xe, dri-devel, netdev, aravind.iddamsetty, anshuman.gupta, rodrigo.vivi, joonas.lahtinen, kuba, simona.vetter, airlied, pratik.bari, joshua.santosh.ranjan, ashwin.kumar.kulkarni, shubham.kumar, ravi.kishore.koppuravuri, maarten.lankhorst, mallesh.koujalagi, soham.purkait, Michal Wajdeczko On Wed, Jul 01, 2026 at 03:14:13PM +0530, Riana Tauro wrote: > Add error-event support for Correctable errors in CRI. Report an error > event to userspace for every component that has crossed the threshold on > receiving an interrupt. ... > +static void ras_send_error_event(struct xe_device *xe, u8 severity, u8 component) > +{ > + u8 drm_severity, drm_component; > + u32 value; > + int ret; > + > + drm_severity = xe_to_drm_ras_severity(severity); > + if (drm_severity == DRM_XE_RAS_ERR_SEV_MAX) { > + xe_warn(xe, "sysctrl: unexpected severity %u\n", severity); This is uapi and not coming from sysctrl, so the message is a bit misleading. But if at all it needs validation, it should be done in drm_ras layer. > + return; > + } > + > + drm_component = xe_to_drm_ras_component(component); > + if (drm_component == DRM_XE_RAS_ERR_COMP_MAX) { > + xe_warn(xe, "sysctrl: unexpected component %u\n", component); Ditto. > + return; > + } > + > + ret = xe_ras_get_counter(xe, drm_severity, drm_component, &value); No, instead of converting back and forth just do get_counter() using sysctrl values and send_event() afterwards. > + if (ret) > + return; > + > + xe_drm_ras_event(xe, drm_component, drm_severity, value, GFP_KERNEL); > +} > + > void xe_ras_counter_threshold_crossed(struct xe_device *xe, > struct xe_sysctrl_event_response *response) > { > 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(XE_RAS_COMP_MAX > (BITS_PER_BYTE * sizeof(sent))); I prefer it the other way around. Also, have you tried using BITS_PER_TYPE()? BUILD_BUG_ON(BITS_PER_TYPE(sent) < XE_RAS_COMP_MAX)); > xe_device_assert_mem_access(xe); > > if (!ncounters || ncounters > XE_RAS_NUM_COUNTERS) > @@ -154,6 +211,24 @@ void xe_ras_counter_threshold_crossed(struct xe_device *xe, > > xe_warn(xe, "[RAS]: %s %s detected\n", > comp_to_str(component), sev_to_str(severity)); > + > + if (severity != XE_RAS_SEV_CORRECTABLE) { > + xe_warn(xe, "sysctrl: unexpected severity %s (%u)\n", sev_to_str(severity), > + severity); This should be before "detected" log above. > + continue; > + } > + > + if (component >= XE_RAS_COMP_MAX) { > + xe_warn(xe, "sysctrl: unexpected component %u\n", component); Ditto. Also, use xx_to_str() in both cases or don't but be consistent. Raag > + continue; > + } > + > + /* Send event once per component */ > + if (sent & BIT(component)) > + continue; > + sent |= BIT(component); > + > + ras_send_error_event(xe, severity, component); > } > } > > -- > 2.47.1 > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-07-09 10:04 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-01 9:44 [PATCH v4 0/3] Add drm_ras netlink error event support Riana Tauro 2026-07-01 9:44 ` [PATCH v4 1/3] drm/drm_ras: Add drm_ras netlink error event Riana Tauro 2026-07-07 6:32 ` Tauro, Riana 2026-07-08 20:21 ` Rodrigo Vivi 2026-07-09 5:15 ` Tauro, Riana 2026-07-09 9:22 ` Raag Jadav 2026-07-01 9:44 ` [PATCH v4 2/3] drm/xe/xe_drm_ras: Add error-event support for PVC Riana Tauro 2026-07-01 9:44 ` [PATCH v4 3/3] drm/xe/xe_ras: Add error-event support for CRI Riana Tauro 2026-07-09 10:04 ` Raag Jadav
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox