Igt-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Koppuravuri, Ravi Kishore" <ravi.kishore.koppuravuri@intel.com>
To: "Purkait, Soham" <soham.purkait@intel.com>,
	<igt-dev@lists.freedesktop.org>
Cc: Riana Tauro <riana.tauro@intel.com>,
	Anshuman Gupta <anshuman.gupta@intel.com>,
	Raag Jadav <raag.jadav@intel.com>,
	Badal Nilawar <badal.nilawar@intel.com>,
	Mallesh Koujalagi <mallesh.koujalagi@intel.com>,
	Harish Chegondi <harish.chegondi@intel.com>
Subject: Re: [PATCH v5 08/10] lib/igt_drm_netlink: add event notify subscription and event wait support
Date: Fri, 23 Oct 2026 12:56:50 +0530	[thread overview]
Message-ID: <0e9ce92e-2519-40e8-968b-ec45d7444732@intel.com> (raw)
In-Reply-To: <5bd1bcf1-31a9-4dd0-bb32-5f6cf18e5f5b@intel.com>

Hi Soham,

On 23-10-2026 01:01, Purkait, Soham wrote:
> Hi Ravi,
>
> On 14-10-2026 00:36, Ravi Kishore Koppuravuri wrote:
>> Added event notification support with subscribe for an error-notify 
>> event
>> and wait for the event notification functionalities.
>>
>> Cc: Soham Purkait <soham.purkait@intel.com>
>> Cc: Riana Tauro <riana.tauro@intel.com>
>> Cc: Anshuman Gupta <anshuman.gupta@intel.com>
>> Cc: Raag Jadav <raag.jadav@intel.com>
>> Cc: Badal Nilawar <badal.nilawar@intel.com>
>> Cc: Mallesh Koujalagi <mallesh.koujalagi@intel.com>
>> Cc: Harish Chegondi <harish.chegondi@intel.com>
>> Signed-off-by: Ravi Kishore Koppuravuri 
>> <ravi.kishore.koppuravuri@intel.com>
>> ---
>> v5:Added a guard to prevent duplicate multicast group subscriptions 
>> (Soham)
>> v4:Renamed the library functions with prefix "igt_drm_netlink_*" (Nikula
>>     Jani & Kamil)
>>     updated error event name from error-notify to error-report to align
>>     with the latest changes in drm-uapi/drm_ras.h
>> v2:Handled SEQ_CHECK nl response using separate callback
>>     Added monotonic-clock deadline to wait for messages without 
>> exceeding the
>>     caller’s total timeout.
>>     Added support to receive events until it sees an event whose node 
>> ID and
>>     error ID match the requested values.
>> ---
>>   lib/igt_drm_ras_nl.c | 182 +++++++++++++++++++++++++++++++++++++++++--
>>   lib/igt_drm_ras_nl.h |  18 +++++
>>   2 files changed, 193 insertions(+), 7 deletions(-)
>>
>> diff --git a/lib/igt_drm_ras_nl.c b/lib/igt_drm_ras_nl.c
>> index 94fcc40ac..c5f1a1a3f 100644
>> --- a/lib/igt_drm_ras_nl.c
>> +++ b/lib/igt_drm_ras_nl.c
>> @@ -6,6 +6,7 @@
>>   #include <errno.h>
>>   #include <poll.h>
>>   #include <stdint.h>
>> +#include <time.h>
>>     #include <netlink/errno.h>
>>   #include <netlink/genl/ctrl.h>
>> @@ -62,10 +63,12 @@ static int ras_command_cb(struct nl_msg *msg, 
>> void *arg)
>>       nlh = nlmsg_hdr(msg);
>>       gnlh = nlmsg_data(nlh);
>>   -    ret = genlmsg_parse(nlh, 0, attrs,
>> -                DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX, NULL);
>> -    if (ret < 0)
>> -        return NL_SKIP;
>> +    if (gnlh->cmd != DRM_RAS_CMD_ERROR_EVENT) {
>> +        ret = genlmsg_parse(nlh, 0, attrs,
>> +                    DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX, NULL);
>> +        if (ret < 0)
>> +            return NL_SKIP;
>> +    }
>>         switch (gnlh->cmd) {
>>       case DRM_RAS_CMD_SET_ERROR_THRESHOLD:
>> @@ -85,17 +88,47 @@ static int ras_command_cb(struct nl_msg *msg, 
>> void *arg)
>> nla_get_u32(attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_THRESHOLD]);
>>           break;
>>       }
>> +    case DRM_RAS_CMD_ERROR_EVENT: {
>> +        struct nlattr *event_attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_MAX + 
>> 1];
> Please declare event_attrs with the other local variables at the start 
> of ras_command_cb(). Could the existing attrs array be reused ? 
> Although in that case, the shared array would need to accommodate the 
> larger of the two *_ATTRS_MAX values.
>
> Regards,
> Soham

