obj-m := swap_sampler.o
swap_sampler-y := swap_sampler_module.o
+
+ifdef CONFIG_HIGH_RES_TIMERS
+ swap_sampler-y += sampler_hrtimer.o
+else
+ swap_sampler-y += sampler_timer.o
+endif
--- /dev/null
+/*
+ * SWAP sampler
+ * modules/sampler/sampler_hrtimer.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2013
+ *
+ * 2013 Alexander Aksenov <a.aksenov@samsung.com>: SWAP sampler porting
+ *
+ */
+
+
+
+#include <linux/types.h>
+#include "sampler_timers.h"
+
+
+static u64 sampler_timer_quantum = 0;
+static DEFINE_PER_CPU(struct hrtimer, dbi_hrtimer);
+static int dbi_hrtimer_running;
+
+restart_ret sampler_timers_restart(swap_timer *timer)
+{
+ restart_ret ret;
+
+ hrtimer_forward_now(timer, ns_to_ktime(sampler_timer_quantum));
+ ret = HRTIMER_RESTART;
+
+ return ret;
+}
+
+
+void sampler_timers_set_run(void)
+{
+ dbi_hrtimer_running = 1;
+}
+
+
+void sampler_timers_set_stop(void)
+{
+ dbi_hrtimer_running = 0;
+}
+
+
+void sampler_timers_start(void *restart_func)
+{
+ struct hrtimer *hrtimer = &__get_cpu_var(dbi_hrtimer);
+
+ if (!dbi_hrtimer_running)
+ return;
+
+ hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ hrtimer->function = restart_func;
+ hrtimer_start(hrtimer, ns_to_ktime(sampler_timer_quantum),
+ HRTIMER_MODE_REL_PINNED);
+}
+
+
+void sampler_timers_stop(int cpu)
+{
+ struct hrtimer *hrtimer = &per_cpu(dbi_hrtimer, cpu);
+
+ if (!dbi_hrtimer_running)
+ return;
+
+ hrtimer_cancel(hrtimer);
+}
+
+
+void sampler_timers_set_quantum(unsigned int timer_quantum)
+{
+ sampler_timer_quantum = timer_quantum * 1000 * 1000;
+}
--- /dev/null
+/*
+ * SWAP sampler
+ * modules/sampler/sampler_timer.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2013
+ *
+ * 2013 Alexander Aksenov <a.aksenov@samsung.com>: SWAP sampler porting
+ *
+ */
+
+
+
+#include "sampler_timers.h"
+
+
+
+static unsigned long sampler_timer_quantum = 0;
+static DEFINE_PER_CPU(struct timer_list, dbi_timer);
+static int dbi_timer_running;
+
+
+restart_ret sampler_timers_restart(swap_timer *timer)
+{
+ restart_ret ret;
+
+ mod_timer_pinned((struct timer_list *)timer,
+ jiffies + sampler_timer_quantum);
+ ret = 0;
+
+ return ret;
+}
+
+
+void sampler_timers_set_run(void)
+{
+ dbi_timer_running = 1;
+}
+
+
+void sampler_timers_set_stop(void)
+{
+ dbi_timer_running = 0;
+}
+
+
+void sampler_timers_start(void *restart_func)
+{
+ struct timer_list *timer = &__get_cpu_var(dbi_timer);
+
+ if (!dbi_timer_running)
+ return;
+
+ init_timer(timer);
+ timer->data = (unsigned long)timer;
+ timer->function = restart_func;
+
+ mod_timer_pinned(timer, jiffies + sampler_timer_quantum);
+}
+
+
+void sampler_timers_stop(int cpu)
+{
+ struct timer_list *timer = &per_cpu(dbi_timer, cpu);
+
+ if (!dbi_timer_running)
+ return;
+ del_timer_sync(timer);
+}
+
+
+void sampler_timers_set_quantum(unsigned int timer_quantum)
+{
+ sampler_timer_quantum = timer_quantum;
+}
--- /dev/null
+/*
+ * SWAP sampler
+ * modules/sampler/sampler_timers.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) Samsung Electronics, 2013
+ *
+ * 2013 Alexander Aksenov <a.aksenov@samsung.com>: SWAP sampler porting
+ *
+ */
+
+
+
+#ifndef __SAMPLER_TIMERS_H__
+#define __SAMPLER_TIMERS_H__
+
+
+/* ===================== INCLUDE ==================== */
+
+#if defined(CONFIG_HIGH_RES_TIMERS)
+
+#include <linux/hrtimer.h>
+
+#else /* CONFIG_HIGH_RES_TIMERS */
+
+#include <linux/timer.h>
+
+#endif /* CONFIG_HIGH_RES_TIMERS */
+
+/* ==================== TYPE DEFS =================== */
+
+#if defined(CONFIG_HIGH_RES_TIMERS)
+
+typedef struct hrtimer swap_timer;
+typedef enum hrtimer_restart restart_ret;
+
+#else /* CONFIG_HIGH_RES_TIMERS */
+
+typedef struct timer_list swap_timer;
+typedef int restart_ret;
+
+#endif /* CONFIG_HIGH_RES_TIMERS */
+
+
+/* ====================== FUNCS ===================== */
+
+restart_ret sampler_timers_restart(swap_timer *timer);
+void sampler_timers_stop(int cpu);
+void sampler_timers_start(void *unused);
+void sampler_timers_set_quantum(unsigned int timer_quantum);
+void sampler_timers_set_run(void);
+void sampler_timers_set_stop(void);
+
+#endif /* __SAMPLER_TIMERS_H__ */
*
*/
-#include <linux/timer.h>
#include <asm/ptrace.h>
#include <asm/processor.h>
#include <asm/types.h>
#include <linux/jiffies.h>
#include <linux/cpumask.h>
#include <linux/sched.h>
-#include <linux/hrtimer.h>
#include <linux/notifier.h>
#include <linux/kernel.h>
#include <linux/smp.h>
#include "swap_sampler_module.h"
#include "swap_sampler_errors.h"
#include "kernel_operations.h"
+#include "sampler_timers.h"
-unsigned int dbi_timer_quantum = 0;
-
-#ifdef CONFIG_HIGH_RES_TIMERS
-static DEFINE_PER_CPU(struct hrtimer, dbi_hrtimer);
-static int dbi_hrtimer_running;
-#else
-static DEFINE_PER_CPU(struct timer_list, dbi_timer);
-static int dbi_timer_running;
-#endif
-
static BLOCKING_NOTIFIER_HEAD(swap_sampler_notifier_list);
-
-#ifdef CONFIG_HIGH_RES_TIMERS
-static enum hrtimer_restart dbi_hrtimer_notify(struct hrtimer *hrtimer)
+static restart_ret dbi_timer_restart(swap_timer *timer)
{
if (current)
sample_msg(task_pt_regs(current));
- hrtimer_forward_now(hrtimer, ns_to_ktime(dbi_timer_quantum));
-
- return HRTIMER_RESTART;
-}
-
-static void __dbi_hrtimer_start(void *unused)
-{
- struct hrtimer *hrtimer = &__get_cpu_var(dbi_hrtimer);
-
- if (!dbi_hrtimer_running)
- return;
-
- hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- hrtimer->function = dbi_hrtimer_notify;
- hrtimer_start(hrtimer, ns_to_ktime(dbi_timer_quantum),
- HRTIMER_MODE_REL_PINNED);
-}
-
-static int dbi_hrtimer_start(void)
-{
- get_online_cpus();
- dbi_hrtimer_running = 1;
- on_each_cpu(__dbi_hrtimer_start, NULL, 1);
- put_online_cpus();
-
- return E_SS_SUCCESS;
-}
-
-static void __dbi_hrtimer_stop(int cpu)
-{
- struct hrtimer *hrtimer = &per_cpu(dbi_hrtimer, cpu);
-
- if (!dbi_hrtimer_running)
- return;
-
- hrtimer_cancel(hrtimer);
-}
-
-static void dbi_hrtimer_stop(void)
-{
- int cpu;
-
- get_online_cpus();
-
- for_each_online_cpu(cpu)
- __dbi_hrtimer_stop(cpu);
-
- dbi_hrtimer_running = 0;
- put_online_cpus();
-}
-
-#else
-
-void dbi_write_sample_data(unsigned long data)
-{
- struct timer_list *timer = (struct timer_list *)data;
-
- if (current)
- sample_msg(task_pt_regs(current));
-
- /* TODO: test pinning */
- mod_timer_pinned(timer, jiffies + dbi_timer_quantum);
-}
-
-static void __dbi_timer_start(void *unused)
-{
- struct timer_list *timer = &__get_cpu_var(dbi_timer);
-
- if (!dbi_timer_running)
- return;
-
- init_timer(timer);
- timer->data = timer;
- timer->function = dbi_write_sample_data;
-
- /* TODO: test pinning */
- mod_timer_pinned(timer, jiffies + dbi_timer_quantum);
+ return sampler_timers_restart(timer);
}
static int dbi_timer_start(void)
{
get_online_cpus();
- dbi_timer_running = 1;
- on_each_cpu(__dbi_timer_start, NULL, 1);
+ sampler_timers_set_run();
+
+ on_each_cpu(sampler_timers_start, dbi_timer_restart, 1);
put_online_cpus();
return E_SS_SUCCESS;
}
-static void __dbi_timer_stop(int cpu)
-{
- struct timer_list *timer = &per_cpu(dbi_timer, cpu);
-
- if (!dbi_timer_running)
- return;
- del_timer_sync(timer);
-}
-
static void dbi_timer_stop(void)
{
int cpu;
get_online_cpus();
for_each_online_cpu(cpu)
- __dbi_timer_stop(cpu);
-
- dbi_timer_running = 0;
+ sampler_timers_stop(cpu);
+ sampler_timers_set_stop();
put_online_cpus();
}
-#endif
-
static int __cpuinit dbi_cpu_notify(struct notifier_block *self,
unsigned long action, void *hcpu)
{
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
-#ifdef CONFIG_HIGH_RES_TIMERS
- smp_call_function_single(cpu, __dbi_hrtimer_start, NULL, 1);
-#else
- smp_call_function_single(cpu, __dbi_timer_start, NULL, 1);
-#endif
+ smp_call_function_single(cpu, sampler_timers_start,
+ dbi_timer_restart, 1);
break;
case CPU_DEAD:
case CPU_DEAD_FROZEN:
-#ifdef CONFIG_HIGH_RES_TIMERS
- __dbi_hrtimer_stop(cpu);
-#else
- __dbi_timer_stop(cpu);
-#endif
+ sampler_timers_stop(cpu);
break;
}
if (timer_quantum <= 0)
return -EINVAL;
- dbi_timer_quantum = timer_quantum * 1000 * 1000;
-
-#ifdef CONFIG_HIGH_RES_TIMERS
- dbi_hrtimer_start();
-#else
+ sampler_timers_set_quantum(timer_quantum);
dbi_timer_start();
-#endif
return 0;
}
static void do_swap_sampler_stop(void)
{
-#ifdef CONFIG_HIGH_RES_TIMERS
- dbi_hrtimer_stop();
-#else
dbi_timer_stop();
-#endif
}
static DEFINE_MUTEX(mutex_run);