[PATCH v2 3/8] lib/igt_drm_netlink: add get_error_threshold command support
Ravi Kishore Koppuravuri <[email protected]>
| Newsgroups | org.freedesktop.lists.igt-dev |
|---|---|
| Message-ID | <[email protected]> |
Add support for GET_ERROR_THRESHOLD to fetch the current value of error threshold Signed-off-by: Ravi Kishore Koppuravuri <[email protected]> --- v2:Added a check whether error_threshold updated by valid callback or not --- --- include/drm-uapi/drm_ras.h | 18 ++++++++++++ lib/igt_drm_netlink.c | 59 ++++++++++++++++++++++++++++++++++++-- lib/igt_drm_netlink.h | 2 ++ 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/include/drm-uapi/drm_ras.h b/include/drm-uapi/drm_ras.h index 218a3ee86..60611833b 100644 --- a/include/drm-uapi/drm_ras.h +++ b/include/drm-uapi/drm_ras.h @@ -33,18 +33,36 @@ enum { DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID, DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_NAME, DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_VALUE, + DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_THRESHOLD, __DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX, 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_GET_ERROR_THRESHOLD, + DRM_RAS_CMD_SET_ERROR_THRESHOLD, + DRM_RAS_CMD_ERROR_EVENT, __DRM_RAS_CMD_MAX, DRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1) }; +#define DRM_RAS_MCGRP_ERROR_NOTIFY "error-notify" + #endif /* _UAPI_LINUX_DRM_RAS_H */ diff --git a/lib/igt_drm_netlink.c b/lib/igt_drm_netlink.c index b72f2d5ca..c530076a6 100644 --- a/lib/igt_drm_netlink.c +++ b/lib/igt_drm_netlink.c @@ -43,6 +43,21 @@ static int ras_command_cb(struct nl_msg *msg, void *arg) ctx->error_value = nla_get_u32(attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_VALUE]); break; } + case DRM_RAS_CMD_GET_ERROR_THRESHOLD: { + struct nlattr *attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX + 1]; + + ret = genlmsg_parse(nlh, 0, attrs, + DRM_RAS_A_ERROR_COUNTER_ATTRS_MAX, NULL); + if (ret < 0) + return NL_SKIP; + + if (!attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_THRESHOLD]) + return NL_SKIP; + + ctx->error_threshold = + nla_get_u32(attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_THRESHOLD]); + break; + } default: return NL_SKIP; } @@ -162,6 +177,7 @@ static int send_command(struct app_context *ctx, uint8_t cmd) } switch (cmd) { + case DRM_RAS_CMD_GET_ERROR_THRESHOLD: case DRM_RAS_CMD_GET_ERROR_COUNTER: ctx->response_required = true; ret = nla_put_u32(msg, @@ -215,6 +231,7 @@ int init_app_context(struct app_context *ctx) ctx->reply_received = false; ctx->ack_received = false; ctx->response_required = false; + ctx->error_threshold = 0; ctx->family_id = -1; return 0; @@ -234,6 +251,7 @@ void cleanup_app_context(struct app_context *ctx) ctx->reply_received = false; ctx->ack_received = false; ctx->response_required = false; + ctx->error_threshold = 0; ctx->family_id = -1; } @@ -285,10 +303,8 @@ int init_nl_socket(struct app_context *ctx) return 0; } -int get_error_counter(struct app_context *ctx) +static int validate_inputs(struct app_context *ctx, uint8_t cmd) { - int ret; - if (!ctx || !ctx->sock || ctx->family_id < 0) return -EINVAL; @@ -301,6 +317,17 @@ int get_error_counter(struct app_context *ctx) return -EINVAL; } + return 0; +} + +int get_error_counter(struct app_context *ctx) +{ + int ret; + + ret = validate_inputs(ctx, DRM_RAS_CMD_GET_ERROR_COUNTER); + if (ret < 0) + return ret; + ctx->error_value = UINT32_MAX; ret = send_command(ctx, DRM_RAS_CMD_GET_ERROR_COUNTER); @@ -318,3 +345,29 @@ int get_error_counter(struct app_context *ctx) return 0; } + +int get_error_threshold(struct app_context *ctx) +{ + int ret; + + ret = validate_inputs(ctx, DRM_RAS_CMD_GET_ERROR_THRESHOLD); + if (ret < 0) + return ret; + + ctx->error_threshold = UINT32_MAX; + + ret = send_command(ctx, DRM_RAS_CMD_GET_ERROR_THRESHOLD); + if (ret < 0) + return ret; + + if (ctx->error_threshold == UINT32_MAX) { + igt_warn("No valid error threshold reply: node_id=%u error_id=%u kernel_error=%d\n", + ctx->node_id, ctx->error_id, ctx->last_nl_error); + return ctx->last_nl_error ? ctx->last_nl_error : -ENODATA; + } + + igt_debug("Retrieved error threshold: node_id=%u error_id=%u threshold=%u\n", + ctx->node_id, ctx->error_id, ctx->error_threshold); + + return 0; +} diff --git a/lib/igt_drm_netlink.h b/lib/igt_drm_netlink.h index f8b49aae8..08ef4eed0 100644 --- a/lib/igt_drm_netlink.h +++ b/lib/igt_drm_netlink.h @@ -28,6 +28,7 @@ struct app_context { bool reply_received; bool ack_received; bool response_required; + uint32_t error_threshold; int family_id; }; @@ -36,6 +37,7 @@ void cleanup_app_context(struct app_context *ctx); void cleanup_nl_socket(struct app_context *ctx); int init_nl_socket(struct app_context *ctx); int get_error_counter(struct app_context *ctx); +int get_error_threshold(struct app_context *ctx); #endif /* IGT_DRM_NETLINK_H */ -- 2.34.1