Skip to content

Commit 301e277

Browse files
committed
Merge tag 'drm-intel-gt-next-2024-12-18' of https://gitlab.freedesktop.org/drm/i915/kernel into drm-next
Driver Changes: - More accurate engine busyness metrics with GuC submission (Umesh) - Ensure partial BO segment offset never exceeds allowed max (Krzysztof) - Flush GuC CT receive tasklet during reset preparation (Zhanjun) - Code cleanups and refactoring (David, Lucas) - Debugging improvements (Jesus) - Selftest improvements (Sk) Signed-off-by: Dave Airlie <[email protected]> From: Joonas Lahtinen <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents bdecb30 + f373ebe commit 301e277

File tree

8 files changed

+79
-50
lines changed

8 files changed

+79
-50
lines changed

drivers/gpu/drm/i915/gt/intel_engine.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ execlists_active(const struct intel_engine_execlists *execlists)
126126
return active;
127127
}
128128

129-
struct i915_request *
130-
execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists);
131-
132129
static inline u32
133130
intel_read_status_page(const struct intel_engine_cs *engine, int reg)
134131
{

drivers/gpu/drm/i915/gt/intel_engine_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,11 @@ struct intel_engine_guc_stats {
343343
* @start_gt_clk: GT clock time of last idle to active transition.
344344
*/
345345
u64 start_gt_clk;
346+
347+
/**
348+
* @total: The last value of total returned
349+
*/
350+
u64 total;
346351
};
347352

348353
union intel_engine_tlb_inv_reg {

drivers/gpu/drm/i915/gt/intel_execlists_submission.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -405,15 +405,6 @@ __unwind_incomplete_requests(struct intel_engine_cs *engine)
405405
return active;
406406
}
407407

408-
struct i915_request *
409-
execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists)
410-
{
411-
struct intel_engine_cs *engine =
412-
container_of(execlists, typeof(*engine), execlists);
413-
414-
return __unwind_incomplete_requests(engine);
415-
}
416-
417408
static void
418409
execlists_context_status_change(struct i915_request *rq, unsigned long status)
419410
{

drivers/gpu/drm/i915/gt/selftest_rps.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,7 @@ static u64 measure_power(struct intel_rps *rps, int *freq)
11251125
static u64 measure_power_at(struct intel_rps *rps, int *freq)
11261126
{
11271127
*freq = rps_set_check(rps, *freq);
1128+
msleep(100);
11281129
return measure_power(rps, freq);
11291130
}
11301131

drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,21 @@ static void __get_engine_usage_record(struct intel_engine_cs *engine,
12431243
} while (++i < 6);
12441244
}
12451245

1246+
static void __set_engine_usage_record(struct intel_engine_cs *engine,
1247+
u32 last_in, u32 id, u32 total)
1248+
{
1249+
struct iosys_map rec_map = intel_guc_engine_usage_record_map(engine);
1250+
1251+
#define record_write(map_, field_, val_) \
1252+
iosys_map_wr_field(map_, 0, struct guc_engine_usage_record, field_, val_)
1253+
1254+
record_write(&rec_map, last_switch_in_stamp, last_in);
1255+
record_write(&rec_map, current_context_index, id);
1256+
record_write(&rec_map, total_runtime, total);
1257+
1258+
#undef record_write
1259+
}
1260+
12461261
static void guc_update_engine_gt_clks(struct intel_engine_cs *engine)
12471262
{
12481263
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)
13631378
total += intel_gt_clock_interval_to_ns(gt, clk);
13641379
}
13651380

1381+
if (total > stats->total)
1382+
stats->total = total;
1383+
13661384
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
13671385

1368-
return ns_to_ktime(total);
1386+
return ns_to_ktime(stats->total);
13691387
}
13701388

13711389
static void guc_enable_busyness_worker(struct intel_guc *guc)
@@ -1431,8 +1449,21 @@ static void __reset_guc_busyness_stats(struct intel_guc *guc)
14311449

