Blame view

drivers/oprofile/timer_int.c 2.47 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  /**
   * @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>
bc078e4ea   Martin Schwidefsky   oprofile: convert...
16
17
18
  #include <linux/cpu.h>
  #include <linux/hrtimer.h>
  #include <asm/irq_regs.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
  #include <asm/ptrace.h>
  
  #include "oprof.h"
bc078e4ea   Martin Schwidefsky   oprofile: convert...
22
  static DEFINE_PER_CPU(struct hrtimer, oprofile_hrtimer);
4ac3dbec8   Santosh Shilimkar   oprofile: Fix the...
23
  static int ctr_running;
bc078e4ea   Martin Schwidefsky   oprofile: convert...
24
25
26
27
28
29
30
31
32
33
  
  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)
  {
879d92745   Christoph Lameter   drivers/oprofile:...
34
  	struct hrtimer *hrtimer = this_cpu_ptr(&oprofile_hrtimer);
bc078e4ea   Martin Schwidefsky   oprofile: convert...
35

4ac3dbec8   Santosh Shilimkar   oprofile: Fix the...
36
37
  	if (!ctr_running)
  		return;
bc078e4ea   Martin Schwidefsky   oprofile: convert...
38
39
40
41
42
43
44
45
  	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)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  {
4ac3dbec8   Santosh Shilimkar   oprofile: Fix the...
47
48
  	get_online_cpus();
  	ctr_running = 1;
bc078e4ea   Martin Schwidefsky   oprofile: convert...
49
  	on_each_cpu(__oprofile_hrtimer_start, NULL, 1);
4ac3dbec8   Santosh Shilimkar   oprofile: Fix the...
50
  	put_online_cpus();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
  	return 0;
  }
bc078e4ea   Martin Schwidefsky   oprofile: convert...
53
  static void __oprofile_hrtimer_stop(int cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  {
bc078e4ea   Martin Schwidefsky   oprofile: convert...
55
  	struct hrtimer *hrtimer = &per_cpu(oprofile_hrtimer, cpu);
4ac3dbec8   Santosh Shilimkar   oprofile: Fix the...
56
57
  	if (!ctr_running)
  		return;
bc078e4ea   Martin Schwidefsky   oprofile: convert...
58
  	hrtimer_cancel(hrtimer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
  }
bc078e4ea   Martin Schwidefsky   oprofile: convert...
60
61
62
  static void oprofile_hrtimer_stop(void)
  {
  	int cpu;
4ac3dbec8   Santosh Shilimkar   oprofile: Fix the...
63
  	get_online_cpus();
bc078e4ea   Martin Schwidefsky   oprofile: convert...
64
65
  	for_each_online_cpu(cpu)
  		__oprofile_hrtimer_stop(cpu);
4ac3dbec8   Santosh Shilimkar   oprofile: Fix the...
66
67
  	ctr_running = 0;
  	put_online_cpus();
bc078e4ea   Martin Schwidefsky   oprofile: convert...
68
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69

a4e0591ec   Sebastian Andrzej Siewior   oprofile/timer: C...
70
  static int oprofile_timer_online(unsigned int cpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  {
a4e0591ec   Sebastian Andrzej Siewior   oprofile/timer: C...
72
73
74
75
  	local_irq_disable();
  	__oprofile_hrtimer_start(NULL);
  	local_irq_enable();
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  }
a4e0591ec   Sebastian Andrzej Siewior   oprofile/timer: C...
77
78
79
80
81
82
83
  static int oprofile_timer_prep_down(unsigned int cpu)
  {
  	__oprofile_hrtimer_stop(cpu);
  	return 0;
  }
  
  static enum cpuhp_state hp_online;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

75c43a20b   Robert Richter   oprofile: Remove ...
85
  static int oprofile_hrtimer_setup(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  {
a4e0591ec   Sebastian Andrzej Siewior   oprofile/timer: C...
87
88
89
90
91
92
93
94
95
96
  	int ret;
  
  	ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
  					"oprofile/timer:online",
  					oprofile_timer_online,
  					oprofile_timer_prep_down);
  	if (ret < 0)
  		return ret;
  	hp_online = ret;
  	return 0;
bc078e4ea   Martin Schwidefsky   oprofile: convert...
97
  }
75c43a20b   Robert Richter   oprofile: Remove ...
98
  static void oprofile_hrtimer_shutdown(void)
bc078e4ea   Martin Schwidefsky   oprofile: convert...
99
  {
a4e0591ec   Sebastian Andrzej Siewior   oprofile/timer: C...
100
  	cpuhp_remove_state_nocalls(hp_online);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
  }
75c43a20b   Robert Richter   oprofile: Remove ...
102
103
104
105
106
107
108
109
110
111
112
113
114
  
  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.
  ");
  	return 0;
  }