4040
4141struct nv_cspmu_ctx {
4242 const char * name ;
43- u32 filter_mask ;
44- u32 filter_default_val ;
43+
4544 struct attribute * * event_attr ;
4645 struct attribute * * format_attr ;
46+
47+ u32 filter_mask ;
48+ u32 filter_default_val ;
49+ u32 filter2_mask ;
50+ u32 filter2_default_val ;
51+
52+ u32 (* get_filter )(const struct perf_event * event );
53+ u32 (* get_filter2 )(const struct perf_event * event );
54+
55+ void * data ;
56+
57+ int (* init_data )(struct arm_cspmu * cspmu );
4758};
4859
4960static struct attribute * scf_pmu_event_attrs [] = {
@@ -144,6 +155,7 @@ static struct attribute *cnvlink_pmu_format_attrs[] = {
144155static struct attribute * generic_pmu_format_attrs [] = {
145156 ARM_CSPMU_FORMAT_EVENT_ATTR ,
146157 ARM_CSPMU_FORMAT_FILTER_ATTR ,
158+ ARM_CSPMU_FORMAT_FILTER2_ATTR ,
147159 NULL ,
148160};
149161
@@ -184,13 +196,36 @@ static u32 nv_cspmu_event_filter(const struct perf_event *event)
184196 return filter_val ;
185197}
186198
199+ static u32 nv_cspmu_event_filter2 (const struct perf_event * event )
200+ {
201+ const struct nv_cspmu_ctx * ctx =
202+ to_nv_cspmu_ctx (to_arm_cspmu (event -> pmu ));
203+
204+ const u32 filter_val = event -> attr .config2 & ctx -> filter2_mask ;
205+
206+ if (filter_val == 0 )
207+ return ctx -> filter2_default_val ;
208+
209+ return filter_val ;
210+ }
211+
187212static void nv_cspmu_set_ev_filter (struct arm_cspmu * cspmu ,
188213 const struct perf_event * event )
189214{
190- u32 filter = nv_cspmu_event_filter (event );
191- u32 offset = PMEVFILTR + (4 * event -> hw .idx );
215+ u32 filter , offset ;
216+ const struct nv_cspmu_ctx * ctx =
217+ to_nv_cspmu_ctx (to_arm_cspmu (event -> pmu ));
218+ offset = 4 * event -> hw .idx ;
192219
193- writel (filter , cspmu -> base0 + offset );
220+ if (ctx -> get_filter ) {
221+ filter = ctx -> get_filter (event );
222+ writel (filter , cspmu -> base0 + PMEVFILTR + offset );
223+ }
224+
225+ if (ctx -> get_filter2 ) {
226+ filter = ctx -> get_filter2 (event );
227+ writel (filter , cspmu -> base0 + PMEVFILT2R + offset );
228+ }
194229}
195230
196231static void nv_cspmu_set_cc_filter (struct arm_cspmu * cspmu ,
@@ -210,74 +245,120 @@ enum nv_cspmu_name_fmt {
210245struct nv_cspmu_match {
211246 u32 prodid ;
212247 u32 prodid_mask ;
213- u64 filter_mask ;
214- u32 filter_default_val ;
215248 const char * name_pattern ;
216249 enum nv_cspmu_name_fmt name_fmt ;
217- struct attribute * * event_attr ;
218- struct attribute * * format_attr ;
250+ struct nv_cspmu_ctx template_ctx ;
251+ struct arm_cspmu_impl_ops ops ;
219252};
220253
221254static const struct nv_cspmu_match nv_cspmu_match [] = {
222255 {
223256 .prodid = 0x10300000 ,
224257 .prodid_mask = NV_PRODID_MASK ,
225- .filter_mask = NV_PCIE_FILTER_ID_MASK ,
226- .filter_default_val = NV_PCIE_FILTER_ID_MASK ,
227258 .name_pattern = "nvidia_pcie_pmu_%u" ,
228259 .name_fmt = NAME_FMT_SOCKET ,
229- .event_attr = mcf_pmu_event_attrs ,
230- .format_attr = pcie_pmu_format_attrs
260+ .template_ctx = {
261+ .event_attr = mcf_pmu_event_attrs ,
262+ .format_attr = pcie_pmu_format_attrs ,
263+ .filter_mask = NV_PCIE_FILTER_ID_MASK ,
264+ .filter_default_val = NV_PCIE_FILTER_ID_MASK ,
265+ .filter2_mask = 0x0 ,
266+ .filter2_default_val = 0x0 ,
267+ .get_filter = nv_cspmu_event_filter ,
268+ .get_filter2 = NULL ,
269+ .data = NULL ,
270+ .init_data = NULL
271+ },
231272 },
232273 {
233274 .prodid = 0x10400000 ,
234275 .prodid_mask = NV_PRODID_MASK ,
235- .filter_mask = NV_NVL_C2C_FILTER_ID_MASK ,
236- .filter_default_val = NV_NVL_C2C_FILTER_ID_MASK ,
237276 .name_pattern = "nvidia_nvlink_c2c1_pmu_%u" ,
238277 .name_fmt = NAME_FMT_SOCKET ,
239- .event_attr = mcf_pmu_event_attrs ,
240- .format_attr = nvlink_c2c_pmu_format_attrs
278+ .template_ctx = {
279+ .event_attr = mcf_pmu_event_attrs ,
280+ .format_attr = nvlink_c2c_pmu_format_attrs ,
281+ .filter_mask = NV_NVL_C2C_FILTER_ID_MASK ,
282+ .filter_default_val = NV_NVL_C2C_FILTER_ID_MASK ,
283+ .filter2_mask = 0x0 ,
284+ .filter2_default_val = 0x0 ,
285+ .get_filter = nv_cspmu_event_filter ,
286+ .get_filter2 = NULL ,
287+ .data = NULL ,
288+ .init_data = NULL
289+ },
241290 },
242291 {
243292 .prodid = 0x10500000 ,
244293 .prodid_mask = NV_PRODID_MASK ,
245- .filter_mask = NV_NVL_C2C_FILTER_ID_MASK ,
246- .filter_default_val = NV_NVL_C2C_FILTER_ID_MASK ,
247294 .name_pattern = "nvidia_nvlink_c2c0_pmu_%u" ,
248295 .name_fmt = NAME_FMT_SOCKET ,
249- .event_attr = mcf_pmu_event_attrs ,
250- .format_attr = nvlink_c2c_pmu_format_attrs
296+ .template_ctx = {
297+ .event_attr = mcf_pmu_event_attrs ,
298+ .format_attr = nvlink_c2c_pmu_format_attrs ,
299+ .filter_mask = NV_NVL_C2C_FILTER_ID_MASK ,
300+ .filter_default_val = NV_NVL_C2C_FILTER_ID_MASK ,
301+ .filter2_mask = 0x0 ,
302+ .filter2_default_val = 0x0 ,
303+ .get_filter = nv_cspmu_event_filter ,
304+ .get_filter2 = NULL ,
305+ .data = NULL ,
306+ .init_data = NULL
307+ },
251308 },
252309 {
253310 .prodid = 0x10600000 ,
254311 .prodid_mask = NV_PRODID_MASK ,
255- .filter_mask = NV_CNVL_FILTER_ID_MASK ,
256- .filter_default_val = NV_CNVL_FILTER_ID_MASK ,
257312 .name_pattern = "nvidia_cnvlink_pmu_%u" ,
258313 .name_fmt = NAME_FMT_SOCKET ,
259- .event_attr = mcf_pmu_event_attrs ,
260- .format_attr = cnvlink_pmu_format_attrs
314+ .template_ctx = {
315+ .event_attr = mcf_pmu_event_attrs ,
316+ .format_attr = cnvlink_pmu_format_attrs ,
317+ .filter_mask = NV_CNVL_FILTER_ID_MASK ,
318+ .filter_default_val = NV_CNVL_FILTER_ID_MASK ,
319+ .filter2_mask = 0x0 ,
320+ .filter2_default_val = 0x0 ,
321+ .get_filter = nv_cspmu_event_filter ,
322+ .get_filter2 = NULL ,
323+ .data = NULL ,
324+ .init_data = NULL
325+ },
261326 },
262327 {
263328 .prodid = 0x2CF00000 ,
264329 .prodid_mask = NV_PRODID_MASK ,
265- .filter_mask = 0x0 ,
266- .filter_default_val = 0x0 ,
267330 .name_pattern = "nvidia_scf_pmu_%u" ,
268331 .name_fmt = NAME_FMT_SOCKET ,
269- .event_attr = scf_pmu_event_attrs ,
270- .format_attr = scf_pmu_format_attrs
332+ .template_ctx = {
333+ .event_attr = scf_pmu_event_attrs ,
334+ .format_attr = scf_pmu_format_attrs ,
335+ .filter_mask = 0x0 ,
336+ .filter_default_val = 0x0 ,
337+ .filter2_mask = 0x0 ,
338+ .filter2_default_val = 0x0 ,
339+ .get_filter = nv_cspmu_event_filter ,
340+ .get_filter2 = NULL ,
341+ .data = NULL ,
342+ .init_data = NULL
343+ },
271344 },
272345 {
273346 .prodid = 0 ,
274347 .prodid_mask = 0 ,
275- .filter_mask = NV_GENERIC_FILTER_ID_MASK ,
276- .filter_default_val = NV_GENERIC_FILTER_ID_MASK ,
277348 .name_pattern = "nvidia_uncore_pmu_%u" ,
278349 .name_fmt = NAME_FMT_GENERIC ,
279- .event_attr = generic_pmu_event_attrs ,
280- .format_attr = generic_pmu_format_attrs
350+ .template_ctx = {
351+ .event_attr = generic_pmu_event_attrs ,
352+ .format_attr = generic_pmu_format_attrs ,
353+ .filter_mask = NV_GENERIC_FILTER_ID_MASK ,
354+ .filter_default_val = NV_GENERIC_FILTER_ID_MASK ,
355+ .filter2_mask = NV_GENERIC_FILTER_ID_MASK ,
356+ .filter2_default_val = NV_GENERIC_FILTER_ID_MASK ,
357+ .get_filter = nv_cspmu_event_filter ,
358+ .get_filter2 = nv_cspmu_event_filter2 ,
359+ .data = NULL ,
360+ .init_data = NULL
361+ },
281362 },
282363};
283364
@@ -310,6 +391,14 @@ static char *nv_cspmu_format_name(const struct arm_cspmu *cspmu,
310391 return name ;
311392}
312393
394+ #define SET_OP (name , impl , match , default_op ) \
395+ do { \
396+ if (match->ops.name) \
397+ impl->name = match->ops.name; \
398+ else if (default_op != NULL) \
399+ impl->name = default_op; \
400+ } while (false)
401+
313402static int nv_cspmu_init_ops (struct arm_cspmu * cspmu )
314403{
315404 struct nv_cspmu_ctx * ctx ;
@@ -330,20 +419,21 @@ static int nv_cspmu_init_ops(struct arm_cspmu *cspmu)
330419 break ;
331420 }
332421
333- ctx -> name = nv_cspmu_format_name (cspmu , match );
334- ctx -> filter_mask = match -> filter_mask ;
335- ctx -> filter_default_val = match -> filter_default_val ;
336- ctx -> event_attr = match -> event_attr ;
337- ctx -> format_attr = match -> format_attr ;
422+ /* Initialize the context with the matched template. */
423+ memcpy (ctx , & match -> template_ctx , sizeof (struct nv_cspmu_ctx ));
424+ ctx -> name = nv_cspmu_format_name (cspmu , match );
338425
339426 cspmu -> impl .ctx = ctx ;
340427
341428 /* NVIDIA specific callbacks. */
342- impl_ops -> set_cc_filter = nv_cspmu_set_cc_filter ;
343- impl_ops -> set_ev_filter = nv_cspmu_set_ev_filter ;
344- impl_ops -> get_event_attrs = nv_cspmu_get_event_attrs ;
345- impl_ops -> get_format_attrs = nv_cspmu_get_format_attrs ;
346- impl_ops -> get_name = nv_cspmu_get_name ;
429+ SET_OP (set_cc_filter , impl_ops , match , nv_cspmu_set_cc_filter );
430+ SET_OP (set_ev_filter , impl_ops , match , nv_cspmu_set_ev_filter );
431+ SET_OP (get_event_attrs , impl_ops , match , nv_cspmu_get_event_attrs );
432+ SET_OP (get_format_attrs , impl_ops , match , nv_cspmu_get_format_attrs );
433+ SET_OP (get_name , impl_ops , match , nv_cspmu_get_name );
434+
435+ if (ctx -> init_data )
436+ return ctx -> init_data (cspmu );
347437
348438 return 0 ;
349439}
0 commit comments