Skip to content

Commit 644a699

Browse files
committed
drm/xe/pf: Add helpers for migration data packet allocation / free
Now that it's possible to free the packets - connect the restore handling logic with the ring. The helpers will also be used in upcoming changes that will start producing migration data packets. Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Link: https://patch.msgid.link/20251112132220.516975-7-michal.winiarski@intel.com Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
1 parent 67df4a5 commit 644a699

7 files changed

Lines changed: 221 additions & 3 deletions

File tree

drivers/gpu/drm/xe/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ xe-$(CONFIG_PCI_IOV) += \
174174
xe_lmtt_2l.o \
175175
xe_lmtt_ml.o \
176176
xe_pci_sriov.o \
177+
xe_sriov_packet.o \
177178
xe_sriov_pf.o \
178179
xe_sriov_pf_control.o \
179180
xe_sriov_pf_debugfs.o \

drivers/gpu/drm/xe/xe_gt_sriov_pf_control.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "xe_gt_sriov_printk.h"
1919
#include "xe_guc_ct.h"
2020
#include "xe_sriov.h"
21+
#include "xe_sriov_packet.h"
2122
#include "xe_sriov_packet_types.h"
2223
#include "xe_sriov_pf_control.h"
2324
#include "xe_sriov_pf_migration.h"
@@ -853,6 +854,8 @@ int xe_gt_sriov_pf_control_resume_vf(struct xe_gt *gt, unsigned int vfid)
853854
static void pf_exit_vf_save_wip(struct xe_gt *gt, unsigned int vfid)
854855
{
855856
if (pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WIP)) {
857+
xe_gt_sriov_pf_migration_ring_free(gt, vfid);
858+
856859
pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_PROCESS_DATA);
857860
pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_WAIT_DATA);
858861
pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_SAVE_DATA_DONE);
@@ -1075,6 +1078,8 @@ int xe_gt_sriov_pf_control_finish_save_vf(struct xe_gt *gt, unsigned int vfid)
10751078
static void pf_exit_vf_restore_wip(struct xe_gt *gt, unsigned int vfid)
10761079
{
10771080
if (pf_exit_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WIP)) {
1081+
xe_gt_sriov_pf_migration_ring_free(gt, vfid);
1082+
10781083
pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_PROCESS_DATA);
10791084
pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_WAIT_DATA);
10801085
pf_escape_vf_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_DATA_DONE);
@@ -1109,6 +1114,8 @@ static int pf_handle_vf_restore_data(struct xe_gt *gt, unsigned int vfid)
11091114

11101115
xe_gt_sriov_notice(gt, "Skipping VF%u unknown data type: %d\n", vfid, data->hdr.type);
11111116

1117+
xe_sriov_packet_free(data);
1118+
11121119
return 0;
11131120
}
11141121

@@ -1202,8 +1209,10 @@ int xe_gt_sriov_pf_control_restore_data_done(struct xe_gt *gt, unsigned int vfid
12021209
*/
12031210
int xe_gt_sriov_pf_control_process_restore_data(struct xe_gt *gt, unsigned int vfid)
12041211
{
1205-
if (!pf_expect_vf_not_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_FAILED))
1212+
if (!pf_expect_vf_not_state(gt, vfid, XE_GT_SRIOV_STATE_RESTORE_FAILED)) {
1213+
xe_gt_sriov_pf_migration_ring_free(gt, vfid);
12061214
return -EIO;
1215+
}
12071216

12081217
pf_exit_vf_restore_wait_data(gt, vfid);
12091218

drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "xe_guc.h"
1515
#include "xe_guc_ct.h"
1616
#include "xe_sriov.h"
17+
#include "xe_sriov_packet.h"
1718
#include "xe_sriov_packet_types.h"
1819
#include "xe_sriov_pf_migration.h"
1920

@@ -419,6 +420,25 @@ bool xe_gt_sriov_pf_migration_ring_full(struct xe_gt *gt, unsigned int vfid)
419420
return ptr_ring_full(&pf_pick_gt_migration(gt, vfid)->ring);
420421
}
421422

