Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Z2KadNXgumx1aQMP@jlahtine-mobl.ger.corp.intel.com

+79 -50
-3
drivers/gpu/drm/i915/gt/intel_engine.h
··· 126 126 return active; 127 127 } 128 128 129 - struct i915_request * 130 - execlists_unwind_incomplete_requests(struct intel_engine_execlists *execlists); 131 - 132 129 static inline u32 133 130 intel_read_status_page(const struct intel_engine_cs *engine, int reg) 134 131 {
+5
drivers/gpu/drm/i915/gt/intel_engine_types.h
··· 343 343 * @start_gt_clk: GT clock time of last idle to active transition. 344 344 */ 345 345 u64 start_gt_clk; 346 + 347 + /** 348 + * @total: The last value of total returned 349 + */ 350 + u64 total; 346 351 }; 347 352 348 353 union intel_engine_tlb_inv_reg {
-9
drivers/gpu/drm/i915/gt/intel_execlists_submission.c
··· 405 405 return active; 406 406 } 407 407 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 - 417 408 static void 418 409 execlists_context_status_change(struct i915_request *rq, unsigned long status) 419 410 {
+1
drivers/gpu/drm/i915/gt/selftest_rps.c
··· 1125 1125 static u64 measure_power_at(struct intel_rps *rps, int *freq) 1126 1126 { 1127 1127 *freq = rps_set_check(rps, *freq); 1128 + msleep(100); 1128 1129 return measure_power(rps, freq); 1129 1130 } 1130 1131
+49 -4
drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
··· 1243 1243 } while (++i < 6); 1244 1244 } 1245 1245 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 + 1246 1261 static void guc_update_engine_gt_clks(struct intel_engine_cs *engine) 1247 1262 { 1248 1263 struct intel_engine_guc_stats *stats = &engine->stats.guc; ··· 1378 1363 total += intel_gt_clock_interval_to_ns(gt, clk); 1379 1364 } 1380 1365 1366 + if (total > stats->total) 1367 + stats->total = total; 1368 + 1381 1369 spin_unlock_irqrestore(&guc->timestamp.lock, flags); 1382 1370 1383 - return ns_to_ktime(total); 1371 + return ns_to_ktime(stats->total); 1384 1372 } 1385 1373 1386 1374 static void guc_enable_busyness_worker(struct intel_guc *guc) ··· 1449 1431 1450 1432 guc_update_pm_timestamp(guc, &unused); 1451 1433 for_each_engine(engine, gt, id) { 1434 + struct intel_engine_guc_stats *stats = &engine->stats.guc; 1435 + 1452 1436 guc_update_engine_gt_clks(engine); 1453 - engine->stats.guc.prev_total = 0; 1437 + 1438 + /* 1439 + * If resetting a running context, accumulate the active 1440 + * time as well since there will be no context switch. 1441 + */ 1442 + if (stats->running) { 1443 + u64 clk = guc->timestamp.gt_stamp - stats->start_gt_clk; 1444 + 1445 + stats->total_gt_clks += clk; 1446 + } 1447 + stats->prev_total = 0; 1448 + stats->running = 0; 1454 1449 } 1455 1450 1456 1451 spin_unlock_irqrestore(&guc->timestamp.lock, flags); ··· 1574 1543 1575 1544 static int guc_action_enable_usage_stats(struct intel_guc *guc) 1576 1545 { 1546 + struct intel_gt *gt = guc_to_gt(guc); 1547 + struct intel_engine_cs *engine; 1548 + enum intel_engine_id id; 1577 1549 u32 offset = intel_guc_engine_usage_offset(guc); 1578 1550 u32 action[] = { 1579 1551 INTEL_GUC_ACTION_SET_ENG_UTIL_BUFF, 1580 1552 offset, 1581 1553 0, 1582 1554 }; 1555 + 1556 + for_each_engine(engine, gt, id) 1557 + __set_engine_usage_record(engine, 0, 0xffffffff, 0); 1583 1558 1584 1559 return intel_guc_send(guc, action, ARRAY_SIZE(action)); 1585 1560 } ··· 1724 1687 /* Flush IRQ handler */ 1725 1688 spin_lock_irq(guc_to_gt(guc)->irq_lock); 1726 1689 spin_unlock_irq(guc_to_gt(guc)->irq_lock); 1690 + 1691 + /* Flush tasklet */ 1692 + tasklet_disable(&guc->ct.receive_tasklet); 1693 + tasklet_enable(&guc->ct.receive_tasklet); 1727 1694 1728 1695 guc_flush_submissions(guc); 1729 1696 guc_flush_destroyed_contexts(guc); ··· 2046 2005 2047 2006 void intel_guc_submission_reset_finish(struct intel_guc *guc) 2048 2007 { 2008 + int outstanding; 2009 + 2049 2010 /* Reset called during driver load or during wedge? */ 2050 2011 if (unlikely(!guc_submission_initialized(guc) || 2051 2012 !intel_guc_is_fw_running(guc) || ··· 2061 2018 * see in CI if this happens frequently / a precursor to taking down the 2062 2019 * machine. 2063 2020 */ 2064 - if (atomic_read(&guc->outstanding_submission_g2h)) 2065 - guc_err(guc, "Unexpected outstanding GuC to Host in reset finish\n"); 2021 + outstanding = atomic_read(&guc->outstanding_submission_g2h); 2022 + if (outstanding) 2023 + guc_err(guc, "Unexpected outstanding GuC to Host response(s) in reset finish: %d\n", 2024 + outstanding); 2066 2025 atomic_set(&guc->outstanding_submission_g2h, 0); 2067 2026 2068 2027 intel_guc_global_policies_update(guc);
+2 -2
drivers/gpu/drm/i915/i915_mm.c
··· 143 143 /* We rely on prevalidation of the io-mapping to skip track_pfn(). */ 144 144 GEM_BUG_ON((vma->vm_flags & EXPECTED_FLAGS) != EXPECTED_FLAGS); 145 145 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; 148 148 r.sgt = __sgt_iter(__sg_next(r.sgt.sgp), use_dma(iobase)); 149 149 if (!r.sgt.sgp) 150 150 return -EINVAL;
+20 -30
drivers/gpu/drm/i915/i915_pmu.c
··· 302 302 { 303 303 struct i915_pmu *pmu = &gt->i915->pmu; 304 304 305 - if (!pmu->base.event_init) 305 + if (!pmu->registered) 306 306 return; 307 307 308 308 spin_lock_irq(&pmu->lock); ··· 324 324 { 325 325 struct i915_pmu *pmu = &gt->i915->pmu; 326 326 327 - if (!pmu->base.event_init) 327 + if (!pmu->registered) 328 328 return; 329 329 330 330 spin_lock_irq(&pmu->lock); ··· 626 626 struct drm_i915_private *i915 = pmu_to_i915(pmu); 627 627 int ret; 628 628 629 - if (pmu->closed) 629 + if (!pmu->registered) 630 630 return -ENODEV; 631 631 632 632 if (event->attr.type != event->pmu->type) ··· 724 724 struct hw_perf_event *hwc = &event->hw; 725 725 u64 prev, new; 726 726 727 - if (pmu->closed) { 727 + if (!pmu->registered) { 728 728 event->hw.state = PERF_HES_STOPPED; 729 729 return; 730 730 } ··· 850 850 { 851 851 struct i915_pmu *pmu = event_to_pmu(event); 852 852 853 - if (pmu->closed) 853 + if (!pmu->registered) 854 854 return; 855 855 856 856 i915_pmu_enable(event); ··· 861 861 { 862 862 struct i915_pmu *pmu = event_to_pmu(event); 863 863 864 - if (pmu->closed) 864 + if (!pmu->registered) 865 865 goto out; 866 866 867 867 if (flags & PERF_EF_UPDATE) ··· 877 877 { 878 878 struct i915_pmu *pmu = event_to_pmu(event); 879 879 880 - if (pmu->closed) 880 + if (!pmu->registered) 881 881 return -ENODEV; 882 882 883 883 if (flags & PERF_EF_START) ··· 1177 1177 { 1178 1178 struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node); 1179 1179 1180 - GEM_BUG_ON(!pmu->base.event_init); 1181 - 1182 1180 /* Select the first online CPU as a designated reader. */ 1183 1181 if (cpumask_empty(&i915_pmu_cpumask)) 1184 1182 cpumask_set_cpu(cpu, &i915_pmu_cpumask); ··· 1189 1191 struct i915_pmu *pmu = hlist_entry_safe(node, typeof(*pmu), cpuhp.node); 1190 1192 unsigned int target = i915_pmu_target_cpu; 1191 1193 1192 - GEM_BUG_ON(!pmu->base.event_init); 1193 - 1194 1194 /* 1195 1195 * Unregistering an instance generates a CPU offline event which we must 1196 1196 * ignore to avoid incorrectly modifying the shared i915_pmu_cpumask. 1197 1197 */ 1198 - if (pmu->closed) 1198 + if (!pmu->registered) 1199 1199 return 0; 1200 1200 1201 1201 if (cpumask_test_and_clear_cpu(cpu, &i915_pmu_cpumask)) { ··· 1214 1218 return 0; 1215 1219 } 1216 1220 1217 - static enum cpuhp_state cpuhp_slot = CPUHP_INVALID; 1221 + static enum cpuhp_state cpuhp_state = CPUHP_INVALID; 1218 1222 1219 1223 int i915_pmu_init(void) 1220 1224 { ··· 1228 1232 pr_notice("Failed to setup cpuhp state for i915 PMU! (%d)\n", 1229 1233 ret); 1230 1234 else 1231 - cpuhp_slot = ret; 1235 + cpuhp_state = ret; 1232 1236 1233 1237 return 0; 1234 1238 } 1235 1239 1236 1240 void i915_pmu_exit(void) 1237 1241 { 1238 - if (cpuhp_slot != CPUHP_INVALID) 1239 - cpuhp_remove_multi_state(cpuhp_slot); 1242 + if (cpuhp_state != CPUHP_INVALID) 1243 + cpuhp_remove_multi_state(cpuhp_state); 1240 1244 } 1241 1245 1242 1246 static int i915_pmu_register_cpuhp_state(struct i915_pmu *pmu) 1243 1247 { 1244 - if (cpuhp_slot == CPUHP_INVALID) 1248 + if (cpuhp_state == CPUHP_INVALID) 1245 1249 return -EINVAL; 1246 1250 1247 - return cpuhp_state_add_instance(cpuhp_slot, &pmu->cpuhp.node); 1251 + return cpuhp_state_add_instance(cpuhp_state, &pmu->cpuhp.node); 1248 1252 } 1249 1253 1250 1254 static void i915_pmu_unregister_cpuhp_state(struct i915_pmu *pmu) 1251 1255 { 1252 - cpuhp_state_remove_instance(cpuhp_slot, &pmu->cpuhp.node); 1256 + cpuhp_state_remove_instance(cpuhp_state, &pmu->cpuhp.node); 1253 1257 } 1254 1258 1255 1259 void i915_pmu_register(struct drm_i915_private *i915) ··· 1261 1265 &i915_pmu_cpumask_attr_group, 1262 1266 NULL 1263 1267 }; 1264 - 1265 1268 int ret = -ENOMEM; 1266 1269 1267 1270 spin_lock_init(&pmu->lock); ··· 1311 1316 if (ret) 1312 1317 goto err_unreg; 1313 1318 1319 + pmu->registered = true; 1320 + 1314 1321 return; 1315 1322 1316 1323 err_unreg: ··· 1320 1323 err_groups: 1321 1324 kfree(pmu->base.attr_groups); 1322 1325 err_attr: 1323 - pmu->base.event_init = NULL; 1324 1326 free_event_attributes(pmu); 1325 1327 err_name: 1326 1328 if (IS_DGFX(i915)) ··· 1332 1336 { 1333 1337 struct i915_pmu *pmu = &i915->pmu; 1334 1338 1335 - if (!pmu->base.event_init) 1339 + if (!pmu->registered) 1336 1340 return; 1337 1341 1338 - /* 1339 - * "Disconnect" the PMU callbacks - since all are atomic synchronize_rcu 1340 - * ensures all currently executing ones will have exited before we 1341 - * proceed with unregistration. 1342 - */ 1343 - pmu->closed = true; 1344 - synchronize_rcu(); 1342 + /* Disconnect the PMU callbacks */ 1343 + pmu->registered = false; 1345 1344 1346 1345 hrtimer_cancel(&pmu->timer); 1347 1346 1348 1347 i915_pmu_unregister_cpuhp_state(pmu); 1349 1348 1350 1349 perf_pmu_unregister(&pmu->base); 1351 - pmu->base.event_init = NULL; 1352 1350 kfree(pmu->base.attr_groups); 1353 1351 if (IS_DGFX(i915)) 1354 1352 kfree(pmu->name);
+2 -2
drivers/gpu/drm/i915/i915_pmu.h
··· 68 68 */ 69 69 struct pmu base; 70 70 /** 71 - * @closed: i915 is unregistering. 71 + * @registered: PMU is registered and not in the unregistering process. 72 72 */ 73 - bool closed; 73 + bool registered; 74 74 /** 75 75 * @name: Name as registered with perf core. 76 76 */