diff options
Diffstat (limited to 'driver/gator_events_irq.c')
-rw-r--r-- | driver/gator_events_irq.c | 48 |
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; | |||
18 | static ulong softirq_enabled; | 18 | static ulong softirq_enabled; |
19 | static ulong hardirq_key; | 19 | static ulong hardirq_key; |
20 | static ulong softirq_key; | 20 | static ulong softirq_key; |
21 | static DEFINE_PER_CPU(int[TOTALIRQ], irqCnt); | 21 | static DEFINE_PER_CPU(atomic_t[TOTALIRQ], irqCnt); |
22 | static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet); | 22 | static DEFINE_PER_CPU(int[TOTALIRQ * 2], irqGet); |
23 | 23 | ||
24 | GATOR_DEFINE_PROBE(irq_handler_exit, | 24 | GATOR_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 | |||
39 | GATOR_DEFINE_PROBE(softirq_exit, TP_PROTO(unsigned int vec_nr)) | 33 | GATOR_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 | ||
51 | static int gator_events_irq_create_files(struct super_block *sb, struct dentry *root) | 39 | static 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 | ||
74 | static int gator_events_irq_online(int **buffer) | 62 | static 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 | ||
137 | static int gator_events_irq_read(int **buffer) | 120 | static 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; |