Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/xe/oa: Add syncs support to OA config ioctl

In addition to stream open, add xe_sync support to the OA config ioctl,
where it is even more useful. This allows e.g. Mesa to replay a workload
repeatedly on the GPU, each time with a different OA configuration, while
precisely controlling (at batch buffer granularity) the workload segment
for which a particular OA configuration is active, without introducing
stalls in the userspace pipeline.

v2: Emit OA config even when config id is same as previous, to ensure
consistent sync behavior (Jose)

Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com>
Signed-off-by: Ashutosh Dixit <ashutosh.dixit@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241022200352.1192560-7-ashutosh.dixit@intel.com

+26 -18
+23 -18
drivers/gpu/drm/xe/xe_oa.c
··· 893 893 xe_gt_WARN_ON(gt, xe_guc_pc_unset_gucrc_mode(&gt->uc.guc.pc)); 894 894 895 895 xe_oa_free_configs(stream); 896 + xe_file_put(stream->xef); 896 897 } 897 898 898 899 static int xe_oa_alloc_oa_buffer(struct xe_oa_stream *stream) ··· 1464 1463 1465 1464 static long xe_oa_config_locked(struct xe_oa_stream *stream, u64 arg) 1466 1465 { 1467 - struct drm_xe_ext_set_property ext; 1466 + struct xe_oa_open_param param = {}; 1468 1467 long ret = stream->oa_config->id; 1469 1468 struct xe_oa_config *config; 1470 1469 int err; 1471 1470 1472 - err = __copy_from_user(&ext, u64_to_user_ptr(arg), sizeof(ext)); 1473 - if (XE_IOCTL_DBG(stream->oa->xe, err)) 1474 - return -EFAULT; 1471 + err = xe_oa_user_extensions(stream->oa, arg, 0, &param); 1472 + if (err) 1473 + return err; 1475 1474 1476 - if (XE_IOCTL_DBG(stream->oa->xe, ext.pad) || 1477 - XE_IOCTL_DBG(stream->oa->xe, ext.base.name != DRM_XE_OA_EXTENSION_SET_PROPERTY) || 1478 - XE_IOCTL_DBG(stream->oa->xe, ext.base.next_extension) || 1479 - XE_IOCTL_DBG(stream->oa->xe, ext.property != DRM_XE_OA_PROPERTY_OA_METRIC_SET)) 1480 - return -EINVAL; 1481 - 1482 - config = xe_oa_get_oa_config(stream->oa, ext.value); 1475 + config = xe_oa_get_oa_config(stream->oa, param.metric_set); 1483 1476 if (!config) 1484 1477 return -ENODEV; 1485 1478 1486 - if (config != stream->oa_config) { 1487 - err = xe_oa_emit_oa_config(stream, config); 1488 - if (!err) 1489 - config = xchg(&stream->oa_config, config); 1490 - else 1491 - ret = err; 1479 + param.xef = stream->xef; 1480 + err = xe_oa_parse_syncs(stream->oa, &param); 1481 + if (err) 1482 + goto err_config_put; 1483 + 1484 + stream->num_syncs = param.num_syncs; 1485 + stream->syncs = param.syncs; 1486 + 1487 + err = xe_oa_emit_oa_config(stream, config); 1488 + if (!err) { 1489 + config = xchg(&stream->oa_config, config); 1490 + drm_dbg(&stream->oa->xe->drm, "changed to oa config uuid=%s\n", 1491 + stream->oa_config->uuid); 1492 1492 } 1493 1493 1494 + err_config_put: 1494 1495 xe_oa_config_put(config); 1495 1496 1496 - return ret; 1497 + return err ?: ret; 1497 1498 } 1498 1499 1499 1500 static long xe_oa_status_locked(struct xe_oa_stream *stream, unsigned long arg) ··· 1737 1734 stream->period_exponent = param->period_exponent; 1738 1735 stream->no_preempt = param->no_preempt; 1739 1736 1737 + stream->xef = xe_file_get(param->xef); 1740 1738 stream->num_syncs = param->num_syncs; 1741 1739 stream->syncs = param->syncs; 1742 1740 ··· 1841 1837 err_free_configs: 1842 1838 xe_oa_free_configs(stream); 1843 1839 exit: 1840 + xe_file_put(stream->xef); 1844 1841 return ret; 1845 1842 } 1846 1843
+3
drivers/gpu/drm/xe/xe_oa_types.h
··· 239 239 /** @no_preempt: Whether preemption and timeslicing is disabled for stream exec_q */ 240 240 u32 no_preempt; 241 241 242 + /** @xef: xe_file with which the stream was opened */ 243 + struct xe_file *xef; 244 + 242 245 /** @last_fence: fence to use in stream destroy when needed */ 243 246 struct dma_fence *last_fence; 244 247