Skip to content

Commit 642a30a

Browse files
committed
drm/xe/pf: Switch VF migration GuC save/restore to struct migration data
In upcoming changes, the GuC VF migration data will be handled as part of separate SAVE/RESTORE states in VF control state machine. Now that the data is decoupled from both guc_state debugfs and PAUSE state, we can safely remove the struct xe_gt_sriov_state_snapshot and modify the GuC save/restore functions to operate on struct xe_sriov_migration_data. Reviewed-by: Michal Wajdeczko <michal.wajdeczko@intel.com> Link: https://patch.msgid.link/20251112132220.516975-16-michal.winiarski@intel.com Signed-off-by: Michał Winiarski <michal.winiarski@intel.com>
1 parent 6e03c13 commit 642a30a

4 files changed

Lines changed: 80 additions & 230 deletions

File tree

drivers/gpu/drm/xe/xe_gt_sriov_pf_migration.c

Lines changed: 76 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,19 @@ static struct xe_gt_sriov_migration_data *pf_pick_gt_migration(struct xe_gt *gt,
2929
return &gt->sriov.pf.vfs[vfid].migration;
3030
}
3131

32+
static void pf_dump_mig_data(struct xe_gt *gt, unsigned int vfid,
33+
struct xe_sriov_packet *data,
34+
const char *what)
35+
{
36+
if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV)) {
37+
struct drm_printer p = xe_gt_dbg_printer(gt);
38+
39+
drm_printf(&p, "VF%u %s (%llu bytes)\n", vfid, what, data->hdr.size);
40+
drm_print_hex_dump(&p, "mig_hdr: ", (void *)&data->hdr, sizeof(data->hdr));
41+
drm_print_hex_dump(&p, "mig_data: ", data->vaddr, min(SZ_64, data->hdr.size));
42+
}
43+
}
44+
3245
/* Return: number of dwords saved/restored/required or a negative error code on failure */
3346
static int guc_action_vf_save_restore(struct xe_guc *guc, u32 vfid, u32 opcode,
3447
u64 addr, u32 ndwords)
@@ -48,7 +61,7 @@ static int guc_action_vf_save_restore(struct xe_guc *guc, u32 vfid, u32 opcode,
4861
}
4962

5063
/* Return: size of the state in dwords or a negative error code on failure */
51-
static int pf_send_guc_query_vf_state_size(struct xe_gt *gt, unsigned int vfid)
64+
static int pf_send_guc_query_vf_mig_data_size(struct xe_gt *gt, unsigned int vfid)
5265
{
5366
int ret;
5467

@@ -57,8 +70,8 @@ static int pf_send_guc_query_vf_state_size(struct xe_gt *gt, unsigned int vfid)
5770
}
5871

