Blame view

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

bc078e4ea   Martin Schwidefsky   oprofile: convert...
69
70
  static int __cpuinit oprofile_cpu_notify(struct notifier_block *self,
  					 unsigned long action, void *hcpu)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
  {
bc078e4ea   Martin Schwidefsky   oprofile: convert...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
  	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;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
  }
bc078e4ea   Martin Schwidefsky   oprofile: convert...
87
88
89
  static struct notifier_block __refdata oprofile_cpu_notifier = {
  	.notifier_call = oprofile_cpu_notify,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90

75c43a20b   Robert Richter   oprofile: Remove ...
91
  static int oprofile_hrtimer_setup(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  {
75c43a20b   Robert Richter   oprofile: Remove ...
93
  	return register_hotcpu_notifier(&oprofile_cpu_notifier);
bc078e4ea   Martin Schwidefsky   oprofile: convert...
94
  }
75c43a20b   Robert Richter   oprofile: Remove ...
95
  static void oprofile_hrtimer_shutdown(void)
bc078e4ea   Martin Schwidefsky   oprofile: convert...
96
97
  {
  	unregister_hotcpu_notifier(&oprofile_cpu_notifier);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
  }
75c43a20b   Robert Richter   oprofile: Remove ...
99
100
101
102
103
104
105
106
107
108
109
110
111
  
  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;
  }