Commit 9a54b512 authored by Michal Wajdeczko's avatar Michal Wajdeczko
Browse files

drm/xe/pf: Make the late-initialization really late



While the late PF per-GT initialization is done quite late in the
single GT initialization flow, in case of multi-GT platforms, it
may still be done before other GT early initialization. That leads
to some issues during unwind, when there are cross-GT dependencies,
like resource cleanup that is shared by both GTs, but the other GT
may already be sanitized or disabled.

The following errors could be observed when trying to unload the PF
driver with some LMEM/VRAM already provisioned for few VFs:

 [ ] xe 0000:03:00.0: DEVRES REL ffff88814708f240 fini_config (16 bytes)
 [ ] xe 0000:03:00.0: [drm:lmtt_write_pte [xe]] PF: LMTT: WRITE level=2 index=1 pte=0x0
 [ ] xe 0000:03:00.0: [drm:lmtt_invalidate_hw [xe]] PF: LMTT: num_fences=2 err=-19
 [ ] xe 0000:03:00.0: [drm:lmtt_pt_free [xe]] PF: LMTT: level=0 addr=53a470000
 [ ] xe 0000:03:00.0: [drm:lmtt_pt_free [xe]] PF: LMTT: level=1 addr=53a4b0000
 [ ] xe 0000:03:00.0: [drm:lmtt_invalidate_hw [xe]] PF: LMTT: num_fences=2 err=-19
 [ ] xe 0000:03:00.0: [drm] PF: LMTT0 invalidation failed (-ENODEV)
 [ ] xe 0000:03:00.0: [drm:lmtt_write_pte [xe]] PF: LMTT: WRITE level=2 index=2 pte=0x0
 [ ] xe 0000:03:00.0: [drm:lmtt_invalidate_hw [xe]] PF: LMTT: num_fences=2 err=-19
 [ ] xe 0000:03:00.0: [drm:lmtt_pt_free [xe]] PF: LMTT: level=0 addr=539b70000
 [ ] xe 0000:03:00.0: [drm:lmtt_pt_free [xe]] PF: LMTT: level=1 addr=539bf0000
 [ ] xe 0000:03:00.0: [drm:lmtt_invalidate_hw [xe]] PF: LMTT: num_fences=2 err=-19
 [ ] xe 0000:03:00.0: [drm] PF: LMTT0 invalidation failed (-ENODEV)

Move all PF per-GT late initialization to the already defined late
SR-IOV initialization function to allow proper order of the cleanup
actions.

While around, format all PF function stubs as one-liners, like many
other stubs are defined in the Xe driver.

Signed-off-by: default avatarMichal Wajdeczko <michal.wajdeczko@intel.com>
Reviewed-by: default avatarJonathan Cavitt <jonathan.cavitt@intel.com>
Reviewed-by: default avatarPiotr Piórkowski <piotr.piorkowski@intel.com>
Link: https://lore.kernel.org/r/20251004162008.1782-1-michal.wajdeczko@intel.com
parent 71f1939e
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -573,10 +573,8 @@ static int gt_init_with_all_forcewake(struct xe_gt *gt)
	if (IS_SRIOV_PF(gt_to_xe(gt)) && xe_gt_is_main_type(gt))
		xe_lmtt_init_hw(&gt_to_tile(gt)->sriov.pf.lmtt);

	if (IS_SRIOV_PF(gt_to_xe(gt))) {
		xe_gt_sriov_pf_init(gt);
	if (IS_SRIOV_PF(gt_to_xe(gt)))
		xe_gt_sriov_pf_init_hw(gt);
	}

	xe_force_wake_put(gt_to_fw(gt), fw_ref);

+2 −0
Original line number Diff line number Diff line
@@ -167,6 +167,8 @@ const char *xe_sriov_function_name(unsigned int n, char *buf, size_t size)
 */
int xe_sriov_init_late(struct xe_device *xe)
{
	if (IS_SRIOV_PF(xe))
		return xe_sriov_pf_init_late(xe);
	if (IS_SRIOV_VF(xe))
		return xe_sriov_vf_init_late(xe);

+25 −0
Original line number Diff line number Diff line
@@ -103,6 +103,31 @@ int xe_sriov_pf_init_early(struct xe_device *xe)
	return 0;
}

/**
 * xe_sriov_pf_init_late() - Late initialization of the SR-IOV PF.
 * @xe: the &xe_device to initialize
 *
 * This function can only be called on PF.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int xe_sriov_pf_init_late(struct xe_device *xe)
{
	struct xe_gt *gt;
	unsigned int id;
	int err;

	xe_assert(xe, IS_SRIOV_PF(xe));

	for_each_gt(gt, xe, id) {
		err = xe_gt_sriov_pf_init(gt);
		if (err)
			return err;
	}

	return 0;
}

/**
 * xe_sriov_pf_wait_ready() - Wait until PF is ready to operate.
 * @xe: the &xe_device to test
+4 −9
Original line number Diff line number Diff line
@@ -15,18 +15,13 @@ struct xe_device;
#ifdef CONFIG_PCI_IOV
bool xe_sriov_pf_readiness(struct xe_device *xe);
int xe_sriov_pf_init_early(struct xe_device *xe);
int xe_sriov_pf_init_late(struct xe_device *xe);
int xe_sriov_pf_wait_ready(struct xe_device *xe);
void xe_sriov_pf_print_vfs_summary(struct xe_device *xe, struct drm_printer *p);
#else
static inline bool xe_sriov_pf_readiness(struct xe_device *xe)
{
	return false;
}

static inline int xe_sriov_pf_init_early(struct xe_device *xe)
{
	return 0;
}
static inline bool xe_sriov_pf_readiness(struct xe_device *xe) { return false; }
static inline int xe_sriov_pf_init_early(struct xe_device *xe) { return 0; }
static inline int xe_sriov_pf_init_late(struct xe_device *xe) { return 0; }
#endif

#endif