14321450
guc_update_pm_timestamp(guc, &unused);
14331451
for_each_engine(engine, gt, id) {
1452+
struct intel_engine_guc_stats *stats = &engine->stats.guc;
1453+
14341454
guc_update_engine_gt_clks(engine);
1435-
engine->stats.guc.prev_total = 0;
1455+
1456+
/*
1457+
* If resetting a running context, accumulate the active
1458+
* time as well since there will be no context switch.
1459+
*/
1460+
if (stats->running) {
1461+
u64 clk = guc->timestamp.gt_stamp - stats->start_gt_clk;
1462+
1463+
stats->total_gt_clks += clk;
1464+
}
1465+
stats->prev_total = 0;
1466+
stats->running = 0;
14361467
}
14371468

14381469
spin_unlock_irqrestore(&guc->timestamp.lock, flags);
@@ -1543,13 +1574,19 @@ static void guc_timestamp_ping(struct work_struct *wrk)
15431574

15441575
static int guc_action_enable_usage_stats(struct intel_guc *guc)
15451576
{
1577+
struct intel_gt *gt = guc_to_gt(guc);
1578+
struct intel_engine_cs *engine;
1579+
enum intel_engine_id id;
15461580
u32 offset = intel_guc_engine_usage_offset(guc);
15471581
u32 action[] = {
15481582
INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF,
15491583
offset,
15501584
0,
15511585
};
15521586

1587+
for_each_engine(engine, gt, id)
1588+
__set_engine_usage_record(engine, 0, 0xffffffff, 0);
1589+
15531590
return intel_guc_send(guc, action, ARRAY_SIZE(action));
15541591
}
15551592

@@ -1688,6 +1725,10 @@ void intel_guc_submission_reset_prepare(struct intel_guc *guc)
16881725
spin_lock_irq(guc_to_gt(guc)->irq_lock);
16891726
spin_unlock_irq(guc_to_gt(guc)->irq_lock);
16901727

1728+
/* Flush tasklet */
1729+
tasklet_disable(&guc->ct.receive_tasklet);
1730+
tasklet_enable(&guc->ct.receive_tasklet);
1731+
16911732
guc_flush_submissions(guc);
16921733
guc_flush_destroyed_contexts(guc);
16931734
flush_work(&guc->ct.requests.worker);
@@ -2005,6 +2046,8 @@ void intel_guc_submission_cancel_requests(struct intel_guc *guc)
20052046

