diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/mmiotrace/mmio-mod.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/arch/x86/kernel/mmiotrace/mmio-mod.c b/arch/x86/kernel/mmiotrace/mmio-mod.c index e43947d218a5..0019dcdf6158 100644 --- a/arch/x86/kernel/mmiotrace/mmio-mod.c +++ b/arch/x86/kernel/mmiotrace/mmio-mod.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <asm/pgtable.h> | 29 | #include <asm/pgtable.h> |
30 | #include <linux/mmiotrace.h> | 30 | #include <linux/mmiotrace.h> |
31 | #include <asm/e820.h> /* for ISA_START_ADDRESS */ | 31 | #include <asm/e820.h> /* for ISA_START_ADDRESS */ |
32 | #include <asm/atomic.h> | ||
32 | 33 | ||
33 | #include "kmmio.h" | 34 | #include "kmmio.h" |
34 | #include "pf_in.h" | 35 | #include "pf_in.h" |
@@ -47,9 +48,13 @@ struct trap_reason { | |||
47 | int active_traces; | 48 | int active_traces; |
48 | }; | 49 | }; |
49 | 50 | ||
51 | /* Accessed per-cpu. */ | ||
50 | static struct trap_reason pf_reason[NR_CPUS]; | 52 | static struct trap_reason pf_reason[NR_CPUS]; |
51 | static struct mm_io_header_rw cpu_trace[NR_CPUS]; | 53 | static struct mm_io_header_rw cpu_trace[NR_CPUS]; |
52 | 54 | ||
55 | /* Access to this is not per-cpu. */ | ||
56 | static atomic_t dropped[NR_CPUS]; | ||
57 | |||
53 | static struct file_operations mmio_fops = { | 58 | static struct file_operations mmio_fops = { |
54 | .owner = THIS_MODULE, | 59 | .owner = THIS_MODULE, |
55 | }; | 60 | }; |
@@ -57,7 +62,6 @@ static struct file_operations mmio_fops = { | |||
57 | static const size_t subbuf_size = 256*1024; | 62 | static const size_t subbuf_size = 256*1024; |
58 | static struct rchan *chan; | 63 | static struct rchan *chan; |
59 | static struct dentry *dir; | 64 | static struct dentry *dir; |
60 | static int suspended; /* XXX should this be per cpu? */ | ||
61 | static struct proc_dir_entry *proc_marker_file; | 65 | static struct proc_dir_entry *proc_marker_file; |
62 | 66 | ||
63 | /* module parameters */ | 67 | /* module parameters */ |
@@ -269,19 +273,21 @@ static void post(struct kmmio_probe *p, unsigned long condition, | |||
269 | static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, | 273 | static int subbuf_start_handler(struct rchan_buf *buf, void *subbuf, |
270 | void *prev_subbuf, size_t prev_padding) | 274 | void *prev_subbuf, size_t prev_padding) |
271 | { | 275 | { |
276 | unsigned int cpu = buf->cpu; | ||
277 | atomic_t *drop = &dropped[cpu]; | ||
278 | int count; | ||
272 | if (relay_buf_full(buf)) { | 279 | if (relay_buf_full(buf)) { |
273 | if (!suspended) { | 280 | if (atomic_inc_return(drop) == 1) { |
274 | suspended = 1; | 281 | printk(KERN_ERR MODULE_NAME ": cpu %d buffer full!\n", |
275 | printk(KERN_ERR MODULE_NAME | 282 | cpu); |
276 | ": cpu %d buffer full!!!\n", | ||
277 | smp_processor_id()); | ||
278 | } | 283 | } |
279 | return 0; | 284 | return 0; |
280 | } else if (suspended) { | 285 | } else if ((count = atomic_read(drop))) { |
281 | suspended = 0; | ||
282 | printk(KERN_ERR MODULE_NAME | 286 | printk(KERN_ERR MODULE_NAME |
283 | ": cpu %d buffer no longer full.\n", | 287 | ": cpu %d buffer no longer full, " |
284 | smp_processor_id()); | 288 | "missed %d events.\n", |
289 | cpu, count); | ||
290 | atomic_sub(count, drop); | ||
285 | } | 291 | } |
286 | 292 | ||
287 | return 1; | 293 | return 1; |