@@ -46,15 +46,19 @@ static const char * ops[] = { OPS };
46
46
enum filter_pred_fn {
47
47
FILTER_PRED_FN_NOP ,
48
48
FILTER_PRED_FN_64 ,
49
+ FILTER_PRED_FN_64_CPUMASK ,
49
50
FILTER_PRED_FN_S64 ,
50
51
FILTER_PRED_FN_U64 ,
51
52
FILTER_PRED_FN_32 ,
53
+ FILTER_PRED_FN_32_CPUMASK ,
52
54
FILTER_PRED_FN_S32 ,
53
55
FILTER_PRED_FN_U32 ,
54
56
FILTER_PRED_FN_16 ,
57
+ FILTER_PRED_FN_16_CPUMASK ,
55
58
FILTER_PRED_FN_S16 ,
56
59
FILTER_PRED_FN_U16 ,
57
60
FILTER_PRED_FN_8 ,
61
+ FILTER_PRED_FN_8_CPUMASK ,
58
62
FILTER_PRED_FN_S8 ,
59
63
FILTER_PRED_FN_U8 ,
60
64
FILTER_PRED_FN_COMM ,
@@ -643,6 +647,39 @@ predicate_parse(const char *str, int nr_parens, int nr_preds,
643
647
return ERR_PTR (ret );
644
648
}
645
649
650
+ static inline int
651
+ do_filter_cpumask (int op , const struct cpumask * mask , const struct cpumask * cmp )
652
+ {
653
+ switch (op ) {
654
+ case OP_EQ :
655
+ return cpumask_equal (mask , cmp );
656
+ case OP_NE :
657
+ return !cpumask_equal (mask , cmp );
658
+ case OP_BAND :
659
+ return cpumask_intersects (mask , cmp );
660
+ default :
661
+ return 0 ;
662
+ }
663
+ }
664
+
665
+ /* Optimisation of do_filter_cpumask() for scalar fields */
666
+ static inline int
667
+ do_filter_scalar_cpumask (int op , unsigned int cpu , const struct cpumask * mask )
668
+ {
669
+ switch (op ) {
670
+ case OP_EQ :
671
+ return cpumask_test_cpu (cpu , mask ) &&
672
+ cpumask_nth (1 , mask ) >= nr_cpu_ids ;
673
+ case OP_NE :
674
+ return !cpumask_test_cpu (cpu , mask ) ||
675
+ cpumask_nth (1 , mask ) < nr_cpu_ids ;
676
+ case OP_BAND :
677
+ return cpumask_test_cpu (cpu , mask );
678
+ default :
679
+ return 0 ;
680
+ }
681
+ }
682
+
646
683
enum pred_cmp_types {
647
684
PRED_CMP_TYPE_NOP ,
648
685
PRED_CMP_TYPE_LT ,
@@ -686,6 +723,18 @@ static int filter_pred_##type(struct filter_pred *pred, void *event) \
686
723
} \
687
724
}
688
725
726
+ #define DEFINE_CPUMASK_COMPARISON_PRED (size ) \
727
+ static int filter_pred_##size##_cpumask(struct filter_pred *pred, void *event) \
728
+ { \
729
+ u##size *addr = (u##size *)(event + pred->offset); \
730
+ unsigned int cpu = *addr; \
731
+ \
732
+ if (cpu >= nr_cpu_ids) \
733
+ return 0; \
734
+ \
735
+ return do_filter_scalar_cpumask(pred->op, cpu, pred->mask); \
736
+ }
737
+
689
738
#define DEFINE_EQUALITY_PRED (size ) \
690
739
static int filter_pred_##size(struct filter_pred *pred, void *event) \
691
740
{ \
@@ -707,6 +756,11 @@ DEFINE_COMPARISON_PRED(u16);
707
756
DEFINE_COMPARISON_PRED (s8 );
708
757
DEFINE_COMPARISON_PRED (u8 );
709
758
759
+ DEFINE_CPUMASK_COMPARISON_PRED (64 );
760
+ DEFINE_CPUMASK_COMPARISON_PRED (32 );
761
+ DEFINE_CPUMASK_COMPARISON_PRED (16 );
762
+ DEFINE_CPUMASK_COMPARISON_PRED (8 );
763
+
710
764
DEFINE_EQUALITY_PRED (64 );
711
765
DEFINE_EQUALITY_PRED (32 );
712
766
DEFINE_EQUALITY_PRED (16 );
@@ -891,16 +945,7 @@ static int filter_pred_cpumask(struct filter_pred *pred, void *event)
891
945
const struct cpumask * mask = (event + loc );
892
946
const struct cpumask * cmp = pred -> mask ;
893
947
894
- switch (pred -> op ) {
895
- case OP_EQ :
896
- return cpumask_equal (mask , cmp );
897
- case OP_NE :
898
- return !cpumask_equal (mask , cmp );
899
- case OP_BAND :
900
- return cpumask_intersects (mask , cmp );
901
- default :
902
- return 0 ;
903
- }
948
+ return do_filter_cpumask (pred -> op , mask , cmp );
904
949
}
905
950
906
951
/* Filter predicate for COMM. */
@@ -1351,24 +1396,32 @@ static int filter_pred_fn_call(struct filter_pred *pred, void *event)
1351
1396
switch (pred -> fn_num ) {
1352
1397
case FILTER_PRED_FN_64 :
1353
1398
return filter_pred_64 (pred , event );
1399
+ case FILTER_PRED_FN_64_CPUMASK :
1400
+ return filter_pred_64_cpumask (pred , event );
1354
1401
case FILTER_PRED_FN_S64 :
1355
1402
return filter_pred_s64 (pred , event );
1356
1403
case FILTER_PRED_FN_U64 :
1357
1404
return filter_pred_u64 (pred , event );
1358
1405
case FILTER_PRED_FN_32 :
1359
1406
return filter_pred_32 (pred , event );
1407
+ case FILTER_PRED_FN_32_CPUMASK :
1408
+ return filter_pred_32_cpumask (pred , event );
1360
1409
case FILTER_PRED_FN_S32 :
1361
1410
return filter_pred_s32 (pred , event );
1362
1411
case FILTER_PRED_FN_U32 :
1363
1412
return filter_pred_u32 (pred , event );
1364
1413
case FILTER_PRED_FN_16 :
1365
1414
return filter_pred_16 (pred , event );
1415
+ case FILTER_PRED_FN_16_CPUMASK :
1416
+ return filter_pred_16_cpumask (pred , event );
1366
1417
case FILTER_PRED_FN_S16 :
1367
1418
return filter_pred_s16 (pred , event );
1368
1419
case FILTER_PRED_FN_U16 :
1369
1420
return filter_pred_u16 (pred , event );
1370
1421
case FILTER_PRED_FN_8 :
1371
1422
return filter_pred_8 (pred , event );
1423
+ case FILTER_PRED_FN_8_CPUMASK :
1424
+ return filter_pred_8_cpumask (pred , event );
1372
1425
case FILTER_PRED_FN_S8 :
1373
1426
return filter_pred_s8 (pred , event );
1374
1427
case FILTER_PRED_FN_U8 :
@@ -1606,6 +1659,7 @@ static int parse_pred(const char *str, void *data,
1606
1659
1607
1660
switch (field -> filter_type ) {
1608
1661
case FILTER_CPUMASK :
1662
+ case FILTER_OTHER :
1609
1663
break ;
1610
1664
default :
1611
1665
parse_error (pe , FILT_ERR_ILLEGAL_FIELD_OP , pos + i );
@@ -1658,8 +1712,24 @@ static int parse_pred(const char *str, void *data,
1658
1712
1659
1713
/* Move along */
1660
1714
i ++ ;
1661
- if (field -> filter_type == FILTER_CPUMASK )
1715
+ if (field -> filter_type == FILTER_CPUMASK ) {
1662
1716
pred -> fn_num = FILTER_PRED_FN_CPUMASK ;
1717
+ } else {
1718
+ switch (field -> size ) {
1719
+ case 8 :
1720
+ pred -> fn_num = FILTER_PRED_FN_64_CPUMASK ;
1721
+ break ;
1722
+ case 4 :
1723
+ pred -> fn_num = FILTER_PRED_FN_32_CPUMASK ;
1724
+ break ;
1725
+ case 2 :
1726
+ pred -> fn_num = FILTER_PRED_FN_16_CPUMASK ;
1727
+ break ;
1728
+ case 1 :
1729
+ pred -> fn_num = FILTER_PRED_FN_8_CPUMASK ;
1730
+ break ;
1731
+ }
1732
+ }
1663
1733
1664
1734
/* This is either a string, or an integer */
1665
1735
} else if (str [i ] == '\'' || str [i ] == '"' ) {
0 commit comments