5972
/* Return: number of state dwords saved or a negative error code on failure */
60-
static int pf_send_guc_save_vf_state(struct xe_gt *gt, unsigned int vfid,
61-
void *dst, size_t size)
73+
static int pf_send_guc_save_vf_mig_data(struct xe_gt *gt, unsigned int vfid,
74+
void *dst, size_t size)
6275
{
6376
const int ndwords = size / sizeof(u32);
6477
struct xe_guc *guc = &gt->uc.guc;
@@ -87,8 +100,8 @@ static int pf_send_guc_save_vf_state(struct xe_gt *gt, unsigned int vfid,
87100
}
88101

89102
/* Return: number of state dwords restored or a negative error code on failure */
90-
static int pf_send_guc_restore_vf_state(struct xe_gt *gt, unsigned int vfid,
91-
const void *src, size_t size)
103+
static int pf_send_guc_restore_vf_mig_data(struct xe_gt *gt, unsigned int vfid,
104+
const void *src, size_t size)
92105
{
93106
const int ndwords = size / sizeof(u32);
94107
struct xe_guc *guc = &gt->uc.guc;
@@ -116,120 +129,66 @@ static bool pf_migration_supported(struct xe_gt *gt)
116129
return xe_sriov_pf_migration_supported(gt_to_xe(gt));
117130
}
118131

119-
static struct mutex *pf_migration_mutex(struct xe_gt *gt)
132+
static int pf_save_vf_guc_mig_data(struct xe_gt *gt, unsigned int vfid)
120133
{
121-
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
122-
return &gt->sriov.pf.migration.snapshot_lock;
123-
}
124-
125-
static struct xe_gt_sriov_state_snapshot *pf_pick_vf_snapshot(struct xe_gt *gt,
126-
unsigned int vfid)
127-
{
128-
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
129-
xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
130-
lockdep_assert_held(pf_migration_mutex(gt));
131-
132-
return &gt->sriov.pf.vfs[vfid].snapshot;
133-
}
134-
135-
static unsigned int pf_snapshot_index(struct xe_gt *gt, struct xe_gt_sriov_state_snapshot *snapshot)
136-
{
137-
return container_of(snapshot, struct xe_gt_sriov_metadata, snapshot) - gt->sriov.pf.vfs;
138-
}
139-
140-
static void pf_free_guc_state(struct xe_gt *gt, struct xe_gt_sriov_state_snapshot *snapshot)
141-
{
142-
struct xe_device *xe = gt_to_xe(gt);
143-
144-
drmm_kfree(&xe->drm, snapshot->guc.buff);
145-
snapshot->guc.buff = NULL;
146-
snapshot->guc.size = 0;
147-
}
148-
149-
static int pf_alloc_guc_state(struct xe_gt *gt,
150-
struct xe_gt_sriov_state_snapshot *snapshot,
151-
size_t size)
152-
{
153-
struct xe_device *xe = gt_to_xe(gt);
154-
void *p;
155-
156-
pf_free_guc_state(gt, snapshot);
157-
158-
if (!size)
159-
return -ENODATA;
160-
161-
if (size % sizeof(u32))
162-
return -EINVAL;
163-
164-
if (size > SZ_2M)
165-
return -EFBIG;
166-
167-
p = drmm_kzalloc(&xe->drm, size, GFP_KERNEL);
168-
if (!p)
169-
return -ENOMEM;
170-
171-
snapshot->guc.buff = p;
172-
snapshot->guc.size = size;
173-
return 0;
174-
}
175-
176-
static void pf_dump_guc_state(struct xe_gt *gt, struct xe_gt_sriov_state_snapshot *snapshot)
177-
{
178-
if (IS_ENABLED(CONFIG_DRM_XE_DEBUG_SRIOV)) {
179-
unsigned int vfid __maybe_unused = pf_snapshot_index(gt, snapshot);
180-
181-
xe_gt_sriov_dbg_verbose(gt, "VF%u GuC state is %zu dwords:\n",
182-
vfid, snapshot->guc.size / sizeof(u32));
183-
print_hex_dump_bytes("state: ", DUMP_PREFIX_OFFSET,
184-
snapshot->guc.buff, min(SZ_64, snapshot->guc.size));
185-
}
186-
}
187-
188-
static int pf_save_vf_guc_state(struct xe_gt *gt, unsigned int vfid)
189-
{
190-
struct xe_gt_sriov_state_snapshot *snapshot = pf_pick_vf_snapshot(gt, vfid);
134+
struct xe_sriov_packet *data;
191135
size_t size;
192136
int ret;
193137

194-
ret = pf_send_guc_query_vf_state_size(gt, vfid);
138+
ret = pf_send_guc_query_vf_mig_data_size(gt, vfid);
195139
if (ret < 0)
196140
goto fail;
141+
197142
size = ret * sizeof(u32);
198-
xe_gt_sriov_dbg_verbose(gt, "VF%u state size is %d dwords (%zu bytes)\n", vfid, ret, size);
199143

200-
ret = pf_alloc_guc_state(gt, snapshot, size);
201-
if (ret < 0)
144+
data = xe_sriov_packet_alloc(gt_to_xe(gt));
145+
if (!data) {
146+
ret = -ENOMEM;
202147
goto fail;
148+
}
149+
150+
ret = xe_sriov_packet_init(data, gt->tile->id, gt->info.id,
151+
XE_SRIOV_PACKET_TYPE_GUC, 0, size);
152+
if (ret)
153+
goto fail_free;
203154

204-
ret = pf_send_guc_save_vf_state(gt, vfid, snapshot->guc.buff, size);
155+
ret = pf_send_guc_save_vf_mig_data(gt, vfid, data->vaddr, size);
205156
if (ret < 0)
206-
goto fail;
157+
goto fail_free;
207158
size = ret * sizeof(u32);
208159
xe_gt_assert(gt, size);
209-
xe_gt_assert(gt, size <= snapshot->guc.size);
210-
snapshot->guc.size = size;
160+
xe_gt_assert(gt, size <= data->hdr.size);
161+
data->hdr.size = size;
162+
data->remaining = size;
163+
164+
pf_dump_mig_data(gt, vfid, data, "GuC data save");
165+
166+
ret = xe_gt_sriov_pf_migration_save_produce(gt, vfid, data);
167+
if (ret)
168+
goto fail_free;
211169

212-
pf_dump_guc_state(gt, snapshot);
213170
return 0;
214171

172+
fail_free:
173+
xe_sriov_packet_free(data);
215174
fail:
216-
xe_gt_sriov_dbg(gt, "Unable to save VF%u state (%pe)\n", vfid, ERR_PTR(ret));
217-
pf_free_guc_state(gt, snapshot);
175+
xe_gt_sriov_err(gt, "Failed to save VF%u GuC data (%pe)\n",
176+
vfid, ERR_PTR(ret));
218177
return ret;
219178
}
220179

221180
/**
222-
* xe_gt_sriov_pf_migration_save_guc_state() - Take a GuC VF state snapshot.
181+
* xe_gt_sriov_pf_migration_guc_size() - Get the size of VF GuC migration data.
223182
* @gt: the &xe_gt
224183
* @vfid: the VF identifier
225184
*
226185
* This function is for PF only.
227186
*
228-
* Return: 0 on success or a negative error code on failure.
187+
* Return: size in bytes or a negative error code on failure.
229188
*/
230-
int xe_gt_sriov_pf_migration_save_guc_state(struct xe_gt *gt, unsigned int vfid)
189+
ssize_t xe_gt_sriov_pf_migration_guc_size(struct xe_gt *gt, unsigned int vfid)
231190
{
232-
int err;
191+
ssize_t size;
233192

234193
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
235194
xe_gt_assert(gt, vfid != PFID);
@@ -238,146 +197,77 @@ int xe_gt_sriov_pf_migration_save_guc_state(struct xe_gt *gt, unsigned int vfid)
238197
if (!pf_migration_supported(gt))
239198
return -ENOPKG;
240199

241-
mutex_lock(pf_migration_mutex(gt));
242-
err = pf_save_vf_guc_state(gt, vfid);
243-
mutex_unlock(pf_migration_mutex(gt));
200+
size = pf_send_guc_query_vf_mig_data_size(gt, vfid);
201+
if (size >= 0)
202+
size *= sizeof(u32);
244203

245-
return err;
246-
}
247-
248-
static int pf_restore_vf_guc_state(struct xe_gt *gt, unsigned int vfid)
249-
{
250-
struct xe_gt_sriov_state_snapshot *snapshot = pf_pick_vf_snapshot(gt, vfid);
251-
int ret;
252-
253-
if (!snapshot->guc.size)
254-
return -ENODATA;
255-
256-
xe_gt_sriov_dbg_verbose(gt, "restoring %zu dwords of VF%u GuC state\n",
257-
snapshot->guc.size / sizeof(u32), vfid);
258-
ret = pf_send_guc_restore_vf_state(gt, vfid, snapshot->guc.buff, snapshot->guc.size);
259-
if (ret < 0)
260-
goto fail;
261-
262-
xe_gt_sriov_dbg_verbose(gt, "restored %d dwords of VF%u GuC state\n", ret, vfid);
263-
return 0;
264-
265-
fail:
266-
xe_gt_sriov_dbg(gt, "Failed to restore VF%u GuC state (%pe)\n", vfid, ERR_PTR(ret));
267-
return ret;
204+
return size;
268205
}
269206

270207
/**
271-
* xe_gt_sriov_pf_migration_restore_guc_state() - Restore a GuC VF state.
208+
* xe_gt_sriov_pf_migration_guc_save() - Save VF GuC migration data.
272209
* @gt: the &xe_gt
273210
* @vfid: the VF identifier
274211
*
275212
* This function is for PF only.
276213
*
277214
* Return: 0 on success or a negative error code on failure.
278215
*/
279-
int xe_gt_sriov_pf_migration_restore_guc_state(struct xe_gt *gt, unsigned int vfid)
216+
int xe_gt_sriov_pf_migration_guc_save(struct xe_gt *gt, unsigned int vfid)
280217
{
281-
int ret;
282-
283218
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
284219
xe_gt_assert(gt, vfid != PFID);
285220
xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
286221

287222
if (!pf_migration_supported(gt))
288223
return -ENOPKG;
289224

290-
mutex_lock(pf_migration_mutex(gt));
291-
ret = pf_restore_vf_guc_state(gt, vfid);
292-
mutex_unlock(pf_migration_mutex(gt));
293-
294-
return ret;
225+
return pf_save_vf_guc_mig_data(gt, vfid);
295226
}
296227

297-
#ifdef CONFIG_DEBUG_FS
298-
/**
299-
* xe_gt_sriov_pf_migration_read_guc_state() - Read a GuC VF state.
300-
* @gt: the &xe_gt
301-
* @vfid: the VF identifier
302-
* @buf: the user space buffer to read to
303-
* @count: the maximum number of bytes to read
304-
* @pos: the current position in the buffer
305-
*
306-
* This function is for PF only.
307-
*
308-
* This function reads up to @count bytes from the saved VF GuC state buffer
309-
* at offset @pos into the user space address starting at @buf.
310-
*
311-
* Return: the number of bytes read or a negative error code on failure.
312-
*/
313-
ssize_t xe_gt_sriov_pf_migration_read_guc_state(struct xe_gt *gt, unsigned int vfid,
314-
char __user *buf, size_t count, loff_t *pos)
228+
static int pf_restore_vf_guc_state(struct xe_gt *gt, unsigned int vfid,
229+
struct xe_sriov_packet *data)
315230
{
316-
struct xe_gt_sriov_state_snapshot *snapshot;
317-
ssize_t ret;
231+
int ret;
318232

319-
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
320-
xe_gt_assert(gt, vfid != PFID);
321-
xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
233+
xe_gt_assert(gt, data->hdr.size);
322234

323-
if (!pf_migration_supported(gt))
324-
return -ENOPKG;
235+
pf_dump_mig_data(gt, vfid, data, "GuC data restore");
325236

326-
mutex_lock(pf_migration_mutex(gt));
327-
snapshot = pf_pick_vf_snapshot(gt, vfid);
328-
if (snapshot->guc.size)
329-
ret = simple_read_from_buffer(buf, count, pos, snapshot->guc.buff,
330-
snapshot->guc.size);
331-
else
332-
ret = -ENODATA;
333-
mutex_unlock(pf_migration_mutex(gt));
237+
ret = pf_send_guc_restore_vf_mig_data(gt, vfid, data->vaddr, data->hdr.size);
238+
if (ret < 0)
239+
goto fail;
240+
241+
return 0;
334242

243+
fail:
244+
xe_gt_sriov_err(gt, "Failed to restore VF%u GuC data (%pe)\n",
245+
vfid, ERR_PTR(ret));
335246
return ret;
336247
}
337248

338249
/**
339-
* xe_gt_sriov_pf_migration_write_guc_state() - Write a GuC VF state.
250+
* xe_gt_sriov_pf_migration_guc_restore() - Restore VF GuC migration data.
340251
* @gt: the &xe_gt
341252
* @vfid: the VF identifier
342-
* @buf: the user space buffer with GuC VF state
343-
* @size: the size of GuC VF state (in bytes)
253+
* @data: the &xe_sriov_packet containing migration data
344254
*
345255
* This function is for PF only.
346256
*
347-
* This function reads @size bytes of the VF GuC state stored at user space
348-
* address @buf and writes it into a internal VF state buffer.
349-
*
350-
* Return: the number of bytes used or a negative error code on failure.
257+
* Return: 0 on success or a negative error code on failure.
351258
*/
352-
ssize_t xe_gt_sriov_pf_migration_write_guc_state(struct xe_gt *gt, unsigned int vfid,
353-
const char __user *buf, size_t size)
259+
int xe_gt_sriov_pf_migration_guc_restore(struct xe_gt *gt, unsigned int vfid,
260+
struct xe_sriov_packet *data)
354261
{
355-
struct xe_gt_sriov_state_snapshot *snapshot;
356-
loff_t pos = 0;
357-
ssize_t ret;
358-
359262
xe_gt_assert(gt, IS_SRIOV_PF(gt_to_xe(gt)));
360263
xe_gt_assert(gt, vfid != PFID);
361264
xe_gt_assert(gt, vfid <= xe_sriov_pf_get_totalvfs(gt_to_xe(gt)));
362265

363266
if (!pf_migration_supported(gt))
364267
return -ENOPKG;
365268

366-
mutex_lock(pf_migration_mutex(gt));
367-
snapshot = pf_pick_vf_snapshot(gt, vfid);
368-
ret = pf_alloc_guc_state(gt, snapshot, size);
369-
if (!ret) {
370-
ret = simple_write_to_buffer(snapshot->guc.buff, size, &pos, buf, size);
371-
if (ret < 0)
372-
pf_free_guc_state(gt, snapshot);
373-
else
374-
pf_dump_guc_state(gt, snapshot);
375-
}
376-
mutex_unlock(pf_migration_mutex(gt));
377-
378-
return ret;
269+
return pf_restore_vf_guc_state(gt, vfid, data);
379270
}
380-
#endif /* CONFIG_DEBUG_FS */
381271

382272
/**
383273
* xe_gt_sriov_pf_migration_size() - Total size of migration data from all components within a GT.
@@ -619,10 +509,6 @@ int xe_gt_sriov_pf_migration_init(struct xe_gt *gt)
619509
if (!pf_migration_supported(gt))
620510
return 0;
621511

622-
err = drmm_mutex_init(&xe->drm, &gt->sriov.pf.migration.snapshot_lock);
623-
if (err)
624-
return err;
625-
626512
totalvfs = xe_sriov_pf_get_totalvfs(xe);
627513
for (n = 1; n <= totalvfs; n++) {
628514
struct xe_gt_sriov_migration_data *migration = pf_pick_gt_migration(gt, n);

0 commit comments

Comments
 (0)