I have separated the struct nlattr * for DRM_RAS_A_ERROR_EVENT_ATTRS_MAX 
and DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX to avoid the confusion to readers. 
And event_attrs pointer is made local to the ERROR_EVENT switch case to 
avoid pointer definition for all other commands. So, the current 
approach also looks good to me.

Thanks,

Ravi Kishore K.

>> +
>> +        ret = genlmsg_parse(nlh, 0, event_attrs,
>> +                    DRM_RAS_A_ERROR_EVENT_ATTRS_MAX, NULL);
>> +        if (ret < 0)
>> +            return NL_SKIP;
>> +
>> +        if (!event_attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID] ||
>> +            !event_attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID] ||
>> + !event_attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE])
>> +            return NL_SKIP;
>> +
>> +        ctx->event_node_id =
>> + nla_get_u32(event_attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_NODE_ID]);
>> +        ctx->event_error_id =
>> + nla_get_u32(event_attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_ID]);
>> +        ctx->event_error_value =
>> + nla_get_u32(event_attrs[DRM_RAS_A_ERROR_EVENT_ATTRS_ERROR_VALUE]);
>> +        ctx->event_received = ctx->event_node_id == ctx->node_id &&
>> +                      ctx->event_error_id == ctx->error_id;
>> +        break;
>> +    }
>>       default:
>>           return NL_SKIP;
>>       }
>>   -    ctx->reply_received = true;
>> -    if (ctx->ack_received)
>> -        ctx->cmd_done = true;
>> +    if (gnlh->cmd != DRM_RAS_CMD_ERROR_EVENT) {
>> +        ctx->reply_received = true;
>> +        if (ctx->ack_received)
>> +            ctx->cmd_done = true;
>> +    }
>>         return NL_OK;
>>   }
>>   +static int ras_multicast_seq_check_cb(struct nl_msg *msg, void *arg)
>> +{
>> +    return NL_OK;
>> +}
>> +
>>   static int ras_error_cb(struct sockaddr_nl *nla, struct nlmsgerr 
>> *err, void *arg)
>>   {
>>       struct igt_drm_ras_nl_context *ctx = arg;
>> @@ -157,6 +190,27 @@ static int register_callbacks(struct nl_cb *cb, 
>> struct igt_drm_ras_nl_context *c
>>       return 0;
>>   }
>>   +static int register_multicast_callbacks(struct nl_cb *cb,
>> +                    struct igt_drm_ras_nl_context *ctx)
>> +{
>> +    int ret;
>> +
>> +    ret = nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, ras_command_cb, 
>> ctx);
>> +    if (ret < 0) {
>> +        igt_warn("Failed to set NL_CB_VALID callback (ret=%d)\n", ret);
>> +        return ret;
>> +    }
>> +
>> +    ret = nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
>> +            ras_multicast_seq_check_cb, ctx);
>> +    if (ret < 0) {
>> +        igt_warn("Failed to set NL_CB_SEQ_CHECK callback 
>> (ret=%d)\n", ret);
>> +        return ret;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   static int send_and_recv_nl_msg(struct igt_drm_ras_nl_context *ctx,
>>                   struct nl_cb *cb,
>>                   struct nl_msg *msg)
>> @@ -299,7 +353,12 @@ static void reset_drm_ras_nl_context(struct 
>> igt_drm_ras_nl_context *ctx)
>>       ctx->ack_received = false;
>>       ctx->response_required = false;
>>       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;
>> +    ctx->subscribed_grp_id = -1;
>>   }
>>     void igt_drm_ras_nl_cleanup(struct igt_drm_ras_nl_context *ctx)
>> @@ -440,3 +499,112 @@ int igt_drm_ras_nl_set_error_threshold(struct 
>> igt_drm_ras_nl_context *ctx)
>>         return 0;
>>   }
>> +
>> +int igt_drm_ras_nl_subscribe_error_report(struct 
>> igt_drm_ras_nl_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;
>> +
>> +    /* Check if already subscribed to the requested multicast group */
>> +    if (ctx->subscribed_grp_id == grp_id) {
>> +        igt_debug("Already subscribed to DRM RAS multicast group 
>> '%s' (id=%d).\n",
>> +              notify_group_name, grp_id);
>> +        return 0;
>> +    }
>> +
>> +    ret = nl_socket_add_membership(ctx->sock, grp_id);
>> +    if (ret < 0)
>> +        return ret;
>> +
>> +    ctx->subscribed_grp_id = grp_id;
>> +
>> +    igt_debug("Subscribed to DRM RAS multicast group '%s' (id=%d).\n",
>> +          notify_group_name, grp_id);
>> +
>> +    return 0;
>> +}
>> +
>> +int igt_drm_ras_nl_wait_for_error_report_event(struct 
>> igt_drm_ras_nl_context *ctx,
>> +                           int timeout_ms)
>> +{
>> +    struct nl_cb *cb;
>> +    struct pollfd pfd;
>> +    struct timespec start, now;
>> +    int remaining_ms;
>> +    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 = register_multicast_callbacks(cb, ctx);
>> +    if (ret < 0) {
>> +        nl_cb_put(cb);
>> +        return ret;
>> +    }
>> +
>> +    ctx->event_received = false;
>> +    clock_gettime(CLOCK_MONOTONIC, &start);
>> +
>> +    pfd.fd = nl_socket_get_fd(ctx->sock);
>> +    pfd.events = POLLIN;
>> +    pfd.revents = 0;
>> +
>> +    while (!ctx->event_received) {
>> +        if (timeout_ms == -1) {
>> +            remaining_ms = -1;
>> +        } else {
>> +            clock_gettime(CLOCK_MONOTONIC, &now);
>> +            remaining_ms = timeout_ms -
>> +                       (int)((now.tv_sec - start.tv_sec) * 1000 +
>> +                       (now.tv_nsec - start.tv_nsec) / 1000000);
>> +            if (remaining_ms <= 0) {
>> +                ret = -ETIMEDOUT;
>> +                break;
>> +            }
>> +        }
>> +
>> +        ret = poll(&pfd, 1, remaining_ms);
>> +        if (ret == 0) {
>> +            ret = -ETIMEDOUT;
>> +            break;
>> +        }
>> +
>> +        if (ret < 0) {
>> +            ret = -errno;
>> +            break;
>> +        }
>> +
>> +        ret = nl_recvmsgs(ctx->sock, cb);
>> +        if (ret < 0)
>> +            break;
>> +    }
>> +    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_ras_nl.h b/lib/igt_drm_ras_nl.h
>> index 5c9be5b17..057c6026f 100644
>> --- a/lib/igt_drm_ras_nl.h
>> +++ b/lib/igt_drm_ras_nl.h
>> @@ -47,6 +47,21 @@ struct igt_drm_ras_nl_context {
>>         /** @error_threshold: Error threshold value to query/set */
>>       uint32_t error_threshold;
>> +
>> +    /** @event_node_id: RAS node ID reported by an error-report 
>> event */
>> +    uint32_t event_node_id;
>> +
>> +    /** @event_error_id: RAS error ID reported by an error-report 
>> event */
>> +    uint32_t event_error_id;
>> +
>> +    /** @event_error_value: Error counter value reported by an 
>> error-report event */
>> +    uint32_t event_error_value;
>> +
>> +    /** @event_received: Set when a matching error-report event has 
>> been received */
>> +    bool event_received;
>> +
>> +    /** @subscribed_grp_id: Multicast group ID currently subscribed 
>> to, or -1 if none */
>> +    int subscribed_grp_id;
>>   };
>>     void igt_drm_ras_nl_cleanup(struct igt_drm_ras_nl_context *ctx);
>> @@ -54,6 +69,9 @@ int igt_drm_ras_nl_init(struct 
>> igt_drm_ras_nl_context *ctx);
>>   int igt_drm_ras_nl_get_error_counter(struct igt_drm_ras_nl_context 
>> *ctx);
>>   int igt_drm_ras_nl_get_error_threshold(struct 
>> igt_drm_ras_nl_context *ctx);
>>   int igt_drm_ras_nl_set_error_threshold(struct 
>> igt_drm_ras_nl_context *ctx);
>> +int igt_drm_ras_nl_subscribe_error_report(struct 
>> igt_drm_ras_nl_context *ctx,
>> +                      const char *notify_group_name);
>> +int igt_drm_ras_nl_wait_for_error_report_event(struct 
>> igt_drm_ras_nl_context *ctx, int timeout_ms);
>>     #endif /* IGT_DRM_RAS_NL_H */

  reply	other threads:[~2026-10-23  7:28 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13 19:06 [PATCH v5 00/10] Xe3P GPU Error Injection Test Suite with DRM RAS Netlink Support Ravi Kishore Koppuravuri
2026-10-13 19:06 ` [PATCH v5 01/10] drm-uapi/drm_ras: Sync with kernel b2207d4c4e84 Ravi Kishore Koppuravuri
2026-10-22 11:56   ` Purkait, Soham
2026-10-13 19:06 ` [PATCH v5 02/10] lib/meson: Add libnl dependencies for DRM RAS support Ravi Kishore Koppuravuri
2026-10-22 11:56   ` Purkait, Soham
2026-10-13 19:06 ` [PATCH v5 03/10] lib/igt_drm_netlink: Introduce DRM RAS Netlink interface library Ravi Kishore Koppuravuri
2026-10-22 12:04   ` Purkait, Soham
2026-10-13 19:06 ` [PATCH v5 04/10] lib/igt_drm_netlink: add get_error_counter support Ravi Kishore Koppuravuri
2026-10-22 12:40   ` Purkait, Soham
2026-10-13 19:06 ` [PATCH v5 05/10] lib/igt_drm_netlink: add get_error_threshold command support Ravi Kishore Koppuravuri
2026-10-13 19:06 ` [PATCH v5 06/10] lib/igt_drm_netlink: add set_error_threshold " Ravi Kishore Koppuravuri
2026-10-22 16:55   ` Purkait, Soham
2026-10-13 19:06 ` [PATCH v5 07/10] tests/intel/xe_err_injection: Add GT UC Unicast GAM Walker Command Parity Error Injection Ravi Kishore Koppuravuri
2026-10-22 17:41   ` Purkait, Soham
2026-10-23 14:42   ` Tauro, Riana
2026-10-13 19:06 ` [PATCH v5 08/10] lib/igt_drm_netlink: add event notify subscription and event wait support Ravi Kishore Koppuravuri
2026-10-22 19:31   ` Purkait, Soham
2026-10-23  7:26     ` Koppuravuri, Ravi Kishore [this message]
2026-10-13 19:06 ` [PATCH v5 09/10] tests/intel/xe_err_injection: Add tests for L2 bank Corr err threshold scenarios Ravi Kishore Koppuravuri
2026-10-13 19:06 ` [PATCH v5 10/10] tests/intel/xe_err_injection: add CRI GPU requirement check Ravi Kishore Koppuravuri
2026-10-23  9:14   ` Purkait, Soham
2026-10-14  1:28 ` ✓ i915.CI.BAT: success for Xe3P GPU Error Injection Test Suite with DRM RAS Netlink Support (rev8) Patchwork
2026-10-14  5:35 ` ✓ Xe.CI.BAT: " Patchwork
2026-10-14 10:25 ` ✗ i915.CI.Full: failure " Patchwork
2026-10-14 20:18 ` ✗ Xe.CI.FULL: " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0e9ce92e-2519-40e8-968b-ec45d7444732@intel.com \
    --to=ravi.kishore.koppuravuri@intel.com \
    --cc=anshuman.gupta@intel.com \
    --cc=badal.nilawar@intel.com \
    --cc=harish.chegondi@intel.com \
    --cc=igt-dev@lists.freedesktop.org \
    --cc=mallesh.koujalagi@intel.com \
    --cc=raag.jadav@intel.com \
    --cc=riana.tauro@intel.com \
    --cc=soham.purkait@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox