From: Michal Wajdeczko <michal.wajdeczko@intel.com>
To: "Michał Winiarski" <michal.winiarski@intel.com>,
"Alex Williamson" <alex@shazbot.org>,
"Lucas De Marchi" <lucas.demarchi@intel.com>,
"Thomas Hellström" <thomas.hellstrom@linux.intel.com>,
"Rodrigo Vivi" <rodrigo.vivi@intel.com>,
"Jason Gunthorpe" <jgg@ziepe.ca>,
"Yishai Hadas" <yishaih@nvidia.com>,
"Kevin Tian" <kevin.tian@intel.com>,
"Shameer Kolothum" <skolothumtho@nvidia.com>,
intel-xe@lists.freedesktop.org, linux-kernel@vger.kernel.org,
kvm@vger.kernel.org, "Matthew Brost" <matthew.brost@intel.com>
Cc: <dri-devel@lists.freedesktop.org>,
Jani Nikula <jani.nikula@linux.intel.com>,
Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
Tvrtko Ursulin <tursulin@ursulin.net>,
David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>,
"Lukasz Laguna" <lukasz.laguna@intel.com>,
Christoph Hellwig <hch@infradead.org>
Subject: Re: [PATCH v3 17/28] drm/xe/pf: Add helpers for VF GGTT migration data handling
Date: Fri, 31 Oct 2025 17:59:12 +0100 [thread overview]
Message-ID: <eb4d6982-e98d-48f0-a69d-617218686514@intel.com> (raw)
In-Reply-To: <20251030203135.337696-18-michal.winiarski@intel.com>
On 10/30/2025 9:31 PM, Michał Winiarski wrote:
> In an upcoming change, the VF GGTT migration data will be handled as
> part of VF control state machine. Add the necessary helpers to allow the
> migration data transfer to/from the HW GGTT resource.
>
> Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
> ---
> drivers/gpu/drm/xe/xe_ggtt.c | 104 +++++++++++++++++++++
> drivers/gpu/drm/xe/xe_ggtt.h | 4 +
> drivers/gpu/drm/xe/xe_ggtt_types.h | 2 +
> drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c | 52 +++++++++++
> drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h | 5 +
> 5 files changed, 167 insertions(+)
>
> diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c
> index 20d226d90c50f..00ddb4f013466 100644
> --- a/drivers/gpu/drm/xe/xe_ggtt.c
> +++ b/drivers/gpu/drm/xe/xe_ggtt.c
> @@ -151,6 +151,14 @@ static void xe_ggtt_set_pte_and_flush(struct xe_ggtt *ggtt, u64 addr, u64 pte)
> ggtt_update_access_counter(ggtt);
> }
>
> +static u64 xe_ggtt_get_pte(struct xe_ggtt *ggtt, u64 addr)
> +{
> + xe_tile_assert(ggtt->tile, !(addr & XE_PTE_MASK));
> + xe_tile_assert(ggtt->tile, addr < ggtt->size);
> +
> + return readq(&ggtt->gsm[addr >> XE_PTE_SHIFT]);
> +}
> +
> static void xe_ggtt_clear(struct xe_ggtt *ggtt, u64 start, u64 size)
> {
> u16 pat_index = tile_to_xe(ggtt->tile)->pat.idx[XE_CACHE_WB];
> @@ -233,16 +241,19 @@ void xe_ggtt_might_lock(struct xe_ggtt *ggtt)
> static const struct xe_ggtt_pt_ops xelp_pt_ops = {
> .pte_encode_flags = xelp_ggtt_pte_flags,
> .ggtt_set_pte = xe_ggtt_set_pte,
> + .ggtt_get_pte = xe_ggtt_get_pte,
> };
>
> static const struct xe_ggtt_pt_ops xelpg_pt_ops = {
> .pte_encode_flags = xelpg_ggtt_pte_flags,
> .ggtt_set_pte = xe_ggtt_set_pte,
> + .ggtt_get_pte = xe_ggtt_get_pte,
> };
>
> static const struct xe_ggtt_pt_ops xelpg_pt_wa_ops = {
> .pte_encode_flags = xelpg_ggtt_pte_flags,
> .ggtt_set_pte = xe_ggtt_set_pte_and_flush,
> + .ggtt_get_pte = xe_ggtt_get_pte,
> };
>
> static void __xe_ggtt_init_early(struct xe_ggtt *ggtt, u32 reserved)
> @@ -889,6 +900,20 @@ u64 xe_ggtt_largest_hole(struct xe_ggtt *ggtt, u64 alignment, u64 *spare)
> return max_hole;
> }
>
> +/**
> + * xe_ggtt_node_pt_size() - Convert GGTT node size to its page table entries size.
> + * @node: the &xe_ggtt_node
> + *
> + * Return: GGTT node page table entries size in bytes.
> + */
> +size_t xe_ggtt_node_pt_size(const struct xe_ggtt_node *node)
> +{
> + if (!node)
> + return 0;
> +
> + return node->base.size / XE_PAGE_SIZE * sizeof(u64);
> +}
> +
> #ifdef CONFIG_PCI_IOV
> static u64 xe_encode_vfid_pte(u16 vfid)
> {
> @@ -930,6 +955,85 @@ void xe_ggtt_assign(const struct xe_ggtt_node *node, u16 vfid)
> xe_ggtt_assign_locked(node->ggtt, &node->base, vfid);
> mutex_unlock(&node->ggtt->lock);
> }
> +
> +/**
> + * xe_ggtt_node_save() - Save a &xe_ggtt_node to a buffer.
> + * @node: the &xe_ggtt_node to be saved
> + * @dst: destination buffer
> + * @size: destination buffer size in bytes
> + * @vfid: VF identifier
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_ggtt_node_save(struct xe_ggtt_node *node, void *dst, size_t size, u16 vfid)
> +{
> + struct xe_ggtt *ggtt;
> + u64 start, end;
> + u64 *buf = dst;
> + u64 pte;
> +
> + if (!node)
> + return -ENOENT;
> +
> + guard(mutex)(&node->ggtt->lock);
> +
> + ggtt = node->ggtt;
> + start = node->base.start;
> + end = start + size - 1;
as you've already noticed, this 'size' (PT size) is the right size to calc the end
> +
> + if (xe_ggtt_node_pt_size(node) != size)
> + return -EINVAL;
> +
> + while (start < end) {
> + pte = ggtt->pt_ops->ggtt_get_pte(ggtt, start);
> + if (vfid != u64_get_bits(pte, GGTT_PTE_VFID))
> + return -EPERM;
> +
> + *buf++ = u64_replace_bits(pte, 0, GGTT_PTE_VFID);
> + start += XE_PAGE_SIZE;
> + }
> +
> + return 0;
> +}
> +
> +/**
> + * xe_ggtt_node_load() - Load a &xe_ggtt_node from a buffer.
> + * @node: the &xe_ggtt_node to be loaded
> + * @src: source buffer
> + * @size: source buffer size in bytes
> + * @vfid: VF identifier
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_ggtt_node_load(struct xe_ggtt_node *node, const void *src, size_t size, u16 vfid)
> +{
> + u64 vfid_pte = xe_encode_vfid_pte(vfid);
> + const u64 *buf = src;
> + struct xe_ggtt *ggtt;
> + u64 start, end;
> +
> + if (!node)
> + return -ENOENT;
> +
> + guard(mutex)(&node->ggtt->lock);
> +
> + ggtt = node->ggtt;
> + start = node->base.start;
> + end = start + size - 1;
ditto
> +
> + if (xe_ggtt_node_pt_size(node) != size)
> + return -EINVAL;
> +
> + while (start < end) {
> + vfid_pte = u64_replace_bits(*buf++, vfid, GGTT_PTE_VFID);
> + ggtt->pt_ops->ggtt_set_pte(ggtt, start, vfid_pte);
> + start += XE_PAGE_SIZE;
> + }
> + xe_ggtt_invalidate(ggtt);
> +
> + return 0;
> +}
> +
> #endif
>
> /**
> diff --git a/drivers/gpu/drm/xe/xe_ggtt.h b/drivers/gpu/drm/xe/xe_ggtt.h
> index 75fc7a1efea76..1edf27608d39a 100644
> --- a/drivers/gpu/drm/xe/xe_ggtt.h
> +++ b/drivers/gpu/drm/xe/xe_ggtt.h
> @@ -41,8 +41,12 @@ u64 xe_ggtt_largest_hole(struct xe_ggtt *ggtt, u64 alignment, u64 *spare);
> int xe_ggtt_dump(struct xe_ggtt *ggtt, struct drm_printer *p);
> u64 xe_ggtt_print_holes(struct xe_ggtt *ggtt, u64 alignment, struct drm_printer *p);
>
> +size_t xe_ggtt_node_pt_size(const struct xe_ggtt_node *node);
> +
> #ifdef CONFIG_PCI_IOV
> void xe_ggtt_assign(const struct xe_ggtt_node *node, u16 vfid);
> +int xe_ggtt_node_save(struct xe_ggtt_node *node, void *dst, size_t size, u16 vfid);
> +int xe_ggtt_node_load(struct xe_ggtt_node *node, const void *src, size_t size, u16 vfid);
> #endif
>
> #ifndef CONFIG_LOCKDEP
> diff --git a/drivers/gpu/drm/xe/xe_ggtt_types.h b/drivers/gpu/drm/xe/xe_ggtt_types.h
> index c5e999d58ff2a..dacd796f81844 100644
> --- a/drivers/gpu/drm/xe/xe_ggtt_types.h
> +++ b/drivers/gpu/drm/xe/xe_ggtt_types.h
> @@ -78,6 +78,8 @@ struct xe_ggtt_pt_ops {
> u64 (*pte_encode_flags)(struct xe_bo *bo, u16 pat_index);
> /** @ggtt_set_pte: Directly write into GGTT's PTE */
> void (*ggtt_set_pte)(struct xe_ggtt *ggtt, u64 addr, u64 pte);
> + /** @ggtt_get_pte: Directly read from GGTT's PTE */
> + u64 (*ggtt_get_pte)(struct xe_ggtt *ggtt, u64 addr);
> };
>
> #endif
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> index c0c0215c07036..55444883f2ac3 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.c
> @@ -726,6 +726,58 @@ int xe_gt_sriov_pf_config_set_fair_ggtt(struct xe_gt *gt, unsigned int vfid,
> return xe_gt_sriov_pf_config_bulk_set_ggtt(gt, vfid, num_vfs, fair);
> }
>
> +/**
> + * xe_gt_sriov_pf_config_ggtt_save() - Save a VF provisioned GGTT data into a buffer.
> + * @gt: the &xe_gt
> + * @vfid: VF identifier (can't be 0)
> + * @buf: the GGTT data destination buffer (or NULL to query the buf size)
> + * @size: the size of the buffer (or 0 to query the buf size)
> + *
> + * This function can only be called on PF.
> + *
> + * Return: size of the buffer needed to save GGTT data if querying,
> + * 0 on successful save or a negative error code on failure.
> + */
> +ssize_t xe_gt_sriov_pf_config_ggtt_save(struct xe_gt *gt, unsigned int vfid,
> + void *buf, size_t size)
> +{
> + struct xe_ggtt_node *node;
> +
> + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
> + xe_gt_assert(gt, vfid);
> + xe_gt_assert(gt, !(!buf ^ !size));
> +
> + guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
> + node = pf_pick_vf_config(gt, vfid)->ggtt_region;
> +
> + if (!buf)
> + return xe_ggtt_node_pt_size(node);
> +
> + return xe_ggtt_node_save(node, buf, size, vfid);
> +}
> +
> +/**
> + * xe_gt_sriov_pf_config_ggtt_restore() - Restore a VF provisioned GGTT data from a buffer.
> + * @gt: the &xe_gt
> + * @vfid: VF identifier (can't be 0)
> + * @buf: the GGTT data source buffer
> + * @size: the size of the buffer
> + *
> + * This function can only be called on PF.
> + *
> + * Return: 0 on success or a negative error code on failure.
> + */
> +int xe_gt_sriov_pf_config_ggtt_restore(struct xe_gt *gt, unsigned int vfid,
> + const void *buf, size_t size)
> +{
> + xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
> + xe_gt_assert(gt, vfid);
> +
> + guard(mutex)(xe_gt_sriov_pf_master_mutex(gt));
> +
> + return xe_ggtt_node_load(pf_pick_vf_config(gt, vfid)->ggtt_region, buf, size, vfid);
> +}
> +
> static u32 pf_get_min_spare_ctxs(struct xe_gt *gt)
> {
> /* XXX: preliminary */
> diff --git a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h
> index 513e6512a575b..0293ba98eb6df 100644
> --- a/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h
> +++ b/drivers/gpu/drm/xe/xe_gt_sriov_pf_config.h
> @@ -61,6 +61,11 @@ ssize_t xe_gt_sriov_pf_config_save(struct xe_gt *gt, unsigned int vfid, void *bu
> int xe_gt_sriov_pf_config_restore(struct xe_gt *gt, unsigned int vfid,
> const void *buf, size_t size);
>
> +ssize_t xe_gt_sriov_pf_config_ggtt_save(struct xe_gt *gt, unsigned int vfid,
> + void *buf, size_t size);
> +int xe_gt_sriov_pf_config_ggtt_restore(struct xe_gt *gt, unsigned int vfid,
> + const void *buf, size_t size);
> +
> bool xe_gt_sriov_pf_config_is_empty(struct xe_gt *gt, unsigned int vfid);
>
> int xe_gt_sriov_pf_config_init(struct xe_gt *gt);
next prev parent reply other threads:[~2025-10-31 16:59 UTC|newest]
Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-30 20:31 [PATCH v3 00/28] vfio/xe: Add driver variant for Xe VF migration Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 01/28] drm/xe/pf: Remove GuC version check for migration support Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 02/28] drm/xe: Move migration support to device-level struct Michał Winiarski
2025-11-03 18:55 ` Michal Wajdeczko
2025-10-30 20:31 ` [PATCH v3 03/28] drm/xe/pf: Convert control state to bitmap Michał Winiarski
2025-10-30 22:57 ` Michal Wajdeczko
2025-10-31 7:50 ` Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 04/28] drm/xe/pf: Add save/restore control state stubs and connect to debugfs Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 05/28] drm/xe/pf: Add data structures and handlers for migration rings Michał Winiarski
2025-10-31 16:17 ` Michal Wajdeczko
2025-11-04 10:25 ` Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 06/28] drm/xe/pf: Add helpers for migration data allocation / free Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 07/28] drm/xe/pf: Add support for encap/decap of bitstream to/from packet Michał Winiarski
2025-10-31 16:31 ` Michal Wajdeczko
2025-11-04 11:16 ` Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 08/28] drm/xe/pf: Add minimalistic migration descriptor Michał Winiarski
2025-10-31 16:41 ` Michal Wajdeczko
2025-10-30 20:31 ` [PATCH v3 09/28] drm/xe/pf: Expose VF migration data size over debugfs Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 10/28] drm/xe: Add sa/guc_buf_cache sync interface Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 11/28] drm/xe: Allow the caller to pass guc_buf_cache size Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 12/28] drm/xe/pf: Increase PF GuC Buffer Cache size and use it for VF migration Michał Winiarski
2025-10-31 16:48 ` Michal Wajdeczko
2025-10-30 20:31 ` [PATCH v3 13/28] drm/xe/pf: Remove GuC migration data save/restore from GT debugfs Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 14/28] drm/xe/pf: Don't save GuC VF migration data on pause Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 15/28] drm/xe/pf: Switch VF migration GuC save/restore to struct migration data Michał Winiarski
2025-11-03 18:30 ` Michal Wajdeczko
2025-10-30 20:31 ` [PATCH v3 16/28] drm/xe/pf: Handle GuC migration data as part of PF control Michał Winiarski
2025-10-31 18:15 ` Michal Wajdeczko
2025-11-04 11:55 ` Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 17/28] drm/xe/pf: Add helpers for VF GGTT migration data handling Michał Winiarski
2025-10-31 16:59 ` Michal Wajdeczko [this message]
2025-10-30 20:31 ` [PATCH v3 18/28] drm/xe/pf: Handle GGTT migration data as part of PF control Michał Winiarski
2025-10-31 18:26 ` Michal Wajdeczko
2025-11-04 12:12 ` Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 19/28] drm/xe/pf: Handle MMIO " Michał Winiarski
2025-10-31 18:39 ` Michal Wajdeczko
2025-11-04 12:29 ` Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 20/28] drm/xe/pf: Add helper to retrieve VF's LMEM object Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 21/28] drm/xe/migrate: Add function to copy of VRAM data in chunks Michał Winiarski
2025-11-03 22:29 ` Matthew Brost
2025-10-30 20:31 ` [PATCH v3 22/28] drm/xe/pf: Handle VRAM migration data as part of PF control Michał Winiarski
2025-11-03 22:37 ` Matthew Brost
2025-11-04 12:39 ` Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 23/28] drm/xe/pf: Add wait helper for VF FLR Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 24/28] drm/xe/pf: Enable SR-IOV VF migration Michał Winiarski
2025-10-31 17:06 ` Michal Wajdeczko
2025-10-30 20:31 ` [PATCH v3 25/28] drm/xe/pci: Introduce a helper to allow VF access to PF xe_device Michał Winiarski
2025-10-31 17:39 ` Michal Wajdeczko
2025-10-30 20:31 ` [PATCH v3 26/28] drm/xe/pf: Export helpers for VFIO Michał Winiarski
2025-10-30 20:31 ` [PATCH v3 27/28] drm/intel/pciids: Add match with VFIO override Michał Winiarski
2025-11-03 21:30 ` Lucas De Marchi
2025-11-04 12:59 ` Michał Winiarski
2025-11-04 17:41 ` Lucas De Marchi
2025-11-04 19:27 ` Jason Gunthorpe
2025-11-05 15:20 ` Michał Winiarski
2025-11-05 17:15 ` Jason Gunthorpe
2025-11-05 17:42 ` Lucas De Marchi
2025-10-30 20:31 ` [PATCH v3 28/28] vfio/xe: Add device specific vfio_pci driver variant for Intel graphics Michał Winiarski
2025-11-07 9:38 ` Muqthyar Ahmed, Syed Abdul
2025-11-07 9:54 ` Winiarski, Michal
2025-10-30 22:34 ` ✗ CI.checkpatch: warning for vfio/xe: Add driver variant for Xe VF migration (rev3) Patchwork
2025-10-30 22:35 ` ✓ CI.KUnit: success " Patchwork
2025-10-30 23:57 ` ✓ Xe.CI.BAT: " Patchwork
2025-10-31 7:50 ` ✗ Xe.CI.Full: failure " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=eb4d6982-e98d-48f0-a69d-617218686514@intel.com \
--to=michal.wajdeczko@intel.com \
--cc=airlied@gmail.com \
--cc=alex@shazbot.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=hch@infradead.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=jgg@ziepe.ca \
--cc=joonas.lahtinen@linux.intel.com \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lucas.demarchi@intel.com \
--cc=lukasz.laguna@intel.com \
--cc=matthew.brost@intel.com \
--cc=michal.winiarski@intel.com \
--cc=rodrigo.vivi@intel.com \
--cc=simona@ffwll.ch \
--cc=skolothumtho@nvidia.com \
--cc=thomas.hellstrom@linux.intel.com \
--cc=tursulin@ursulin.net \
--cc=yishaih@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.