Commit b7c1b990 authored by Michał Winiarski's avatar Michał Winiarski
Browse files

drm/xe/pf: Handle MMIO migration data as part of PF control



Implement the helpers and use them for save and restore of MMIO
migration data in stop_copy / resume device state.

Reviewed-by: default avatarMichal Wajdeczko <michal.wajdeczko@intel.com>
Link: https://patch.msgid.link/20251112132220.516975-20-michal.winiarski@intel.com


Signed-off-by: default avatarMichał Winiarski <michal.winiarski@intel.com>
parent 2579764a
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -880,6 +880,18 @@ static int pf_handle_vf_save_data(struct xe_gt *gt, unsigned int vfid)
		return -EAGAIN;
	}

	if (xe_gt_sriov_pf_migration_save_data_pending(gt, vfid,
						       XE_SRIOV_PACKET_TYPE_MMIO)) {
		ret = xe_gt_sriov_pf_migration_mmio_save(gt, vfid);
		if (ret)
			return ret;

		xe_gt_sriov_pf_migration_save_data_complete(gt, vfid,
							    XE_SRIOV_PACKET_TYPE_MMIO);

		return -EAGAIN;
	}

	return 0;
}

@@ -1112,6 +1124,9 @@ static int pf_handle_vf_restore_data(struct xe_gt *gt, unsigned int vfid)
	case XE_SRIOV_PACKET_TYPE_GGTT:
		ret = xe_gt_sriov_pf_migration_ggtt_restore(gt, vfid, data);
		break;
	case XE_SRIOV_PACKET_TYPE_MMIO:
		ret = xe_gt_sriov_pf_migration_mmio_restore(gt, vfid, data);
		break;
	case XE_SRIOV_PACKET_TYPE_GUC:
		ret = xe_gt_sriov_pf_migration_guc_restore(gt, vfid, data);
		break;
+157 −0
Original line number Diff line number Diff line
@@ -5,10 +5,13 @@

#include <drm/drm_managed.h>

#include "regs/xe_guc_regs.h"

#include "abi/guc_actions_sriov_abi.h"
#include "xe_bo.h"
#include "xe_ggtt.h"
#include "xe_gt.h"
#include "xe_gt_sriov_pf.h"
#include "xe_gt_sriov_pf_config.h"
#include "xe_gt_sriov_pf_control.h"
#include "xe_gt_sriov_pf_helpers.h"
@@ -16,6 +19,7 @@
#include "xe_gt_sriov_printk.h"
#include "xe_guc_buf.h"
#include "xe_guc_ct.h"
#include "xe_mmio.h"
#include "xe_sriov.h"
#include "xe_sriov_packet.h"
#include "xe_sriov_packet_types.h"
@@ -358,6 +362,149 @@ int xe_gt_sriov_pf_migration_guc_restore(struct xe_gt *gt, unsigned int vfid,
	return pf_restore_vf_guc_state(gt, vfid, data);
}

static ssize_t pf_migration_mmio_size(struct xe_gt *gt, unsigned int vfid)
{
	if (xe_gt_is_media_type(gt))
		return MED_VF_SW_FLAG_COUNT * sizeof(u32);
	else
		return VF_SW_FLAG_COUNT * sizeof(u32);
}

static int pf_migration_mmio_save(struct xe_gt *gt, unsigned int vfid, void *buf, size_t size)
{
	struct xe_mmio mmio;
	u32 *regs = buf;
	int n;

	if (size != pf_migration_mmio_size(gt, vfid))
		return -EINVAL;

	xe_mmio_init_vf_view(&mmio, &gt->mmio, vfid);

	if (xe_gt_is_media_type(gt))
		for (n = 0; n < MED_VF_SW_FLAG_COUNT; n++)
			regs[n] = xe_mmio_read32(&gt->mmio, MED_VF_SW_FLAG(n));
	else
		for (n = 0; n < VF_SW_FLAG_COUNT; n++)
			regs[n] = xe_mmio_read32(&gt->mmio, VF_SW_FLAG(n));

	return 0;
}

static int pf_migration_mmio_restore(struct xe_gt *gt, unsigned int vfid,
				     const void *buf, size_t size)
{
	const u32 *regs = buf;
	struct xe_mmio mmio;
	int n;

	if (size != pf_migration_mmio_size(gt, vfid))
		return -EINVAL;

	xe_mmio_init_vf_view(&mmio, &gt->mmio, vfid);

	if (xe_gt_is_media_type(gt))
		for (n = 0; n < MED_VF_SW_FLAG_COUNT; n++)
			xe_mmio_write32(&gt->mmio, MED_VF_SW_FLAG(n), regs[n]);
	else
		for (n = 0; n < VF_SW_FLAG_COUNT; n++)
			xe_mmio_write32(&gt->mmio, VF_SW_FLAG(n), regs[n]);

	return 0;
}