20062047
void intel_guc_submission_reset_finish(struct intel_guc *guc)
20072048
{
2049+
int outstanding;
2050+
20082051
/* Reset called during driver load or during wedge? */
20092052
if (unlikely(!guc_submission_initialized(guc) ||
20102053
!intel_guc_is_fw_running(guc) ||
@@ -2018,8 +2061,10 @@ void intel_guc_submission_reset_finish(struct intel_guc *guc)
20182061
* see in CI if this happens frequently / a precursor to taking down the
20192062
* machine.
20202063
*/
2021-
if (atomic_read(&guc->outstanding_submission_g2h))
2022-
guc_err(guc, "Unexpected outstanding GuC to Host in reset finish\n");
2064+
outstanding = atomic_read(&guc->outstanding_submission_g2h);
2065+
if (outstanding)
2066+
guc_err(guc, "Unexpected outstanding GuC to Host response(s) in reset finish: %d\n",
2067+
outstanding);
20232068
atomic_set(&guc->outstanding_submission_g2h, 0);
20242069

20252070
intel_guc_global_policies_update(guc);

drivers/gpu/drm/i915/i915_mm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ int remap_io_sg(struct vm_area_struct *vma,
143143
/* We rely on prevalidation of the io-mapping to skip track_pfn(). */
144144
GEM_BUG_ON((vma->vm_flags & EXPECTED_FLAGS) != EXPECTED_FLAGS);
145145

146-
while (offset >= sg_dma_len(r.sgt.sgp) >> PAGE_SHIFT) {
147-
offset -= sg_dma_len(r.sgt.sgp) >> PAGE_SHIFT;
146+
while (offset >= r.sgt.max >> PAGE_SHIFT) {
147+
offset -= r.sgt.max >> PAGE_SHIFT;
148148
r.sgt = __sgt_iter(__sg_next(r.sgt.sgp), use_dma(iobase));
149149
if (!r.sgt.sgp)
150150
return -EINVAL;

drivers/gpu/drm/i915/i915_pmu.c

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ void i915_pmu_gt_parked(struct intel_gt *gt)
302302
{
303303
struct i915_pmu *pmu = &gt->i915->pmu;
304304

305-
if (!pmu->base.event_init)
305+
if (!pmu->registered)
306306
return;
307307

308308
spin_lock_irq(&pmu->lock);
@@ -324,7 +324,7 @@ void i915_pmu_gt_unparked(struct intel_gt *gt)
324324
{
325325
struct i915_pmu *pmu = &gt->i915->pmu;
326326

327-
if (!pmu->base.event_init)
327+
if (!pmu->registered)
328328
return;
329329

330330
spin_lock_irq(&pmu->lock);
@@ -626,7 +626,7 @@ static int i915_pmu_event_init(struct perf_event *event)
626626
struct drm_i915_private *i915 = pmu_to_i915(pmu);
627627
int ret;
628628

629-
if (pmu->closed)
629+
if (!pmu->registered)
630630
return -ENODEV;
631631

632632
if (event->attr.type != event->pmu->type)
@@ -724,7 +724,7 @@ static void i915_pmu_event_read(struct perf_event *event)
724724
struct hw_perf_event *hwc = &event->hw;
725725
u64 prev, new;
726726

727-
if (pmu->closed) {
727+
if (!pmu->registered) {
728728
event->hw.state = PERF_HES_STOPPED;
729729
return;
730730
}
@@ -850,7 +850,7 @@ static void i915_pmu_event_start(struct perf_event *event, int flags)
850850
{
851851
struct i915_pmu *pmu = event_to_pmu(event);
852852

853-
if (pmu->closed)
853+
if (!pmu->registered)
854854
return;
855855

856856
i915_pmu_enable(event);
@@ -861,7 +861,7 @@ static void i915_pmu_event_stop(struct perf_event *event, int flags)
861861
{
862862
struct i915_pmu *pmu = event_to_pmu(event);
863863

864-
if (pmu->closed)
864+
if (!pmu->registered)
865865
goto out;
866866

867867
if (flags & PERF_EF_UPDATE)
@@ -877,7 +877,7 @@ static int i915_pmu_event_add(struct perf_event *event, int flags)
877877
{
878878
struct i915_pmu *pmu = event_to_pmu(event);
879879

880-
if (pmu->closed)
880+
if (!pmu->registered)
881881
return -ENODEV;
882882

883883
if (flags & PERF_EF_START)
@@ -1177,8 +1177,6 @@ static int i915_pmu_cpu_online(unsigned int cpu, struct hlist_node *node)
11771177
{
11781178
struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
11791179

1180-
GEM_BUG_ON(!pmu->base.event_init);
1181-
11821180
/* Select the first online CPU as a designated reader. */
11831181
if (cpumask_empty(&i915_pmu_cpumask))
11841182
cpumask_set_cpu(cpu, &i915_pmu_cpumask);
@@ -1191,13 +1189,11 @@ static int i915_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
11911189
struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node);
11921190
unsigned int target = i915_pmu_target_cpu;
11931191

1194-
GEM_BUG_ON(!pmu->base.event_init);
1195-
11961192
/*
11971193
* Unregistering an instance generates a CPU offline event which we must
11981194
* ignore to avoid incorrectly modifying the shared i915_pmu_cpumask.
11991195
*/
1200-
if (pmu->closed)
1196+
if (!pmu->registered)
12011197
return 0;
12021198

12031199
if (cpumask_test_and_clear_cpu(cpu, &i915_pmu_cpumask)) {
@@ -1218,7 +1214,7 @@ static int i915_pmu_cpu_offline(unsigned int cpu, struct hlist_node *node)
12181214
return 0;
12191215
}
12201216

1221-
static enum cpuhp_state cpuhp_slot = CPUHP_INVALID;
1217+
static enum cpuhp_state cpuhp_state = CPUHP_INVALID;
12221218

12231219
int i915_pmu_init(void)
12241220
{
@@ -1232,28 +1228,28 @@ int i915_pmu_init(void)
12321228
pr_notice("Failed to setup cpuhp state for i915 PMU! (%d)\n",
12331229
ret);
12341230
else
1235-
cpuhp_slot = ret;
1231+
cpuhp_state = ret;
12361232

12371233
return 0;
12381234
}
12391235

12401236
void i915_pmu_exit(void)
12411237
{
1242-
if (cpuhp_slot != CPUHP_INVALID)
1243-
cpuhp_remove_multi_state(cpuhp_slot);
1238+
if (cpuhp_state != CPUHP_INVALID)
1239+
cpuhp_remove_multi_state(cpuhp_state);
12441240
}
12451241

12461242
static int i915_pmu_register_cpuhp_state(struct i915_pmu *pmu)
12471243
{
1248-
if (cpuhp_slot == CPUHP_INVALID)
1244+
if (cpuhp_state == CPUHP_INVALID)
12491245
return -EINVAL;
12501246

1251-
return cpuhp_state_add_instance(cpuhp_slot, &pmu->cpuhp.node);
1247+
return cpuhp_state_add_instance(cpuhp_state, &pmu->cpuhp.node);
12521248
}
12531249

12541250
static void i915_pmu_unregister_cpuhp_state(struct i915_pmu *pmu)
12551251
{
1256-
cpuhp_state_remove_instance(cpuhp_slot, &pmu->cpuhp.node);
1252+
cpuhp_state_remove_instance(cpuhp_state, &pmu->cpuhp.node);
12571253
}
12581254

12591255
void i915_pmu_register(struct drm_i915_private *i915)
@@ -1265,7 +1261,6 @@ void i915_pmu_register(struct drm_i915_private *i915)
12651261
&i915_pmu_cpumask_attr_group,
12661262
NULL
12671263
};
1268-
12691264
int ret = -ENOMEM;
12701265

12711266
spin_lock_init(&pmu->lock);
@@ -1316,14 +1311,15 @@ void i915_pmu_register(struct drm_i915_private *i915)
13161311
if (ret)
13171312
goto err_unreg;
13181313

1314+
pmu->registered = true;
1315+
13191316
return;
13201317

13211318
err_unreg:
13221319
perf_pmu_unregister(&pmu->base);
13231320
err_groups:
13241321
kfree(pmu->base.attr_groups);
13251322
err_attr:
1326-
pmu->base.event_init = NULL;
13271323
free_event_attributes(pmu);
13281324
err_name:
13291325
if (IS_DGFX(i915))
@@ -1336,23 +1332,17 @@ void i915_pmu_unregister(struct drm_i915_private *i915)
13361332
{
13371333
struct i915_pmu *pmu = &i915->pmu;
13381334

1339-
if (!pmu->base.event_init)
1335+
if (!pmu->registered)
13401336
return;
13411337

1342-
/*
1343-
* "Disconnect" the PMU callbacks - since all are atomic synchronize_rcu
1344-
* ensures all currently executing ones will have exited before we
1345-
* proceed with unregistration.
1346-
*/
1347-
pmu->closed = true;
1348-
synchronize_rcu();
1338+
/* Disconnect the PMU callbacks */
1339+
pmu->registered = false;
13491340

13501341
hrtimer_cancel(&pmu->timer);
13511342

13521343
i915_pmu_unregister_cpuhp_state(pmu);
13531344

13541345
perf_pmu_unregister(&pmu->base);
1355-
pmu->base.event_init = NULL;
13561346
kfree(pmu->base.attr_groups);
13571347
if (IS_DGFX(i915))
13581348
kfree(pmu->name);

drivers/gpu/drm/i915/i915_pmu.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ struct i915_pmu {
6868
*/
6969
struct pmu base;
7070
/**
71-
* @closed: i915 is unregistering.
71+
* @registered: PMU is registered and not in the unregistering process.
7272
*/
73-
bool closed;
73+
bool registered;
7474
/**
7575
* @name: Name as registered with perf core.
7676
*/

0 commit comments

Comments
 (0)