From 7bc232cfcc148b29fbbc23b9b726e95b3c8c0f12 Mon Sep 17 00:00:00 2001 From: Brett Date: Fri, 27 Jan 2017 13:34:48 -0800 Subject: [PATCH 1/6] Basics for kernel 4.10 hotplug support - in progress --- driver/main.c | 98 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 25 deletions(-) diff --git a/driver/main.c b/driver/main.c index fa0d3a2a77..0fd7234d43 100644 --- a/driver/main.c +++ b/driver/main.c @@ -178,11 +178,13 @@ static struct tracepoint *tp_signal_deliver; #ifdef _DEBUG static bool verbose = 1; #else -static bool verbose = 0; +static bool verbose = 1; #endif static unsigned int max_consumers = 5; +static enum cpuhp_state hp_state = 0; + #define vpr_info(fmt, ...) \ do { \ if (verbose) \ @@ -1955,36 +1957,13 @@ static char *ppm_devnode(struct device *dev, mode_t *mode) } #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) */ -/* - * This gets called every time a CPU is added or removed - */ -static int cpu_callback(struct notifier_block *self, unsigned long action, - void *hcpu) +static void do_cpu_callback(long cpu, long sd_action) { - long cpu = (long)hcpu; struct ppm_ring_buffer_context *ring; struct ppm_consumer_t *consumer; bool event_recorded = false; struct timespec ts; struct event_data_t event_data; - long sd_action = 0; - - switch (action) { - case CPU_UP_PREPARE: -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - case CPU_UP_PREPARE_FROZEN: -#endif - sd_action = 1; - break; - case CPU_DOWN_PREPARE: -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) - case CPU_DOWN_PREPARE_FROZEN: -#endif - sd_action = 2; - break; - default: - break; - } /* * Based on the action, spit an event in the first available ring @@ -2010,6 +1989,50 @@ static int cpu_callback(struct notifier_block *self, unsigned long action, rcu_read_unlock(); } +} + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) +static int dyncpu_up(unsigned int cpu) +{ + pr_info("dyncpu_up on cpu %d\n", cpu); + do_cpu_callback(cpu, 1); + return 0; +} + +static int dyncpu_down(unsigned int cpu) +{ + pr_info("dyncpu_down on cpu %d\n", cpu); + do_cpu_callback(cpu, 2); + return 0; +} +#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) */ +/* + * This gets called every time a CPU is added or removed + */ +static int cpu_callback(struct notifier_block *self, unsigned long action, + void *hcpu) +{ + long cpu = (long)hcpu; + long sd_action = 0; + + switch (action) { + case CPU_UP_PREPARE: +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) + case CPU_UP_PREPARE_FROZEN: +#endif + sd_action = 1; + break; + case CPU_DOWN_PREPARE: +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) + case CPU_DOWN_PREPARE_FROZEN: +#endif + sd_action = 2; + break; + default: + break; + } + + do_cpu_callback(cpu, sd_action); return NOTIFY_DONE; } @@ -2018,6 +2041,7 @@ static struct notifier_block cpu_notifier = { .notifier_call = &cpu_callback, .next = NULL, }; +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0) */ int sysdig_init(void) { @@ -2026,6 +2050,7 @@ int sysdig_init(void) unsigned int num_cpus; int ret; int acrret = 0; + int hp_ret; int j; int n_created_devices = 0; #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) @@ -2129,7 +2154,20 @@ int sysdig_init(void) * Set up our callback in case we get a hotplug even while we are * initializing the cpu structures */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) + hp_ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + "sysdig/probe:online", + dyncpu_up, + dyncpu_down); + if (hp_ret <= 0) { + pr_err("error registering cpu hotplug callback\n"); + ret = hp_ret; + goto init_module_err; + } + hp_state = hp_ret; +#else register_cpu_notifier(&cpu_notifier); +#endif /* * All ok. Final initalizations. @@ -2139,6 +2177,11 @@ int sysdig_init(void) return 0; init_module_err: +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) + if (hp_state > 0) + cpuhp_remove_state(hp_state); +#endif + for (j = 0; j < n_created_devices; ++j) { device_destroy(g_ppm_class, g_ppm_devs[j].dev); cdev_del(&g_ppm_devs[j].cdev); @@ -2178,7 +2221,12 @@ void sysdig_exit(void) tracepoint_synchronize_unregister(); #endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) + if (hp_state > 0) + cpuhp_remove_state(hp_state); +#else unregister_cpu_notifier(&cpu_notifier); +#endif } module_init(sysdig_init); From 8a0d8423980b769bd9b99c3a81f9295a7ddd5044 Mon Sep 17 00:00:00 2001 From: Brett Date: Tue, 31 Jan 2017 09:34:34 -0800 Subject: [PATCH 2/6] Further 4.10 support changes, works with 4.10 now, untested pre 4.10 Fixes a bug where enabling a cpu that the module has never seen online will kernel panic. This should exist in the stock version too. (needs testing) --- driver/main.c | 97 ++++++++++++++++++++++++++------------------------- driver/ppm.h | 1 - 2 files changed, 50 insertions(+), 48 deletions(-) diff --git a/driver/main.c b/driver/main.c index 0fd7234d43..aa9f0d0270 100644 --- a/driver/main.c +++ b/driver/main.c @@ -118,6 +118,7 @@ static void record_event_all_consumers(enum ppm_event_type event_type, struct event_data_t *event_datap); static int init_ring_buffer(struct ppm_ring_buffer_context *ring); static void free_ring_buffer(struct ppm_ring_buffer_context *ring); +static void reset_ring_buffer(struct ppm_ring_buffer_context *ring); void ppm_task_cputime_adjusted(struct task_struct *p, cputime_t *ut, cputime_t *st); #ifndef CONFIG_HAVE_SYSCALL_TRACEPOINTS @@ -183,7 +184,9 @@ static bool verbose = 1; static unsigned int max_consumers = 5; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) static enum cpuhp_state hp_state = 0; +#endif #define vpr_info(fmt, ...) \ do { \ @@ -248,9 +251,7 @@ static void check_remove_consumer(struct ppm_consumer_t *consumer, int remove_fr for_each_possible_cpu(cpu) { struct ppm_ring_buffer_context *ring = per_cpu_ptr(consumer->ring_buffers, cpu); - - if (ring->cpu_online) - free_ring_buffer(ring); + free_ring_buffer(ring); } free_percpu(consumer->ring_buffers); @@ -335,7 +336,6 @@ static int ppm_open(struct inode *inode, struct file *filp) for_each_possible_cpu(cpu) { ring = per_cpu_ptr(consumer->ring_buffers, cpu); - ring->cpu_online = false; ring->str_storage = NULL; ring->buffer = NULL; ring->info = NULL; @@ -351,8 +351,6 @@ static int ppm_open(struct inode *inode, struct file *filp) ret = -ENOMEM; goto err_init_ring_buffer; } - - ring->cpu_online = true; } list_add_rcu(&consumer->node, &g_consumer_list); @@ -367,7 +365,7 @@ static int ppm_open(struct inode *inode, struct file *filp) * Check if the CPU pointed by this device is online. If it isn't stop here and * return ENODEV. */ - if (ring->cpu_online == false) { + if (ring->buffer == NULL) { ret = -ENODEV; goto cleanup_open; } @@ -396,16 +394,7 @@ static int ppm_open(struct inode *inode, struct file *filp) consumer->need_to_insert_drop_e = 0; consumer->need_to_insert_drop_x = 0; bitmap_fill(g_events_mask, PPM_EVENT_MAX); /* Enable all syscall to be passed to userspace */ - ring->info->head = 0; - ring->info->tail = 0; - ring->nevents = 0; - ring->info->n_evts = 0; - ring->info->n_drops_buffer = 0; - ring->info->n_drops_pf = 0; - ring->info->n_preemptions = 0; - ring->info->n_context_switches = 0; - ring->capture_enabled = false; - getnstimeofday(&ring->last_print_time); + reset_ring_buffer(ring); ring->open = true; if (!g_tracepoint_registered) { @@ -1813,7 +1802,7 @@ static int init_ring_buffer(struct ppm_ring_buffer_context *ring) ring->str_storage = (char *)__get_free_page(GFP_USER); if (!ring->str_storage) { pr_err("Error allocating the string storage\n"); - goto err_str_storage; + goto init_ring_err; } /* @@ -1824,7 +1813,7 @@ static int init_ring_buffer(struct ppm_ring_buffer_context *ring) ring->buffer = vmalloc(RING_BUF_SIZE + 2 * PAGE_SIZE); if (ring->buffer == NULL) { pr_err("Error allocating ring memory\n"); - goto err_buffer; + goto init_ring_err; } for (j = 0; j < RING_BUF_SIZE + 2 * PAGE_SIZE; j++) @@ -1836,49 +1825,55 @@ static int init_ring_buffer(struct ppm_ring_buffer_context *ring) ring->info = vmalloc(sizeof(struct ppm_ring_buffer_info)); if (ring->info == NULL) { pr_err("Error allocating ring memory\n"); - goto err_ring_info; + goto init_ring_err; } /* * Initialize the buffer info structure */ - ring->open = false; - ring->capture_enabled = false; - ring->info->head = 0; - ring->info->tail = 0; - ring->nevents = 0; - ring->info->n_evts = 0; - ring->info->n_drops_buffer = 0; - ring->info->n_drops_pf = 0; - ring->info->n_preemptions = 0; - ring->info->n_context_switches = 0; + reset_ring_buffer(ring); atomic_set(&ring->preempt_count, 0); - getnstimeofday(&ring->last_print_time); pr_info("CPU buffer initialized, size=%d\n", RING_BUF_SIZE); return 1; -err_ring_info: - vfree((void *)ring->buffer); - ring->buffer = NULL; -err_buffer: - free_page((unsigned long)ring->str_storage); - ring->str_storage = NULL; -err_str_storage: +init_ring_err: + free_ring_buffer(ring); return 0; } static void free_ring_buffer(struct ppm_ring_buffer_context *ring) { - if (ring->info) + if (ring->info) { vfree(ring->info); + ring->info = NULL; + } - if (ring->buffer) + if (ring->buffer) { vfree((void *)ring->buffer); + ring->buffer = NULL; + } - if (ring->str_storage) + if (ring->str_storage) { free_page((unsigned long)ring->str_storage); + ring->str_storage = NULL; + } +} + +static void reset_ring_buffer(struct ppm_ring_buffer_context *ring) +{ + ring->open = false; + ring->capture_enabled = false; + ring->info->head = 0; + ring->info->tail = 0; + ring->nevents = 0; + ring->info->n_evts = 0; + ring->info->n_drops_buffer = 0; + ring->info->n_drops_pf = 0; + ring->info->n_preemptions = 0; + ring->info->n_context_switches = 0; + getnstimeofday(&ring->last_print_time); } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) @@ -1973,16 +1968,24 @@ static void do_cpu_callback(long cpu, long sd_action) list_for_each_entry_rcu(consumer, &g_consumer_list, node) { ring = per_cpu_ptr(consumer->ring_buffers, cpu); - ring->capture_enabled = false; + if (sd_action == 1) { + // XXX we have the consumer list, is it safe + // to access consumers and rings? Need mutex? + if (ring->buffer == NULL) + init_ring_buffer(ring); + ring->capture_enabled = true; + } else if (sd_action == 2) + ring->capture_enabled = false; - getnstimeofday(&ts); + if (!event_recorded) { + getnstimeofday(&ts); - event_data.category = PPMC_CONTEXT_SWITCH; - event_data.event_info.context_data.sched_prev = (void *)cpu; - event_data.event_info.context_data.sched_next = (void *)sd_action; + event_data.category = PPMC_CONTEXT_SWITCH; + event_data.event_info.context_data.sched_prev = (void *)cpu; + event_data.event_info.context_data.sched_next = (void *)sd_action; - if (!event_recorded) { record_event_consumer(consumer, PPME_CPU_HOTPLUG_E, UF_NEVER_DROP, &ts, &event_data); + vpr_info("rercording PPME_CPU_HOTPLUG_E event"); event_recorded = true; } } diff --git a/driver/ppm.h b/driver/ppm.h index b9cd626db6..166edf1390 100644 --- a/driver/ppm.h +++ b/driver/ppm.h @@ -69,7 +69,6 @@ struct syscall_evt_pair { * We have one of these for each CPU. */ struct ppm_ring_buffer_context { - bool cpu_online; bool open; bool capture_enabled; struct ppm_ring_buffer_info *info; From 23b73ed45b77ba4cff51f90fc4dec72e2c8698e9 Mon Sep 17 00:00:00 2001 From: Brett Date: Wed, 1 Feb 2017 13:30:17 -0800 Subject: [PATCH 3/6] Misc fixes and cleanup for hotplug code Switch to nocalls cpuhp variants Hold the consumer mutex when initializing rings in the hotplug callback Record the hotplug event on all consumers Fix pre-4.10 code to use NOTIFY_OK instead of NOTIFY_DONE --- driver/main.c | 92 +++++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/driver/main.c b/driver/main.c index aa9f0d0270..cf36167545 100644 --- a/driver/main.c +++ b/driver/main.c @@ -1863,6 +1863,10 @@ static void free_ring_buffer(struct ppm_ring_buffer_context *ring) static void reset_ring_buffer(struct ppm_ring_buffer_context *ring) { + /* + * ring->preempt_count is not reset to 0 on purpose, to prevent a race condition + * see ppm_open + */ ring->open = false; ring->capture_enabled = false; ring->info->head = 0; @@ -1952,61 +1956,67 @@ static char *ppm_devnode(struct device *dev, mode_t *mode) } #endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) */ -static void do_cpu_callback(long cpu, long sd_action) +static int do_cpu_callback(unsigned long cpu, long sd_action) { struct ppm_ring_buffer_context *ring; struct ppm_consumer_t *consumer; - bool event_recorded = false; - struct timespec ts; struct event_data_t event_data; + int ret = 0; - /* - * Based on the action, spit an event in the first available ring - */ if (sd_action != 0) { + /* + * We need to hold g_consumer_mutex in case we need to init ring + * buffers. Since the loop is computationally cheap, lock the + * whole loop for simplicity and avoiding in-loop lock/unlock cycles + */ + mutex_lock(&g_consumer_mutex); rcu_read_lock(); list_for_each_entry_rcu(consumer, &g_consumer_list, node) { ring = per_cpu_ptr(consumer->ring_buffers, cpu); if (sd_action == 1) { - // XXX we have the consumer list, is it safe - // to access consumers and rings? Need mutex? - if (ring->buffer == NULL) - init_ring_buffer(ring); + if (ring->buffer == NULL) { + if (!init_ring_buffer(ring)) { + /* + * We may have already allocated one or more ring + * buffers for previous consumers in the loop, but it's + * okay to leave them allocated. The undo-up callback + * will disable capture on them + */ + pr_err("can't initialize the ring buffer for CPU %lu\n", cpu); + ret = -ENOMEM; + break; + } + } ring->capture_enabled = true; } else if (sd_action == 2) ring->capture_enabled = false; - - if (!event_recorded) { - getnstimeofday(&ts); - - event_data.category = PPMC_CONTEXT_SWITCH; - event_data.event_info.context_data.sched_prev = (void *)cpu; - event_data.event_info.context_data.sched_next = (void *)sd_action; - - record_event_consumer(consumer, PPME_CPU_HOTPLUG_E, UF_NEVER_DROP, &ts, &event_data); - vpr_info("rercording PPME_CPU_HOTPLUG_E event"); - event_recorded = true; - } } rcu_read_unlock(); + mutex_unlock(&g_consumer_mutex); + + if (ret == 0) { + event_data.category = PPMC_CONTEXT_SWITCH; + event_data.event_info.context_data.sched_prev = (void *)cpu; + event_data.event_info.context_data.sched_next = (void *)sd_action; + record_event_all_consumers(PPME_CPU_HOTPLUG_E, UF_NEVER_DROP, &event_data); + } } + return ret; } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) -static int dyncpu_up(unsigned int cpu) +static int sysdig_cpu_online(unsigned int cpu) { - pr_info("dyncpu_up on cpu %d\n", cpu); - do_cpu_callback(cpu, 1); - return 0; + pr_info("sysdig_cpu_online on cpu %d\n", cpu); + return do_cpu_callback(cpu, 1); } -static int dyncpu_down(unsigned int cpu) +static int sysdig_cpu_offline(unsigned int cpu) { - pr_info("dyncpu_down on cpu %d\n", cpu); - do_cpu_callback(cpu, 2); - return 0; + pr_info("sysdig_cpu_offline on cpu %d\n", cpu); + return do_cpu_callback(cpu, 2); } #else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) */ /* @@ -2015,7 +2025,7 @@ static int dyncpu_down(unsigned int cpu) static int cpu_callback(struct notifier_block *self, unsigned long action, void *hcpu) { - long cpu = (long)hcpu; + unsigned long cpu = (unsigned long)hcpu; long sd_action = 0; switch (action) { @@ -2035,9 +2045,10 @@ static int cpu_callback(struct notifier_block *self, unsigned long action, break; } - do_cpu_callback(cpu, sd_action); - - return NOTIFY_DONE; + if (do_cpu_callback(cpu, sd_action) < 0) + return NOTIFY_BAD; + else + return NOTIFY_OK; } static struct notifier_block cpu_notifier = { @@ -2158,10 +2169,10 @@ int sysdig_init(void) * initializing the cpu structures */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) - hp_ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, + hp_ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "sysdig/probe:online", - dyncpu_up, - dyncpu_down); + sysdig_cpu_online, + sysdig_cpu_offline); if (hp_ret <= 0) { pr_err("error registering cpu hotplug callback\n"); ret = hp_ret; @@ -2180,11 +2191,6 @@ int sysdig_init(void) return 0; init_module_err: -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) - if (hp_state > 0) - cpuhp_remove_state(hp_state); -#endif - for (j = 0; j < n_created_devices; ++j) { device_destroy(g_ppm_class, g_ppm_devs[j].dev); cdev_del(&g_ppm_devs[j].cdev); @@ -2226,7 +2232,7 @@ void sysdig_exit(void) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) if (hp_state > 0) - cpuhp_remove_state(hp_state); + cpuhp_remove_state_nocalls(hp_state); #else unregister_cpu_notifier(&cpu_notifier); #endif From 8c1b3411036b2afe637c68f8142415a7299a5e36 Mon Sep 17 00:00:00 2001 From: Brett Date: Fri, 3 Feb 2017 14:55:54 -0800 Subject: [PATCH 4/6] Fixed pre-4.10 compiler warning --- driver/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/driver/main.c b/driver/main.c index cf36167545..95de979a76 100644 --- a/driver/main.c +++ b/driver/main.c @@ -2064,7 +2064,9 @@ int sysdig_init(void) unsigned int num_cpus; int ret; int acrret = 0; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) int hp_ret; +#endif int j; int n_created_devices = 0; #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) From 1cdea6cf0cbf37c4a6b76b554842de815b25d3bb Mon Sep 17 00:00:00 2001 From: Brett Date: Tue, 7 Feb 2017 10:15:20 -0800 Subject: [PATCH 5/6] Remove potential vmalloc in atomic context This also re-adds cpu_online to fix some logic inconsistencies in using a mix of cpu_online, capture_enabled, and buffer to determine if a CPU is online --- driver/main.c | 64 +++++++++++++++++++++++++-------------------------- driver/ppm.h | 1 + 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/driver/main.c b/driver/main.c index 95de979a76..41d4ac6e84 100644 --- a/driver/main.c +++ b/driver/main.c @@ -336,11 +336,20 @@ static int ppm_open(struct inode *inode, struct file *filp) for_each_possible_cpu(cpu) { ring = per_cpu_ptr(consumer->ring_buffers, cpu); + ring->cpu_online = false; ring->str_storage = NULL; ring->buffer = NULL; ring->info = NULL; } + /* + * If a cpu is offline when the consumer is first created, we + * will never get events for that cpu even if it later comes + * online via hotplug. We could allocate these rings on-demand + * later in this function if needed for hotplug, but that + * requires the consumer to know to call open again, and sysdig + * doesn't support that. + */ for_each_online_cpu(cpu) { ring = per_cpu_ptr(consumer->ring_buffers, cpu); @@ -351,6 +360,8 @@ static int ppm_open(struct inode *inode, struct file *filp) ret = -ENOMEM; goto err_init_ring_buffer; } + + ring->cpu_online = true; } list_add_rcu(&consumer->node, &g_consumer_list); @@ -363,9 +374,11 @@ static int ppm_open(struct inode *inode, struct file *filp) /* * Check if the CPU pointed by this device is online. If it isn't stop here and - * return ENODEV. + * return ENODEV. The cpu could be online while buffer is NULL if there's a cpu + * online hotplug callback between the first open on this consumer and the open + * for this particular device. */ - if (ring->buffer == NULL) { + if (ring->cpu_online == false || ring->buffer == NULL) { ret = -ENODEV; goto cleanup_open; } @@ -1961,49 +1974,34 @@ static int do_cpu_callback(unsigned long cpu, long sd_action) struct ppm_ring_buffer_context *ring; struct ppm_consumer_t *consumer; struct event_data_t event_data; - int ret = 0; if (sd_action != 0) { - /* - * We need to hold g_consumer_mutex in case we need to init ring - * buffers. Since the loop is computationally cheap, lock the - * whole loop for simplicity and avoiding in-loop lock/unlock cycles - */ - mutex_lock(&g_consumer_mutex); rcu_read_lock(); list_for_each_entry_rcu(consumer, &g_consumer_list, node) { ring = per_cpu_ptr(consumer->ring_buffers, cpu); if (sd_action == 1) { - if (ring->buffer == NULL) { - if (!init_ring_buffer(ring)) { - /* - * We may have already allocated one or more ring - * buffers for previous consumers in the loop, but it's - * okay to leave them allocated. The undo-up callback - * will disable capture on them - */ - pr_err("can't initialize the ring buffer for CPU %lu\n", cpu); - ret = -ENOMEM; - break; - } - } - ring->capture_enabled = true; - } else if (sd_action == 2) - ring->capture_enabled = false; + /* + * If the cpu was offline when the consumer was created, + * this won't do anything because we never created a ring + * buffer. We can't safely create one here because we're + * in atomic context, and the consumer needs to call open + * on this device anyways, so do it in ppm_open. + */ + ring->cpu_online = true; + } else if (sd_action == 2) { + ring->cpu_online = false; + } } rcu_read_unlock(); - mutex_unlock(&g_consumer_mutex); - if (ret == 0) { - event_data.category = PPMC_CONTEXT_SWITCH; - event_data.event_info.context_data.sched_prev = (void *)cpu; - event_data.event_info.context_data.sched_next = (void *)sd_action; - record_event_all_consumers(PPME_CPU_HOTPLUG_E, UF_NEVER_DROP, &event_data); - } + event_data.category = PPMC_CONTEXT_SWITCH; + event_data.event_info.context_data.sched_prev = (void *)cpu; + event_data.event_info.context_data.sched_next = (void *)sd_action; + record_event_all_consumers(PPME_CPU_HOTPLUG_E, UF_NEVER_DROP, &event_data); } - return ret; + return 0; } #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) diff --git a/driver/ppm.h b/driver/ppm.h index 166edf1390..b9cd626db6 100644 --- a/driver/ppm.h +++ b/driver/ppm.h @@ -69,6 +69,7 @@ struct syscall_evt_pair { * We have one of these for each CPU. */ struct ppm_ring_buffer_context { + bool cpu_online; bool open; bool capture_enabled; struct ppm_ring_buffer_info *info; From ac3d56b524585b4dd926cdeacd1fa6f717bd0b7f Mon Sep 17 00:00:00 2001 From: Brett Date: Tue, 7 Feb 2017 11:22:23 -0800 Subject: [PATCH 6/6] Fix up debugging code for release --- driver/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/driver/main.c b/driver/main.c index 41d4ac6e84..2c9f16b15f 100644 --- a/driver/main.c +++ b/driver/main.c @@ -179,7 +179,7 @@ static struct tracepoint *tp_signal_deliver; #ifdef _DEBUG static bool verbose = 1; #else -static bool verbose = 1; +static bool verbose = 0; #endif static unsigned int max_consumers = 5; @@ -2007,13 +2007,13 @@ static int do_cpu_callback(unsigned long cpu, long sd_action) #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) static int sysdig_cpu_online(unsigned int cpu) { - pr_info("sysdig_cpu_online on cpu %d\n", cpu); + vpr_info("sysdig_cpu_online on cpu %d\n", cpu); return do_cpu_callback(cpu, 1); } static int sysdig_cpu_offline(unsigned int cpu) { - pr_info("sysdig_cpu_offline on cpu %d\n", cpu); + vpr_info("sysdig_cpu_offline on cpu %d\n", cpu); return do_cpu_callback(cpu, 2); } #else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)) */