summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'driver/gator_events_irq.c')
-rw-r--r--driver/gator_events_irq.c48
1 files changed, 13 insertions, 35 deletions
diff --git a/driver/gator_events_irq.c b/driver/gator_events_irq.c
index 1221372..b4df7fa 100644
--- a/driver/gator_events_irq.c
+++ b/driver/gator_events_irq.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * Copyright (C) ARM Limited 2010-2012. All rights reserved. 2 * Copyright (C) ARM Limited 2010-2013. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
@@ -18,19 +18,13 @@ static ulong hardirq_enabled;
18static ulong softirq_enabled; 18static ulong softirq_enabled;
19static ulong hardirq_key; 19static ulong hardirq_key;
20static ulong softirq_key; 20static ulong softirq_key;
21static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt); 21static DEFINE_PER_CPU(atomic_t[TOTALIRQ], irqCnt);
22static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet); 22static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet);
23 23
24GATOR_DEFINE_PROBE(irq_handler_exit, 24GATOR_DEFINE_PROBE(irq_handler_exit,
25 TP_PROTO(int irq, struct irqaction *action, int ret)) 25 TP_PROTO(int irq, struct irqaction *action, int ret))
26{ 26{
27 unsigned long flags; 27 atomic_inc(&per_cpu(irqCnt, get_physical_cpu())[HARDIRQ]);
28
29 // disable interrupts to synchronize with gator_events_irq_read()
30 // spinlocks not needed since percpu buffers are used
31 local_irq_save(flags);
32 per_cpu(irqCnt, smp_processor_id())[HARDIRQ]++;
33 local_irq_restore(flags);
34} 28}
35 29
36#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) 30#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)
@@ -39,13 +33,7 @@ GATOR_DEFINE_PROBE(softirq_exit, TP_PROTO(struct softirq_action *h, struct softi
39GATOR_DEFINE_PROBE(softirq_exit, TP_PROTO(unsigned int vec_nr)) 33GATOR_DEFINE_PROBE(softirq_exit, TP_PROTO(unsigned int vec_nr))
40#endif 34#endif
41{ 35{
42 unsigned long flags; 36 atomic_inc(&per_cpu(irqCnt, get_physical_cpu())[SOFTIRQ]);
43
44 // disable interrupts to synchronize with gator_events_irq_read()
45 // spinlocks not needed since percpu buffers are used
46 local_irq_save(flags);
47 per_cpu(irqCnt, smp_processor_id())[SOFTIRQ]++;
48 local_irq_restore(flags);
49} 37}
50 38
51static int gator_events_irq_create_files(struct super_block *sb, struct dentry *root) 39static int gator_events_irq_create_files(struct super_block *sb, struct dentry *root)
@@ -71,24 +59,19 @@ static int gator_events_irq_create_files(struct super_block *sb, struct dentry *
71 return 0; 59 return 0;
72} 60}
73 61
74static int gator_events_irq_online(int **buffer) 62static int gator_events_irq_online(int **buffer, bool migrate)
75{ 63{
76 int len = 0, cpu = smp_processor_id(); 64 int len = 0, cpu = get_physical_cpu();
77 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
78 65
79 // synchronization with the irq_exit functions is not necessary as the values are being reset 66 // synchronization with the irq_exit functions is not necessary as the values are being reset
80 if (hardirq_enabled) { 67 if (hardirq_enabled) {
81 local_irq_save(flags); 68 atomic_set(&per_cpu(irqCnt, cpu)[HARDIRQ], 0);
82 per_cpu(irqCnt, cpu)[HARDIRQ] = 0;
83 local_irq_restore(flags);
84 per_cpu(irqGet, cpu)[len++] = hardirq_key; 69 per_cpu(irqGet, cpu)[len++] = hardirq_key;
85 per_cpu(irqGet, cpu)[len++] = 0; 70 per_cpu(irqGet, cpu)[len++] = 0;
86 } 71 }
87 72
88 if (softirq_enabled) { 73 if (softirq_enabled) {
89 local_irq_save(flags); 74 atomic_set(&per_cpu(irqCnt, cpu)[SOFTIRQ], 0);
90 per_cpu(irqCnt, cpu)[SOFTIRQ] = 0;
91 local_irq_restore(flags);
92 per_cpu(irqGet, cpu)[len++] = softirq_key; 75 per_cpu(irqGet, cpu)[len++] = softirq_key;
93 per_cpu(irqGet, cpu)[len++] = 0; 76 per_cpu(irqGet, cpu)[len++] = 0;
94 } 77 }
@@ -136,26 +119,21 @@ static void gator_events_irq_stop(void)
136 119
137static int gator_events_irq_read(int **buffer) 120static int gator_events_irq_read(int **buffer)
138{ 121{
139 unsigned long flags; // not necessary as we are in interrupt context anyway, but doesn't hurt
140 int len, value; 122 int len, value;
141 int cpu = smp_processor_id(); 123 int cpu = get_physical_cpu();
142 124
143 len = 0; 125 len = 0;
144 if (hardirq_enabled) { 126 if (hardirq_enabled) {
145 local_irq_save(flags); 127 value = atomic_read(&per_cpu(irqCnt, cpu)[HARDIRQ]);
146 value = per_cpu(irqCnt, cpu)[HARDIRQ]; 128 atomic_sub(value, &per_cpu(irqCnt, cpu)[HARDIRQ]);
147 per_cpu(irqCnt, cpu)[HARDIRQ] = 0;
148 local_irq_restore(flags);
149 129
150 per_cpu(irqGet, cpu)[len++] = hardirq_key; 130 per_cpu(irqGet, cpu)[len++] = hardirq_key;
151 per_cpu(irqGet, cpu)[len++] = value; 131 per_cpu(irqGet, cpu)[len++] = value;
152 } 132 }
153 133
154 if (softirq_enabled) { 134 if (softirq_enabled) {
155 local_irq_save(flags); 135 value = atomic_read(&per_cpu(irqCnt, cpu)[SOFTIRQ]);
156 value = per_cpu(irqCnt, cpu)[SOFTIRQ]; 136 atomic_sub(value, &per_cpu(irqCnt, cpu)[SOFTIRQ]);
157 per_cpu(irqCnt, cpu)[SOFTIRQ] = 0;
158 local_irq_restore(flags);
159 137
160 per_cpu(irqGet, cpu)[len++] = softirq_key; 138 per_cpu(irqGet, cpu)[len++] = softirq_key;
161 per_cpu(irqGet, cpu)[len++] = value; 139 per_cpu(irqGet, cpu)[len++] = value;