Merge tag 'drm-intel-fixes-2024-12-18' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-fixes

- Reset engine utilization buffer before registration (Umesh Nerlige Ramappa)
- Ensure busyness counter increases motonically (Umesh Nerlige Ramappa)
- Accumulate active runtime on gt reset (Umesh Nerlige Ramappa)

Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Tvrtko Ursulin <tursulin@igalia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Z2LppUZudGKXwWjW@linux
This commit is contained in:
Dave Airlie 2024-12-19 20:31:35 +10:00
commit e9088ac19e
2 changed files with 44 additions and 2 deletions

View File

@ -343,6 +343,11 @@ struct intel_engine_guc_stats {
* @start_gt_clk: GT clock time of last idle to active transition.
*/
u64 start_gt_clk;
/**
* @total: The last value of total returned
*/
u64 total;
};
union intel_engine_tlb_inv_reg {

View File

@ -1243,6 +1243,21 @@ static void __get_engine_usage_record(struct intel_engine_cs *engine,
} while (++i < 6);
}
static void __set_engine_usage_record(struct intel_engine_cs *engine,
u32 last_in, u32 id, u32 total)
{
struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine);
#define record_write(map_, field_, val_) \
iosys_map_wr_field(map_, 0, struct guc_engine_usage_record, field_, val_)
record_write(&rec_map, last_switch_in_stamp, last_in);
record_write(&rec_map, current_context_index, id);
record_write(&rec_map, total_runtime, total);
#undef record_write
}
static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
{
struct intel_engine_guc_stats *stats = &engine->stats.guc;
@ -1363,9 +1378,12 @@ static ktime_t guc_engine_busyness(struct intel_engine_cs *engine, ktime_t *now)
total += intel_gt_clock_interval_to_ns(gt, clk);
}
if (total > stats->total)
stats->total = total;
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
return ns_to_ktime(total);
return ns_to_ktime(stats->total);
}
static void guc_enable_busyness_worker(struct intel_guc *guc)
@ -1431,8 +1449,21 @@ static void __reset_guc_busyness_stats(struct intel_guc *guc)
guc_update_pm_timestamp(guc, &unused);
for_each_engine(engine, gt, id) {
struct intel_engine_guc_stats *stats = &engine->stats.guc;
guc_update_engine_gt_clks(engine);
engine->stats.guc.prev_total = 0;
/*
* If resetting a running context, accumulate the active
* time as well since there will be no context switch.
*/
if (stats->running) {
u64 clk = guc->timestamp.gt_stamp - stats->start_gt_clk;
stats->total_gt_clks += clk;
}
stats->prev_total = 0;
stats->running = 0;
}
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
@ -1543,6 +1574,9 @@ static void guc_timestamp_ping(struct work_struct *wrk)
static int guc_action_enable_usage_stats(struct intel_guc *guc)
{
struct intel_gt *gt = guc_to_gt(guc);
struct intel_engine_cs *engine;
enum intel_engine_id id;
u32 offset = intel_guc_engine_usage_offset(guc);
u32 action[] = {
INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF,
@ -1550,6 +1584,9 @@ static int guc_action_enable_usage_stats(struct intel_guc *guc)
0,
};
for_each_engine(engine, gt, id)
__set_engine_usage_record(engine, 0, 0xffffffff, 0);
return intel_guc_send(guc, action, ARRAY_SIZE(action));
}