423+
/**
424+
* xe_gt_sriov_pf_migration_ring_free() - Consume and free all data in migration ring
425+
* @gt: the &xe_gt
426+
* @vfid: the VF identifier
427+
*/
428+
void xe_gt_sriov_pf_migration_ring_free(struct xe_gt *gt, unsigned int vfid)
429+
{
430+
struct xe_gt_sriov_migration_data *migration = pf_pick_gt_migration(gt, vfid);
431+
struct xe_sriov_packet *data;
432+
433+
if (ptr_ring_empty(&migration->ring))
434+
return;
435+
436+
xe_gt_sriov_notice(gt, "VF%u unprocessed migration data left in the ring!\n", vfid);
437+
438+
while ((data = ptr_ring_consume(&migration->ring)))
439+
xe_sriov_packet_free(data);
440+
}
441+
422442
/**
423443
* xe_gt_sriov_pf_migration_save_produce() - Add VF save data packet to migration ring.
424444
* @gt: the &xe_gt
@@ -545,8 +565,10 @@ xe_gt_sriov_pf_migration_save_consume(struct xe_gt *gt, unsigned int vfid)
545565
data = ptr_ring_consume(&migration->ring);
546566
if (data) {
547567
ret = xe_gt_sriov_pf_control_process_save_data(gt, vfid);
548-
if (ret)
568+
if (ret) {
569+
xe_sriov_packet_free(data);
549570
return ERR_PTR(ret);
571+
}
550572

551573
return data;
552574
}
@@ -560,11 +582,18 @@ xe_gt_sriov_pf_migration_save_consume(struct xe_gt *gt, unsigned int vfid)
560582
return ERR_PTR(-EAGAIN);
561583
}
562584

585+
static void destroy_pf_packet(void *ptr)
586+
{
587+
struct xe_sriov_packet *data = ptr;
588+
589+
xe_sriov_packet_free(data);
590+
}
591+
563592
static void action_ring_cleanup(void *arg)
564593
{
565594
struct ptr_ring *r = arg;
566595

567-
ptr_ring_cleanup(r, NULL);
596+
ptr_ring_cleanup(r, destroy_pf_packet);
568597
}
569598

570599
/**

drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ int xe_gt_sriov_pf_migration_restore_guc_state(struct xe_gt *gt, unsigned int vf
1717

1818
bool xe_gt_sriov_pf_migration_ring_empty(struct xe_gt *gt, unsigned int vfid);
1919
bool xe_gt_sriov_pf_migration_ring_full(struct xe_gt *gt, unsigned int vfid);
20+
void xe_gt_sriov_pf_migration_ring_free(struct xe_gt *gt, unsigned int vfid);
2021

2122
int xe_gt_sriov_pf_migration_save_produce(struct xe_gt *gt, unsigned int vfid,
2223
struct xe_sriov_packet *data);
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// SPDX-License-Identifier: MIT
2+
/*
3+
* Copyright © 2025 Intel Corporation
4+
*/
5+
6+
#include "xe_bo.h"
7+
#include "xe_device.h"
8+
#include "xe_printk.h"
9+
#include "xe_sriov_packet.h"
10+
#include "xe_sriov_packet_types.h"
11+
12+
static bool pkt_needs_bo(struct xe_sriov_packet *data)
13+
{
14+
return data->hdr.type == XE_SRIOV_PACKET_TYPE_VRAM;
15+
}
16+
17+
/**
18+
* xe_sriov_packet_alloc() - Allocate migration data packet
19+
* @xe: the &xe_device
20+
*
21+
* Only allocates the "outer" structure, without initializing the migration
22+
* data backing storage.
23+
*
24+
* Return: Pointer to &xe_sriov_packet on success,
25+
* NULL in case of error.
26+
*/
27+
struct xe_sriov_packet *xe_sriov_packet_alloc(struct xe_device *xe)
28+
{
29+
struct xe_sriov_packet *data;
30+
31+
data = kzalloc(sizeof(*data), GFP_KERNEL);
32+
if (!data)
33+
return NULL;
34+
35+
data->xe = xe;
36+
data->hdr_remaining = sizeof(data->hdr);
37+
38+
return data;
39+
}
40+
41+
/**
42+
* xe_sriov_packet_free() - Free migration data packet.
43+
* @data: the &xe_sriov_packet
44+
*/
45+
void xe_sriov_packet_free(struct xe_sriov_packet *data)
46+
{
47+
if (IS_ERR_OR_NULL(data))
48+
return;
49+
50+
if (pkt_needs_bo(data))
51+
xe_bo_unpin_map_no_vm(data->bo);
52+
else
53+
kvfree(data->buff);
54+
55+
kfree(data);
56+
}
57+
58+
static int pkt_init(struct xe_sriov_packet *data)
59+
{
60+
struct xe_gt *gt = xe_device_get_gt(data->xe, data->hdr.gt_id);
61+
62+
if (!gt)
63+
return -EINVAL;
64+
65+
if (data->hdr.size == 0)
66+
return 0;
67+
68+
if (pkt_needs_bo(data)) {
69+
struct xe_bo *bo;
70+
71+
bo = xe_bo_create_pin_map_novm(data->xe, gt->tile, PAGE_ALIGN(data->hdr.size),
72+
ttm_bo_type_kernel,
73+
XE_BO_FLAG_SYSTEM | XE_BO_FLAG_PINNED, false);
74+
if (IS_ERR(bo))
75+
return PTR_ERR(bo);
76+
77+
data->bo = bo;
78+
data->vaddr = bo->vmap.vaddr;
79+
} else {
80+
void *buff = kvzalloc(data->hdr.size, GFP_KERNEL);
81+
82+
if (!buff)
83+
return -ENOMEM;
84+
85+
data->buff = buff;
86+
data->vaddr = buff;
87+
}
88+
89+
return 0;
90+
}
91+
92+
#define XE_SRIOV_PACKET_SUPPORTED_VERSION 1
93+
94+
/**
95+
* xe_sriov_packet_init() - Initialize migration packet header and backing storage.
96+
* @data: the &xe_sriov_packet
97+
* @tile_id: tile identifier
98+
* @gt_id: GT identifier
99+
* @type: &xe_sriov_packet_type
100+
* @offset: offset of data packet payload (within wider resource)
101+
* @size: size of data packet payload
102+
*
103+
* Return: 0 on success or a negative error code on failure.
104+
*/
105+
int xe_sriov_packet_init(struct xe_sriov_packet *data, u8 tile_id, u8 gt_id,
106+
enum xe_sriov_packet_type type, loff_t offset, size_t size)
107+
{
108+
data->hdr.version = XE_SRIOV_PACKET_SUPPORTED_VERSION;
109+
data->hdr.type = type;
110+
data->hdr.tile_id = tile_id;
111+
data->hdr.gt_id = gt_id;
112+
data->hdr.offset = offset;
113+
data->hdr.size = size;
114+
data->remaining = size;
115+
116+
return pkt_init(data);
117+
}
118+
119+
/**
120+
* xe_sriov_packet_init_from_hdr() - Initialize migration packet backing storage based on header.
121+
* @data: the &xe_sriov_packet
122+
*
123+
* Header data is expected to be filled prior to calling this function.
124+
*
125+
* Return: 0 on success or a negative error code on failure.
126+
*/
127+
int xe_sriov_packet_init_from_hdr(struct xe_sriov_packet *data)
128+
{
129+
xe_assert(data->xe, !data->hdr_remaining);
130+
131+
if (data->hdr.version != XE_SRIOV_PACKET_SUPPORTED_VERSION)
132+
return -EINVAL;
133+
134+
data->remaining = data->hdr.size;
135+
136+
return pkt_init(data);
137+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/* SPDX-License-Identifier: MIT */
2+
/*
3+
* Copyright © 2025 Intel Corporation
4+
*/
5+
6+
#ifndef _XE_SRIOV_PACKET_H_
7+
#define _XE_SRIOV_PACKET_H_
8+
9+
#include <linux/types.h>
10+
11+
struct xe_device;
12+
struct xe_sriov_packet;
13+
enum xe_sriov_packet_type;
14+
15+
struct xe_sriov_packet *xe_sriov_packet_alloc(struct xe_device *xe);
16+
void xe_sriov_packet_free(struct xe_sriov_packet *data);
17+
18+
int xe_sriov_packet_init(struct xe_sriov_packet *data, u8 tile_id, u8 gt_id,
19+
enum xe_sriov_packet_type, loff_t offset, size_t size);
20+
int xe_sriov_packet_init_from_hdr(struct xe_sriov_packet *data);
21+
22+
#endif

drivers/gpu/drm/xe/xe_sriov_packet_types.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@
88

99
#include <linux/types.h>
1010

11+
/**
12+
* enum xe_sriov_packet_type - Xe SR-IOV VF migration data packet type
13+
* @XE_SRIOV_PACKET_TYPE_DESCRIPTOR: Descriptor with VF device metadata
14+
* @XE_SRIOV_PACKET_TYPE_TRAILER: Trailer indicating end-of-stream
15+
* @XE_SRIOV_PACKET_TYPE_GGTT: Global GTT migration data
16+
* @XE_SRIOV_PACKET_TYPE_MMIO: MMIO registers migration data
17+
* @XE_SRIOV_PACKET_TYPE_GUC: GuC firmware migration data
18+
* @XE_SRIOV_PACKET_TYPE_VRAM: VRAM migration data
19+
*/
20+
enum xe_sriov_packet_type {
21+
/* Skipping 0 to catch uninitialized data */
22+
XE_SRIOV_PACKET_TYPE_DESCRIPTOR = 1,
23+
XE_SRIOV_PACKET_TYPE_TRAILER,
24+
XE_SRIOV_PACKET_TYPE_GGTT,
25+
XE_SRIOV_PACKET_TYPE_MMIO,
26+
XE_SRIOV_PACKET_TYPE_GUC,
27+
XE_SRIOV_PACKET_TYPE_VRAM,
28+
};
29+
1130
/**
1231
* struct xe_sriov_packet_hdr - Xe SR-IOV VF migration data packet header
1332
*/

0 commit comments

Comments
 (0)