@@ -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 */
3346static 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 );
215174fail :
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