From fe19328b900cc2c92054259e16d99023111c57f3 Mon Sep 17 00:00:00 2001 From: Lucas De Marchi Date: Fri, 26 May 2023 09:43:47 -0700 Subject: [PATCH] drm/xe/rtp: Add support for entries with no action Add a separate struct to hold entries in a table that has no action associated with each of them. The goal is that the caller in future can set a per-context callback, or just use the active entry marking feature. Reviewed-by: Matt Roper Link: https://lore.kernel.org/r/20230526164358.86393-11-lucas.demarchi@intel.com Signed-off-by: Lucas De Marchi Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/xe/xe_rtp.c | 65 +++++++++++++++++++++++++++---- drivers/gpu/drm/xe/xe_rtp.h | 3 ++ drivers/gpu/drm/xe/xe_rtp_types.h | 7 ++++ 3 files changed, 67 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/xe/xe_rtp.c b/drivers/gpu/drm/xe/xe_rtp.c index 70769852a93d..ebcfb04c391a 100644 --- a/drivers/gpu/drm/xe/xe_rtp.c +++ b/drivers/gpu/drm/xe/xe_rtp.c @@ -26,14 +26,14 @@ static bool rule_matches(const struct xe_device *xe, struct xe_gt *gt, struct xe_hw_engine *hwe, - const struct xe_rtp_entry_sr *entry) + const struct xe_rtp_rule *rules, + unsigned int n_rules) { const struct xe_rtp_rule *r; unsigned int i; bool match; - for (r = entry->rules, i = 0; i < entry->n_rules; - r = &entry->rules[++i]) { + for (r = rules, i = 0; i < n_rules; r = &rules[++i]) { switch (r->match_type) { case XE_RTP_MATCH_PLATFORM: match = xe->info.platform == r->platform; @@ -122,7 +122,7 @@ static bool rtp_process_one_sr(const struct xe_rtp_entry_sr *entry, u32 mmio_base; unsigned int i; - if (!rule_matches(xe, gt, hwe, entry)) + if (!rule_matches(xe, gt, hwe, entry->rules, entry->n_rules)) return false; for (action = &entry->actions[0]; i < entry->n_actions; action++, i++) { @@ -178,15 +178,18 @@ void xe_rtp_process_ctx_enable_active_tracking(struct xe_rtp_process_ctx *ctx, static void rtp_mark_active(struct xe_device *xe, struct xe_rtp_process_ctx *ctx, - unsigned int bit) + unsigned int first, unsigned int last) { if (!ctx->active_entries) return; - if (drm_WARN_ON(&xe->drm, bit > ctx->n_entries)) + if (drm_WARN_ON(&xe->drm, last > ctx->n_entries)) return; - bitmap_set(ctx->active_entries, bit, 1); + if (first == last) + bitmap_set(ctx->active_entries, first, 1); + else + bitmap_set(ctx->active_entries, first, last - first + 2); } /** @@ -228,11 +231,57 @@ void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx, } if (match) - rtp_mark_active(xe, ctx, entry - entries); + rtp_mark_active(xe, ctx, entry - entries, + entry - entries); } } EXPORT_SYMBOL_IF_KUNIT(xe_rtp_process_to_sr); +/** + * xe_rtp_process - Process all rtp @entries, without running any action + * @ctx: The context for processing the table, with one of device, gt or hwe + * @entries: Table with RTP definitions + * + * Walk the table pointed by @entries (with an empty sentinel), executing the + * rules. A few differences from xe_rtp_process_to_sr(): + * + * 1. There is no action associated with each entry since this uses + * struct xe_rtp_entry. Its main use is for marking active workarounds via + * xe_rtp_process_ctx_enable_active_tracking(). + * 2. There is support for OR operations by having entries with no name. + */ +void xe_rtp_process(struct xe_rtp_process_ctx *ctx, + const struct xe_rtp_entry *entries) +{ + const struct xe_rtp_entry *entry, *first_entry; + struct xe_hw_engine *hwe; + struct xe_gt *gt; + struct xe_device *xe; + + rtp_get_context(ctx, &hwe, >, &xe); + + first_entry = entries; + if (drm_WARN_ON(&xe->drm, !first_entry->name)) + return; + + for (entry = entries; entry && entry->rules; entry++) { + if (entry->name) + first_entry = entry; + + if (!rule_matches(xe, gt, hwe, entry->rules, entry->n_rules)) + continue; + + /* Fast-forward entry, eliminating the OR'ed entries */ + for (entry++; entry && entry->rules; entry++) + if (entry->name) + break; + entry--; + + rtp_mark_active(xe, ctx, first_entry - entries, + entry - entries); + } +} + bool xe_rtp_match_even_instance(const struct xe_gt *gt, const struct xe_hw_engine *hwe) { diff --git a/drivers/gpu/drm/xe/xe_rtp.h b/drivers/gpu/drm/xe/xe_rtp.h index d55701d2f39b..8581bd9b1426 100644 --- a/drivers/gpu/drm/xe/xe_rtp.h +++ b/drivers/gpu/drm/xe/xe_rtp.h @@ -384,6 +384,9 @@ void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx, const struct xe_rtp_entry_sr *entries, struct xe_reg_sr *sr); +void xe_rtp_process(struct xe_rtp_process_ctx *ctx, + const struct xe_rtp_entry *entries); + /* Match functions to be used with XE_RTP_MATCH_FUNC */ /** diff --git a/drivers/gpu/drm/xe/xe_rtp_types.h b/drivers/gpu/drm/xe/xe_rtp_types.h index af49cbf98407..d170532a98a5 100644 --- a/drivers/gpu/drm/xe/xe_rtp_types.h +++ b/drivers/gpu/drm/xe/xe_rtp_types.h @@ -96,6 +96,13 @@ struct xe_rtp_entry_sr { u8 flags; }; +/** struct xe_rtp_entry - Entry in an rtp table, with no action associated */ +struct xe_rtp_entry { + const char *name; + const struct xe_rtp_rule *rules; + u8 n_rules; +}; + enum xe_rtp_process_type { XE_RTP_PROCESS_TYPE_GT, XE_RTP_PROCESS_TYPE_ENGINE,