[PATCH 6/8] lib/igt_drm_netlink: add event notify subscription and event wait support
Ravi Kishore Koppuravuri <[email protected]> Wed, 29 Jul 2026 17:49:57 +0530
| Newsgroups | org.freedesktop.lists.igt-dev |
|---|---|
| Message-ID | <[email protected]> |
Added event notification support with subscribe for an error-notify event and wait for the event notification functionalities. Signed-off-by: Ravi Kishore Koppuravuri <[email protected]> --- lib/igt_drm_netlink.c | 108 ++++++++++++++++++++++++++++++++++++++++++ lib/igt_drm_netlink.h | 6 +++ 2 files changed, 114 insertions(+) diff --git a/lib/igt_drm_netlink.c b/lib/igt_drm_netlink.c index 4738090af..b72fb343d 100644 --- a/lib/igt_drm_netlink.c +++ b/lib/igt_drm_netlink.c @@ -6,6 +6,7 @@ #include <stdbool.h> #include <stdint.h> #include <errno.h> +#include <poll.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -31,6 +32,26 @@ static int ras_command_cb(struct nl_msg *msg, void *arg) switch (gnlh->cmd) { case DRM_RAS_CMD_SET_ERROR_THRESHOLD: break; + case DRM_RAS_CMD_ERROR_EVENT: { + struct nlattr *attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_MAX + 1]; + + ret = genlmsg_parse(nlh, 0, attrs, + DRM_RAS_A_ERROR_EVENT_ATTRS_MAX, NULL); + if (ret < 0) + return NL_SKIP; + + if (!attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID] || + !attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID] || + !attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE]) + return NL_SKIP; + + ctx->event_node_id = nla_get_u32(attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID]); + ctx->event_error_id = nla_get_u32(attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID]); + ctx->event_error_value = + nla_get_u32(attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE]); + ctx->event_received = true; + break; + } case DRM_RAS_CMD_GET_ERROR_COUNTER: { struct nlattr *attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX + 1]; @@ -171,6 +192,10 @@ int init_app_context(struct app_context *ctx) ctx->error_id = UINT32_MAX; ctx->error_value = 0; ctx->error_threshold = 0; + ctx->event_node_id = UINT32_MAX; + ctx->event_error_id = UINT32_MAX; + ctx->event_error_value = 0; + ctx->event_received = false; ctx->family_id = -1; return 0; @@ -186,6 +211,10 @@ void cleanup_app_context(struct app_context *ctx) ctx->error_id = UINT32_MAX; ctx->error_value = 0; ctx->error_threshold = 0; + ctx->event_node_id = UINT32_MAX; + ctx->event_error_id = UINT32_MAX; + ctx->event_error_value = 0; + ctx->event_received = false; ctx->family_id = -1; } @@ -319,3 +348,82 @@ int set_error_threshold(struct app_context *ctx) return 0; } + +int subscribe_error_notify(struct app_context *ctx, const char *notify_group_name) +{ + int grp_id; + int ret; + + if (!ctx || !ctx->sock || ctx->family_id < 0 || + !notify_group_name || notify_group_name[0] == '\0') + return -EINVAL; + + grp_id = genl_ctrl_resolve_grp(ctx->sock, + DRM_RAS_FAMILY_NAME, + notify_group_name); + if (grp_id < 0) + return grp_id; + + ret = nl_socket_add_membership(ctx->sock, grp_id); + if (ret < 0) + return ret; + + igt_debug("Subscribed to DRM RAS multicast group '%s' (id=%d).\n", + notify_group_name, grp_id); + + return 0; +} + +int wait_for_error_notify_event(struct app_context *ctx, int timeout_ms) +{ + struct nl_cb *cb; + struct pollfd pfd; + int ret; + + if (!ctx || !ctx->sock || ctx->family_id < 0) + return -EINVAL; + + if (timeout_ms < -1) + return -EINVAL; + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) + return -ENOMEM; + + ret = nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, ras_command_cb, ctx); + if (ret < 0) { + nl_cb_put(cb); + return ret; + } + + ctx->event_received = false; + + pfd.fd = nl_socket_get_fd(ctx->sock); + pfd.events = POLLIN; + pfd.revents = 0; + + ret = poll(&pfd, 1, timeout_ms); + if (ret == 0) { + nl_cb_put(cb); + return -ETIMEDOUT; + } + + if (ret < 0) { + ret = -errno; + nl_cb_put(cb); + return ret; + } + + ret = nl_recvmsgs(ctx->sock, cb); + nl_cb_put(cb); + if (ret < 0) + return ret; + + if (!ctx->event_received) + return -ENOMSG; + + igt_debug("Received error-notify event: node_id=%u error_id=%u value=%u\n", + ctx->event_node_id, ctx->event_error_id, ctx->event_error_value); + + return 0; +} diff --git a/lib/igt_drm_netlink.h b/lib/igt_drm_netlink.h index c44486ffa..b04221a23 100644 --- a/lib/igt_drm_netlink.h +++ b/lib/igt_drm_netlink.h @@ -24,6 +24,10 @@ struct app_context { uint32_t error_id; uint32_t error_value; uint32_t error_threshold; + uint32_t event_node_id; + uint32_t event_error_id; + uint32_t event_error_value; + bool event_received; int family_id; }; @@ -34,6 +38,8 @@ int init_nl_socket(struct app_context *ctx); int get_error_counter(struct app_context *ctx); int get_error_threshold(struct app_context *ctx); int set_error_threshold(struct app_context *ctx); +int subscribe_error_notify(struct app_context *ctx, const char *notify_group_name); +int wait_for_error_notify_event(struct app_context *ctx, int timeout_ms); #endif /* IGT_DRM_NETLINK_H */ -- 2.34.1