mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +00:00
![Paul Gortmaker](/assets/img/avatar_default.png)
The __cpuinit type of throwaway sections might have made sense
some time ago when RAM was more constrained, but now the savings
do not offset the cost and complications. For example, the fix in
commit 5e427ec2d0
("x86: Fix bit corruption at CPU resume time")
is a good example of the nasty type of bugs that can be created
with improper use of the various __init prefixes.
After a discussion on LKML[1] it was decided that cpuinit should go
the way of devinit and be phased out. Once all the users are gone,
we can then finally remove the macros themselves from linux/init.h.
This removes all the remaining one-off uses of the __cpuinit macros
from all C files in the drivers/* directory.
[1] https://lkml.org/lkml/2013/5/20/589
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
120 lines
2.5 KiB
C
120 lines
2.5 KiB
C
/**
|
|
* @file timer_int.c
|
|
*
|
|
* @remark Copyright 2002 OProfile authors
|
|
* @remark Read the file COPYING
|
|
*
|
|
* @author John Levon <levon@movementarian.org>
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/notifier.h>
|
|
#include <linux/smp.h>
|
|
#include <linux/oprofile.h>
|
|
#include <linux/profile.h>
|
|
#include <linux/init.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/hrtimer.h>
|
|
#include <asm/irq_regs.h>
|
|
#include <asm/ptrace.h>
|
|
|
|
#include "oprof.h"
|
|
|
|
static DEFINE_PER_CPU(struct hrtimer, oprofile_hrtimer);
|
|
static int ctr_running;
|
|
|
|
static enum hrtimer_restart oprofile_hrtimer_notify(struct hrtimer *hrtimer)
|
|
{
|
|
oprofile_add_sample(get_irq_regs(), 0);
|
|
hrtimer_forward_now(hrtimer, ns_to_ktime(TICK_NSEC));
|
|
return HRTIMER_RESTART;
|
|
}
|
|
|
|
static void __oprofile_hrtimer_start(void *unused)
|
|
{
|
|
struct hrtimer *hrtimer = &__get_cpu_var(oprofile_hrtimer);
|
|
|
|
if (!ctr_running)
|
|
return;
|
|
|
|
hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
|
hrtimer->function = oprofile_hrtimer_notify;
|
|
|
|
hrtimer_start(hrtimer, ns_to_ktime(TICK_NSEC),
|
|
HRTIMER_MODE_REL_PINNED);
|
|
}
|
|
|
|
static int oprofile_hrtimer_start(void)
|
|
{
|
|
get_online_cpus();
|
|
ctr_running = 1;
|
|
on_each_cpu(__oprofile_hrtimer_start, NULL, 1);
|
|
put_online_cpus();
|
|
return 0;
|
|
}
|
|
|
|
static void __oprofile_hrtimer_stop(int cpu)
|
|
{
|
|
struct hrtimer *hrtimer = &per_cpu(oprofile_hrtimer, cpu);
|
|
|
|
if (!ctr_running)
|
|
return;
|
|
|
|
hrtimer_cancel(hrtimer);
|
|
}
|
|
|
|
static void oprofile_hrtimer_stop(void)
|
|
{
|
|
int cpu;
|
|
|
|
get_online_cpus();
|
|
for_each_online_cpu(cpu)
|
|
__oprofile_hrtimer_stop(cpu);
|
|
ctr_running = 0;
|
|
put_online_cpus();
|
|
}
|
|
|
|
static int oprofile_cpu_notify(struct notifier_block *self,
|
|
unsigned long action, void *hcpu)
|
|
{
|
|
long cpu = (long) hcpu;
|
|
|
|
switch (action) {
|
|
case CPU_ONLINE:
|
|
case CPU_ONLINE_FROZEN:
|
|
smp_call_function_single(cpu, __oprofile_hrtimer_start,
|
|
NULL, 1);
|
|
break;
|
|
case CPU_DEAD:
|
|
case CPU_DEAD_FROZEN:
|
|
__oprofile_hrtimer_stop(cpu);
|
|
break;
|
|
}
|
|
return NOTIFY_OK;
|
|
}
|
|
|
|
static struct notifier_block __refdata oprofile_cpu_notifier = {
|
|
.notifier_call = oprofile_cpu_notify,
|
|
};
|
|
|
|
static int oprofile_hrtimer_setup(void)
|
|
{
|
|
return register_hotcpu_notifier(&oprofile_cpu_notifier);
|
|
}
|
|
|
|
static void oprofile_hrtimer_shutdown(void)
|
|
{
|
|
unregister_hotcpu_notifier(&oprofile_cpu_notifier);
|
|
}
|
|
|
|
int oprofile_timer_init(struct oprofile_operations *ops)
|
|
{
|
|
ops->create_files = NULL;
|
|
ops->setup = oprofile_hrtimer_setup;
|
|
ops->shutdown = oprofile_hrtimer_shutdown;
|
|
ops->start = oprofile_hrtimer_start;
|
|
ops->stop = oprofile_hrtimer_stop;
|
|
ops->cpu_type = "timer";
|
|
printk(KERN_INFO "oprofile: using timer interrupt.\n");
|
|
return 0;
|
|
}
|