Whenever a correctable or an uncorrectable error happens an event is sent to the corresponding listeners of these groups. Signed-off-by: Aravind Iddamsetty <aravind.iddamsetty@xxxxxxxxx> --- drivers/gpu/drm/xe/xe_irq.c | 32 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_netlink.c | 2 ++ 2 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/xe/xe_irq.c b/drivers/gpu/drm/xe/xe_irq.c index 226be96e341a..1b415c8585a4 100644 --- a/drivers/gpu/drm/xe/xe_irq.c +++ b/drivers/gpu/drm/xe/xe_irq.c @@ -1073,6 +1073,37 @@ xe_gsc_hw_error_handler(struct xe_gt *gt, const enum hardware_error hw_err) xe_mmio_write32(gt, GSC_HEC_CORR_UNCORR_ERR_STATUS(base, hw_err).reg, err_status); } +static void generate_netlink_event(struct xe_gt *gt, const enum hardware_error hw_err) +{ + struct xe_device *xe = gt->xe; + struct sk_buff *msg; + void *hdr; + + if (!xe->xe_genl_family.module) + return; + + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); + if (!msg) { + drm_dbg_driver(&xe->drm, "couldn't allocate memory for error multicast event\n"); + return; + } + + hdr = genlmsg_put(msg, 0, 0, &xe->xe_genl_family, 0, DRM_CMD_ERROR_EVENT); + if (!hdr) { + drm_dbg_driver(&xe->drm, "mutlicast msg buffer is small\n"); + nlmsg_free(msg); + return; + } + + genlmsg_end(msg, hdr); + + genlmsg_multicast(&xe->xe_genl_family, msg, 0, + hw_err ? + DRM_GENL_MCAST_UNCORR_ERR + : DRM_GENL_MCAST_CORR_ERR, + GFP_ATOMIC); +} + static void xe_hw_error_source_handler(struct xe_gt *gt, const enum hardware_error hw_err) { @@ -1103,6 +1134,7 @@ xe_hw_error_source_handler(struct xe_gt *gt, const enum hardware_error hw_err) xe_mmio_write32(gt, DEV_ERR_STAT_REG(hw_err).reg, errsrc); + generate_netlink_event(gt, hw_err); out_unlock: spin_unlock_irqrestore(>_to_xe(gt)->irq.lock, flags); } diff --git a/drivers/gpu/drm/xe/xe_netlink.c b/drivers/gpu/drm/xe/xe_netlink.c index 2a6965f5cde9..0c1d51e1a9a5 100644 --- a/drivers/gpu/drm/xe/xe_netlink.c +++ b/drivers/gpu/drm/xe/xe_netlink.c @@ -490,6 +490,8 @@ static void xe_genl_family_init(struct xe_device *xe) xe->xe_genl_family.ops = xe_genl_ops; xe->xe_genl_family.n_ops = ARRAY_SIZE(xe_genl_ops); xe->xe_genl_family.maxattr = DRM_ATTR_MAX; + xe->xe_genl_family.mcgrps = drm_event_mcgrps; + xe->xe_genl_family.n_mcgrps = ARRAY_SIZE(drm_event_mcgrps); xe->xe_genl_family.module = THIS_MODULE; } -- 2.25.1