36
36
#include "xe_pm.h"
37
37
#include "xe_sched_job.h"
38
38
#include "xe_sriov.h"
39
+ #include "xe_sync.h"
39
40
40
41
#define DEFAULT_POLL_FREQUENCY_HZ 200
41
42
#define DEFAULT_POLL_PERIOD_NS (NSEC_PER_SEC / DEFAULT_POLL_FREQUENCY_HZ)
@@ -70,6 +71,7 @@ struct flex {
70
71
};
71
72
72
73
struct xe_oa_open_param {
74
+ struct xe_file * xef ;
73
75
u32 oa_unit_id ;
74
76
bool sample ;
75
77
u32 metric_set ;
@@ -81,6 +83,9 @@ struct xe_oa_open_param {
81
83
struct xe_exec_queue * exec_q ;
82
84
struct xe_hw_engine * hwe ;
83
85
bool no_preempt ;
86
+ struct drm_xe_sync __user * syncs_user ;
87
+ int num_syncs ;
88
+ struct xe_sync_entry * syncs ;
84
89
};
85
90
86
91
struct xe_oa_config_bo {
@@ -1398,6 +1403,9 @@ static int xe_oa_stream_init(struct xe_oa_stream *stream,
1398
1403
stream -> period_exponent = param -> period_exponent ;
1399
1404
stream -> no_preempt = param -> no_preempt ;
1400
1405
1406
+ stream -> num_syncs = param -> num_syncs ;
1407
+ stream -> syncs = param -> syncs ;
1408
+
1401
1409
/*
1402
1410
* For Xe2+, when overrun mode is enabled, there are no partial reports at the end
1403
1411
* of buffer, making the OA buffer effectively a non-power-of-2 size circular
@@ -1752,6 +1760,20 @@ static int xe_oa_set_no_preempt(struct xe_oa *oa, u64 value,
1752
1760
return 0 ;
1753
1761
}
1754
1762
1763
+ static int xe_oa_set_prop_num_syncs (struct xe_oa * oa , u64 value ,
1764
+ struct xe_oa_open_param * param )
1765
+ {
1766
+ param -> num_syncs = value ;
1767
+ return 0 ;
1768
+ }
1769
+
1770
+ static int xe_oa_set_prop_syncs_user (struct xe_oa * oa , u64 value ,
1771
+ struct xe_oa_open_param * param )
1772
+ {
1773
+ param -> syncs_user = u64_to_user_ptr (value );
1774
+ return 0 ;
1775
+ }
1776
+
1755
1777
typedef int (* xe_oa_set_property_fn )(struct xe_oa * oa , u64 value ,
1756
1778
struct xe_oa_open_param * param );
1757
1779
static const xe_oa_set_property_fn xe_oa_set_property_funcs [] = {
@@ -1764,6 +1786,8 @@ static const xe_oa_set_property_fn xe_oa_set_property_funcs[] = {
1764
1786
[DRM_XE_OA_PROPERTY_EXEC_QUEUE_ID ] = xe_oa_set_prop_exec_queue_id ,
1765
1787
[DRM_XE_OA_PROPERTY_OA_ENGINE_INSTANCE ] = xe_oa_set_prop_engine_instance ,
1766
1788
[DRM_XE_OA_PROPERTY_NO_PREEMPT ] = xe_oa_set_no_preempt ,
1789
+ [DRM_XE_OA_PROPERTY_NUM_SYNCS ] = xe_oa_set_prop_num_syncs ,
1790
+ [DRM_XE_OA_PROPERTY_SYNCS ] = xe_oa_set_prop_syncs_user ,
1767
1791
};
1768
1792
1769
1793
static int xe_oa_user_ext_set_property (struct xe_oa * oa , u64 extension ,
@@ -1823,6 +1847,49 @@ static int xe_oa_user_extensions(struct xe_oa *oa, u64 extension, int ext_number
1823
1847
return 0 ;
1824
1848
}
1825
1849
1850
+ static int xe_oa_parse_syncs (struct xe_oa * oa , struct xe_oa_open_param * param )
1851
+ {
1852
+ int ret , num_syncs , num_ufence = 0 ;
1853
+
1854
+ if (param -> num_syncs && !param -> syncs_user ) {
1855
+ drm_dbg (& oa -> xe -> drm , "num_syncs specified without sync array\n" );
1856
+ ret = - EINVAL ;
1857
+ goto exit ;
1858
+ }
1859
+
1860
+ if (param -> num_syncs ) {
1861
+ param -> syncs = kcalloc (param -> num_syncs , sizeof (* param -> syncs ), GFP_KERNEL );
1862
+ if (!param -> syncs ) {
1863
+ ret = - ENOMEM ;
1864
+ goto exit ;
1865
+ }
1866
+ }
1867
+
1868
+ for (num_syncs = 0 ; num_syncs < param -> num_syncs ; num_syncs ++ ) {
1869
+ ret = xe_sync_entry_parse (oa -> xe , param -> xef , & param -> syncs [num_syncs ],
1870
+ & param -> syncs_user [num_syncs ], 0 );
1871
+ if (ret )
1872
+ goto err_syncs ;
1873
+
1874
+ if (xe_sync_is_ufence (& param -> syncs [num_syncs ]))
1875
+ num_ufence ++ ;
1876
+ }
1877
+
1878
+ if (XE_IOCTL_DBG (oa -> xe , num_ufence > 1 )) {
1879
+ ret = - EINVAL ;
1880
+ goto err_syncs ;
1881
+ }
1882
+
1883
+ return 0 ;
1884
+
1885
+ err_syncs :
1886
+ while (num_syncs -- )
1887
+ xe_sync_entry_cleanup (& param -> syncs [num_syncs ]);
1888
+ kfree (param -> syncs );
1889
+ exit :
1890
+ return ret ;
1891
+ }
1892
+
1826
1893
/**
1827
1894
* xe_oa_stream_open_ioctl - Opens an OA stream
1828
1895
* @dev: @drm_device
@@ -1848,6 +1915,7 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
1848
1915
return - ENODEV ;
1849
1916
}
1850
1917
1918
+ param .xef = xef ;
1851
1919
ret = xe_oa_user_extensions (oa , data , 0 , & param );
1852
1920
if (ret )
1853
1921
return ret ;
@@ -1916,11 +1984,24 @@ int xe_oa_stream_open_ioctl(struct drm_device *dev, u64 data, struct drm_file *f
1916
1984
drm_dbg (& oa -> xe -> drm , "Using periodic sampling freq %lld Hz\n" , oa_freq_hz );
1917
1985
}
1918
1986
1987
+ ret = xe_oa_parse_syncs (oa , & param );
1988
+ if (ret )
1989
+ goto err_exec_q ;
1990
+
1919
1991
mutex_lock (& param .hwe -> gt -> oa .gt_lock );
1920
1992
ret = xe_oa_stream_open_ioctl_locked (oa , & param );
1921
1993
mutex_unlock (& param .hwe -> gt -> oa .gt_lock );
1994
+ if (ret < 0 )
1995
+ goto err_sync_cleanup ;
1996
+
1997
+ return ret ;
1998
+
1999
+ err_sync_cleanup :
2000
+ while (param .num_syncs -- )
2001
+ xe_sync_entry_cleanup (& param .syncs [param .num_syncs ]);
2002
+ kfree (param .syncs );
1922
2003
err_exec_q :
1923
- if (ret < 0 && param .exec_q )
2004
+ if (param .exec_q )
1924
2005
xe_exec_queue_put (param .exec_q );
1925
2006
return ret ;
1926
2007
}
0 commit comments