@@ -394,6 +394,7 @@ static void check_remove_consumer(struct ppm_consumer_t *consumer, int remove_fr
394394static int ppm_open (struct inode * inode , struct file * filp )
395395{
396396 int ret ;
397+ int i ;
397398 int in_list = false;
398399#if LINUX_VERSION_CODE > KERNEL_VERSION (2 , 6 , 20 )
399400 int ring_no = iminor (filp -> f_path .dentry -> d_inode );
@@ -531,9 +532,12 @@ static int ppm_open(struct inode *inode, struct file *filp)
531532 */
532533 consumer -> dropping_mode = 0 ;
533534 consumer -> snaplen = SNAPLEN ;
534- consumer -> sampling_ratio = 1 ;
535- consumer -> sampling_interval = 0 ;
536- consumer -> is_dropping = 0 ;
535+ for (i = 0 ; i < SYSCALL_TABLE_SIZE ; i ++ )
536+ {
537+ consumer -> sampling_ratio [i ] = 1 ;
538+ consumer -> sampling_interval [i ] = 0 ;
539+ consumer -> is_dropping [i ] = false;
540+ }
537541 consumer -> do_dynamic_snaplen = false;
538542 consumer -> drop_failed = false;
539543 consumer -> need_to_insert_drop_e = 0 ;
@@ -956,17 +960,23 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
956960 switch (cmd ) {
957961 case PPM_IOCTL_DISABLE_DROPPING_MODE :
958962 {
963+ int i ;
959964 vpr_info ("PPM_IOCTL_DISABLE_DROPPING_MODE, consumer %p\n" , consumer_id );
960965
961966 consumer -> dropping_mode = 0 ;
962- consumer -> sampling_interval = 1000000000 ;
963- consumer -> sampling_ratio = 1 ;
967+ for (i = 0 ; i < SYSCALL_TABLE_SIZE ; i ++ )
968+ {
969+ consumer -> sampling_interval [i ] = 1000000000 ;
970+ consumer -> sampling_ratio [i ] = 1 ;
971+ consumer -> is_dropping [i ] = false;
972+ }
964973
965974 ret = 0 ;
966975 goto cleanup_ioctl ;
967976 }
968977 case PPM_IOCTL_ENABLE_DROPPING_MODE :
969978 {
979+ int i ;
970980 u32 new_sampling_ratio ;
971981
972982 consumer -> dropping_mode = 1 ;
@@ -987,10 +997,13 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
987997 goto cleanup_ioctl ;
988998 }
989999
990- consumer -> sampling_interval = 1000000000 / new_sampling_ratio ;
991- consumer -> sampling_ratio = new_sampling_ratio ;
1000+ for (i = 0 ; i < SYSCALL_TABLE_SIZE ; i ++ )
1001+ {
1002+ consumer -> sampling_interval [i ] = 1000000000 / new_sampling_ratio ;
1003+ consumer -> sampling_ratio [i ] = new_sampling_ratio ;
1004+ }
9921005
993- vpr_info ("new sampling ratio: %d\n" , new_sampling_ratio );
1006+ vpr_info ("new default sampling ratio: %d\n" , new_sampling_ratio );
9941007
9951008 ret = 0 ;
9961009 goto cleanup_ioctl ;
@@ -1186,6 +1199,43 @@ static long ppm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
11861199 ret = 0 ;
11871200 goto cleanup_ioctl ;
11881201 }
1202+ case PPM_IOCTL_SET_DROPPING_RATIO :
1203+ {
1204+ u32 syscall_to_set = (arg >> 32 ) - SYSCALL_TABLE_ID0 ;
1205+ u32 new_sampling_ratio = (u32 )arg ;
1206+
1207+ vpr_info ("PPM_IOCTL_SET_DROPPING_RATIO, syscall(%u), ratio(%u), consumer %p\n" , syscall_to_set , new_sampling_ratio , consumer_id );
1208+
1209+ if (syscall_to_set >= SYSCALL_TABLE_SIZE ) {
1210+ pr_err ("invalid syscall %u\n" , syscall_to_set );
1211+ ret = - EINVAL ;
1212+ goto cleanup_ioctl ;
1213+ }
1214+
1215+ if ((g_syscall_table [syscall_to_set ].flags & (UF_NEVER_DROP | UF_ALWAYS_DROP ))) {
1216+ ret = - EPERM ;
1217+ goto cleanup_ioctl ;
1218+ }
1219+
1220+ if (new_sampling_ratio != 1 &&
1221+ new_sampling_ratio != 2 &&
1222+ new_sampling_ratio != 4 &&
1223+ new_sampling_ratio != 8 &&
1224+ new_sampling_ratio != 16 &&
1225+ new_sampling_ratio != 32 &&
1226+ new_sampling_ratio != 64 &&
1227+ new_sampling_ratio != 128 ) {
1228+ pr_err ("invalid sampling ratio %u\n" , new_sampling_ratio );
1229+ ret = - EINVAL ;
1230+ goto cleanup_ioctl ;
1231+ }
1232+
1233+ consumer -> sampling_interval [syscall_to_set ] = 1000000000 / new_sampling_ratio ;
1234+ consumer -> sampling_ratio [syscall_to_set ] = new_sampling_ratio ;
1235+ pr_info ("new sampling ratio %u, %u\n" , syscall_to_set , new_sampling_ratio );
1236+ ret = 0 ;
1237+ goto cleanup_ioctl ;
1238+ }
11891239 default :
11901240 ret = - ENOTTY ;
11911241 goto cleanup_ioctl ;
@@ -1660,6 +1710,7 @@ static inline int drop_nostate_event(ppm_event_code event_type,
16601710static inline int drop_event (struct ppm_consumer_t * consumer ,
16611711 ppm_event_code event_type ,
16621712 enum syscall_flags drop_flags ,
1713+ long table_index ,
16631714 nanoseconds ns ,
16641715 struct pt_regs * regs )
16651716{
@@ -1682,21 +1733,22 @@ static inline int drop_event(struct ppm_consumer_t *consumer,
16821733 ASSERT ((drop_flags & UF_NEVER_DROP ) == 0 );
16831734 return 1 ;
16841735 }
1736+ if (table_index != -1 ) {
1737+ if (consumer -> sampling_interval [table_index ] < SECOND_IN_NS &&
1738+ /* do_div replaces ns2 with the quotient and returns the remainder */
1739+ do_div (ns2 , SECOND_IN_NS ) >= consumer -> sampling_interval [table_index ]) {
1740+ if (!consumer -> is_dropping [table_index ]) {
1741+ consumer -> is_dropping [table_index ] = true;
1742+ record_drop_e (consumer , ns , drop_flags );
1743+ }
16851744
1686- if (consumer -> sampling_interval < SECOND_IN_NS &&
1687- /* do_div replaces ns2 with the quotient and returns the remainder */
1688- do_div (ns2 , SECOND_IN_NS ) >= consumer -> sampling_interval ) {
1689- if (consumer -> is_dropping == 0 ) {
1690- consumer -> is_dropping = 1 ;
1691- record_drop_e (consumer , ns , drop_flags );
1745+ return 1 ;
16921746 }
16931747
1694- return 1 ;
1695- }
1696-
1697- if (consumer -> is_dropping == 1 ) {
1698- consumer -> is_dropping = 0 ;
1699- record_drop_x (consumer , ns , drop_flags );
1748+ if (consumer -> is_dropping [table_index ]) {
1749+ consumer -> is_dropping [table_index ] = false;
1750+ record_drop_x (consumer , ns , drop_flags );
1751+ }
17001752 }
17011753 }
17021754
@@ -1742,7 +1794,7 @@ static int record_event_consumer(struct ppm_consumer_t *consumer,
17421794 int drop = 1 ;
17431795 int32_t cbres = PPM_SUCCESS ;
17441796 int cpu ;
1745- long table_index ;
1797+ long table_index = -1 ;
17461798 int64_t retval ;
17471799
17481800 if (tp_type < INTERNAL_EVENTS && !(consumer -> tracepoints_attached & (1 << tp_type )))
@@ -1807,6 +1859,7 @@ static int record_event_consumer(struct ppm_consumer_t *consumer,
18071859 if (drop_event (consumer ,
18081860 event_type ,
18091861 drop_flags ,
1862+ table_index ,
18101863 ns ,
18111864 event_datap -> event_info .syscall_data .regs ))
18121865 return res ;
0 commit comments