static int pf_save_vf_mmio_mig_data(struct xe_gt *gt, unsigned int vfid)
{
	struct xe_sriov_packet *data;
	size_t size;
	int ret;

	size = pf_migration_mmio_size(gt, vfid);
	xe_gt_assert(gt, size);

	data = xe_sriov_packet_alloc(gt_to_xe(gt));
	if (!data)
		return -ENOMEM;

	ret = xe_sriov_packet_init(data, gt->tile->id, gt->info.id,
				   XE_SRIOV_PACKET_TYPE_MMIO, 0, size);
	if (ret)
		goto fail;

	ret = pf_migration_mmio_save(gt, vfid, data->vaddr, size);
	if (ret)
		goto fail;

	pf_dump_mig_data(gt, vfid, data, "MMIO data save");

	ret = xe_gt_sriov_pf_migration_save_produce(gt, vfid, data);
	if (ret)
		goto fail;

	return 0;

fail:
	xe_sriov_packet_free(data);
	xe_gt_sriov_err(gt, "Failed to save VF%u MMIO data (%pe)\n", vfid, ERR_PTR(ret));
	return ret;
}

static int pf_restore_vf_mmio_mig_data(struct xe_gt *gt, unsigned int vfid,
				       struct xe_sriov_packet *data)
{
	int ret;

	pf_dump_mig_data(gt, vfid, data, "MMIO data restore");

	ret = pf_migration_mmio_restore(gt, vfid, data->vaddr, data->hdr.size);
	if (ret) {
		xe_gt_sriov_err(gt, "Failed to restore VF%u MMIO data (%pe)\n",
				vfid, ERR_PTR(ret));

		return ret;
	}

	return 0;
}

/**
 * xe_gt_sriov_pf_migration_mmio_save() - Save VF MMIO migration data.
 * @gt: the &xe_gt
 * @vfid: the VF identifier (can't be 0)
 *
 * This function is for PF only.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int xe_gt_sriov_pf_migration_mmio_save(struct xe_gt *gt, unsigned int vfid)
{
	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
	xe_gt_assert(gt, vfid != PFID);
	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));

	return pf_save_vf_mmio_mig_data(gt, vfid);
}

/**
 * xe_gt_sriov_pf_migration_mmio_restore() - Restore VF MMIO migration data.
 * @gt: the &xe_gt
 * @vfid: the VF identifier (can't be 0)
 * @data: the &xe_sriov_packet containing migration data
 *
 * This function is for PF only.
 *
 * Return: 0 on success or a negative error code on failure.
 */
int xe_gt_sriov_pf_migration_mmio_restore(struct xe_gt *gt, unsigned int vfid,
					  struct xe_sriov_packet *data)
{
	xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
	xe_gt_assert(gt, vfid != PFID);
	xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));

	return pf_restore_vf_mmio_mig_data(gt, vfid, data);
}

/**
 * xe_gt_sriov_pf_migration_size() - Total size of migration data from all components within a GT.
 * @gt: the &xe_gt
@@ -390,6 +537,13 @@ ssize_t xe_gt_sriov_pf_migration_size(struct xe_gt *gt, unsigned int vfid)
		size += sizeof(struct xe_sriov_packet_hdr);
	total += size;

	size = pf_migration_mmio_size(gt, vfid);
	if (size < 0)
		return size;
	if (size > 0)
		size += sizeof(struct xe_sriov_packet_hdr);
	total += size;

	return total;
}

@@ -458,6 +612,9 @@ void xe_gt_sriov_pf_migration_save_init(struct xe_gt *gt, unsigned int vfid)

	if (pf_migration_ggtt_size(gt, vfid) > 0)
		pf_migration_save_data_todo(gt, vfid, XE_SRIOV_PACKET_TYPE_GGTT);

	xe_gt_assert(gt, pf_migration_mmio_size(gt, vfid) > 0);
	pf_migration_save_data_todo(gt, vfid, XE_SRIOV_PACKET_TYPE_MMIO);
}

/**
+3 −0
Original line number Diff line number Diff line
@@ -22,6 +22,9 @@ int xe_gt_sriov_pf_migration_guc_restore(struct xe_gt *gt, unsigned int vfid,
int xe_gt_sriov_pf_migration_ggtt_save(struct xe_gt *gt, unsigned int vfid);
int xe_gt_sriov_pf_migration_ggtt_restore(struct xe_gt *gt, unsigned int vfid,
					  struct xe_sriov_packet *data);
int xe_gt_sriov_pf_migration_mmio_save(struct xe_gt *gt, unsigned int vfid);
int xe_gt_sriov_pf_migration_mmio_restore(struct xe_gt *gt, unsigned int vfid,
					  struct xe_sriov_packet *data);

ssize_t xe_gt_sriov_pf_migration_size(struct xe_gt *gt, unsigned int vfid);