aboutsummaryrefslogtreecommitdiff
path: root/drivers/gator/gator_events_meminfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gator/gator_events_meminfo.c')
-rw-r--r--drivers/gator/gator_events_meminfo.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/drivers/gator/gator_events_meminfo.c b/drivers/gator/gator_events_meminfo.c
index ad552ef6c6e5..f9dfa9a04eb4 100644
--- a/drivers/gator/gator_events_meminfo.c
+++ b/drivers/gator/gator_events_meminfo.c
@@ -28,6 +28,8 @@ static bool new_data_avail;
static void wq_sched_handler(struct work_struct *wsptr);
DECLARE_WORK(work, wq_sched_handler);
+static struct timer_list meminfo_wake_up_timer;
+static void meminfo_wake_up_handler(unsigned long unused_data);
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 3, 0)
GATOR_DEFINE_PROBE(mm_page_free_direct, TP_PROTO(struct page *page, unsigned int order)) {
@@ -107,6 +109,7 @@ static int gator_events_meminfo_start(void)
if (GATOR_REGISTER_TRACE(mm_page_alloc))
goto mm_page_alloc_exit;
+ setup_timer(&meminfo_wake_up_timer, meminfo_wake_up_handler, 0);
return 0;
mm_page_alloc_exit:
@@ -140,13 +143,15 @@ static void gator_events_meminfo_stop(void)
GATOR_UNREGISTER_TRACE(mm_page_alloc);
}
+ del_timer_sync(&meminfo_wake_up_timer);
+
meminfo_global_enabled = 0;
for (i = 0; i < MEMINFO_TOTAL; i++) {
meminfo_enabled[i] = 0;
}
}
-// Must be run in process context (work queue) as the kernel function si_meminfo() can sleep
+// Must be run in process context as the kernel function si_meminfo() can sleep
static void wq_sched_handler(struct work_struct *wsptr)
{
struct sysinfo info;
@@ -181,6 +186,12 @@ static void wq_sched_handler(struct work_struct *wsptr)
new_data_avail = true;
}
+static void meminfo_wake_up_handler(unsigned long unused_data)
+{
+ // had to delay scheduling work as attempting to schedule work during the context switch is illegal in kernel versions 3.5 and greater
+ schedule_work(&work);
+}
+
static int gator_events_meminfo_read(long long **buffer)
{
static unsigned int last_mem_event = 0;
@@ -190,11 +201,7 @@ static int gator_events_meminfo_read(long long **buffer)
if (last_mem_event != mem_event) {
last_mem_event = mem_event;
- if (in_interrupt()) {
- schedule_work(&work);
- } else {
- wq_sched_handler(NULL);
- }
+ mod_timer(&meminfo_wake_up_timer, jiffies + 1);
}
if (!new_data_avail)