Skip to content

Commit e790789

Browse files
committed
set sampling ratio of dropping for single syscall individually
1 parent c670f57 commit e790789

File tree

20 files changed

+261
-59
lines changed

20 files changed

+261
-59
lines changed

driver/bpf/fillers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4939,7 +4939,7 @@ FILLER(sched_drop, false)
49394939
/*
49404940
* ratio
49414941
*/
4942-
return bpf_push_u32_to_ring(data, data->settings->sampling_ratio);
4942+
return bpf_push_u32_to_ring(data, 0);
49434943
}
49444944

49454945
/* In this kernel version the instruction limit was bumped to 1000000 */

driver/bpf/plumbing_helpers.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ static __always_inline bool drop_event(void *ctx,
493493
struct scap_bpf_settings *settings,
494494
enum syscall_flags drop_flags)
495495
{
496+
long id;
496497
if (!settings->dropping_mode)
497498
return false;
498499

@@ -563,19 +564,25 @@ static __always_inline bool drop_event(void *ctx,
563564
if (drop_flags & UF_ALWAYS_DROP)
564565
return true;
565566

567+
id = bpf_syscall_get_nr(ctx);
568+
if (id < 0 || id >= SYSCALL_TABLE_SIZE)
569+
{
570+
return false;
571+
}
572+
566573
if (state->tail_ctx.ts % 1000000000 >= 1000000000 /
567-
settings->sampling_ratio) {
568-
if (!settings->is_dropping) {
569-
settings->is_dropping = true;
574+
settings->sampling_ratio[id]) {
575+
if (!settings->is_dropping[id]) {
576+
settings->is_dropping[id] = true;
570577
state->tail_ctx.evt_type = PPME_DROP_E;
571578
return false;
572579
}
573580

574581
return true;
575582
}
576583

577-
if (settings->is_dropping) {
578-
settings->is_dropping = false;
584+
if (settings->is_dropping[id]) {
585+
settings->is_dropping[id] = false;
579586
state->tail_ctx.evt_type = PPME_DROP_X;
580587
return false;
581588
}

driver/bpf/types.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,10 @@ struct scap_bpf_settings {
233233
uint64_t boot_time;
234234
void *socket_file_ops;
235235
uint32_t snaplen;
236-
uint32_t sampling_ratio;
236+
uint32_t sampling_ratio[SYSCALL_TABLE_SIZE];
237237
bool do_dynamic_snaplen;
238238
bool dropping_mode;
239-
bool is_dropping;
239+
bool is_dropping[SYSCALL_TABLE_SIZE];
240240
bool drop_failed;
241241
bool tracers_enabled;
242242
uint16_t fullcapture_port_range_start;

driver/main.c

Lines changed: 74 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ static void check_remove_consumer(struct ppm_consumer_t *consumer, int remove_fr
394394
static 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,
16601710
static 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;

driver/modern_bpf/helpers/base/maps_getters.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ static __always_inline bool maps__get_dropping_mode()
3131
return g_settings.dropping_mode;
3232
}
3333

34-
static __always_inline uint32_t maps__get_sampling_ratio()
34+
static __always_inline uint32_t maps__get_sampling_ratio(u32 syscall_id)
3535
{
36-
return g_settings.sampling_ratio;
36+
return g_settings.sampling_ratio[syscall_id];
3737
}
3838

3939
static __always_inline bool maps__get_drop_failed()
@@ -65,14 +65,14 @@ static __always_inline uint16_t maps__get_statsd_port()
6565

6666
/*=============================== KERNEL CONFIGS ===========================*/
6767

68-
static __always_inline bool maps__get_is_dropping()
68+
static __always_inline bool maps__get_is_dropping(u32 syscall_id)
6969
{
70-
return is_dropping;
70+
return is_dropping[syscall_id];
7171
}
7272

73-
static __always_inline void maps__set_is_dropping(bool value)
73+
static __always_inline void maps__set_is_dropping(u32 syscall_id, bool value)
7474
{
75-
is_dropping = value;
75+
is_dropping[syscall_id] = value;
7676
}
7777

7878
/*=============================== KERNEL CONFIGS ===========================*/

driver/modern_bpf/helpers/interfaces/attached_programs.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,28 +55,33 @@ static __always_inline bool sampling_logic(void* ctx, u32 id, enum intrumentatio
5555
return true;
5656
}
5757

58-
if((bpf_ktime_get_boot_ns() % SECOND_TO_NS) >= (SECOND_TO_NS / maps__get_sampling_ratio()))
58+
if (id < 0 || id >= SYSCALL_TABLE_SIZE)
59+
{
60+
return false;
61+
}
62+
63+
if((bpf_ktime_get_boot_ns() % SECOND_TO_NS) >= (SECOND_TO_NS / maps__get_sampling_ratio(id)))
5964
{
6065
/* If we are starting the dropping phase we need to notify the userspace, otherwise, we
6166
* simply drop our event.
6267
* PLEASE NOTE: this logic is not per-CPU so it is best effort!
6368
*/
64-
if(!maps__get_is_dropping())
69+
if(!maps__get_is_dropping(id))
6570
{
6671
/* Here we are not sure we can send the drop_e event to userspace
6772
* if the buffer is full, but this is not essential even if we lose
6873
* an iteration we will synchronize again the next time the logic is enabled.
6974
*/
70-
maps__set_is_dropping(true);
75+
maps__set_is_dropping(id, true);
7176
bpf_tail_call(ctx, &extra_event_prog_tail_table, T1_DROP_E);
7277
bpf_printk("unable to tail call into 'drop_e' prog");
7378
}
7479
return true;
7580
}
7681

77-
if(maps__get_is_dropping())
82+
if(maps__get_is_dropping(id))
7883
{
79-
maps__set_is_dropping(false);
84+
maps__set_is_dropping(id, false);
8085
bpf_tail_call(ctx, &extra_event_prog_tail_table, T1_DROP_X);
8186
bpf_printk("unable to tail call into 'drop_x' prog");
8287
}

driver/modern_bpf/maps/maps.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ __weak struct capture_settings g_settings;
8383
* @brief Variable used only kernel side to understand when we need to send
8484
* `DROP_E` and `DROP_X` events
8585
*/
86-
__weak bool is_dropping;
86+
__weak bool is_dropping[SYSCALL_TABLE_SIZE];
8787

8888
/*=============================== BPF GLOBAL VARIABLES ===============================*/
8989

driver/modern_bpf/programs/tail_called/events/custom_logic/drop.bpf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ int BPF_PROG(t1_drop_e)
2222

2323
/*=============================== COLLECT PARAMETERS ===========================*/
2424

25-
ringbuf__store_u32(&ringbuf, maps__get_sampling_ratio());
25+
ringbuf__store_u32(&ringbuf, 0);
2626

2727
/*=============================== COLLECT PARAMETERS ===========================*/
2828

@@ -47,7 +47,7 @@ int BPF_PROG(t1_drop_x)
4747

4848
/*=============================== COLLECT PARAMETERS ===========================*/
4949

50-
ringbuf__store_u32(&ringbuf, maps__get_sampling_ratio());
50+
ringbuf__store_u32(&ringbuf, 0);
5151

5252
/*=============================== COLLECT PARAMETERS ===========================*/
5353

driver/modern_bpf/shared_definitions/struct_definitions.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818
#define AUXILIARY_MAP_SIZE 128 * 1024
1919

20+
#define SYSCALL_TABLE_SIZE 512
2021
/**
2122
* @brief General settings shared among all the CPUs.
2223
*
@@ -26,7 +27,7 @@ struct capture_settings
2627
uint64_t boot_time; /* boot time. */
2728
uint32_t snaplen; /* we use it when we want to read a maximum size from an event and no more. */
2829
bool dropping_mode; /* this flag actives the sampling logic */
29-
uint32_t sampling_ratio; /* this config tells tracepoints when they have to drop events */
30+
uint32_t sampling_ratio[SYSCALL_TABLE_SIZE]; /* this config tells tracepoints when they have to drop events */
3031
bool drop_failed; /* whether to drop failed syscalls (exit events) */
3132
bool do_dynamic_snaplen; /* enforce snaplen according to the event content */
3233
uint16_t fullcapture_port_range_start; /* first interesting port */

driver/ppm_consumer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ struct ppm_consumer_t {
2121
struct ppm_ring_buffer_context *ring_buffers;
2222
#endif
2323
u32 snaplen;
24-
u32 sampling_ratio;
24+
uint16_t sampling_ratio[SYSCALL_TABLE_SIZE];
2525
bool do_dynamic_snaplen;
26-
u32 sampling_interval;
27-
int is_dropping;
26+
u32 sampling_interval[SYSCALL_TABLE_SIZE];
27+
bool is_dropping[SYSCALL_TABLE_SIZE];
2828
int dropping_mode;
2929
bool drop_failed;
3030
volatile int need_to_insert_drop_e;

0 commit comments

Comments
 (0)