diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2009-03-31 18:23:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-01 11:59:14 -0400 |
commit | f4112de6b679d84bd9b9681c7504be7bdfb7c7d5 (patch) | |
tree | c9a5665b31e751e1d4255b8c35a6245d5abfa3eb | |
parent | 851a039cc547b33b8139fe6d7c2bbfb158e2724e (diff) |
mm: introduce debug_kmap_atomic
x86 has debug_kmap_atomic_prot() which is error checking function for
kmap_atomic. It is usefull for the other architectures, although it needs
CONFIG_TRACE_IRQFLAGS_SUPPORT.
This patch exposes it to the other architectures.
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/x86/mm/highmem_32.c | 45 | ||||
-rw-r--r-- | include/linux/highmem.h | 12 | ||||
-rw-r--r-- | mm/highmem.c | 45 |
3 files changed, 58 insertions, 44 deletions
diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c index 522db5e3d0bf..8126e8d1a2a4 100644 --- a/arch/x86/mm/highmem_32.c +++ b/arch/x86/mm/highmem_32.c | |||
@@ -19,49 +19,6 @@ void kunmap(struct page *page) | |||
19 | kunmap_high(page); | 19 | kunmap_high(page); |
20 | } | 20 | } |
21 | 21 | ||
22 | static void debug_kmap_atomic_prot(enum km_type type) | ||
23 | { | ||
24 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
25 | static unsigned warn_count = 10; | ||
26 | |||
27 | if (unlikely(warn_count == 0)) | ||
28 | return; | ||
29 | |||
30 | if (unlikely(in_interrupt())) { | ||
31 | if (in_irq()) { | ||
32 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
33 | type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ && | ||
34 | type != KM_BOUNCE_READ) { | ||
35 | WARN_ON(1); | ||
36 | warn_count--; | ||
37 | } | ||
38 | } else if (!irqs_disabled()) { /* softirq */ | ||
39 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
40 | type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 && | ||
41 | type != KM_SKB_SUNRPC_DATA && | ||
42 | type != KM_SKB_DATA_SOFTIRQ && | ||
43 | type != KM_BOUNCE_READ) { | ||
44 | WARN_ON(1); | ||
45 | warn_count--; | ||
46 | } | ||
47 | } | ||
48 | } | ||
49 | |||
50 | if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ || | ||
51 | type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) { | ||
52 | if (!irqs_disabled()) { | ||
53 | WARN_ON(1); | ||
54 | warn_count--; | ||
55 | } | ||
56 | } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) { | ||
57 | if (irq_count() == 0 && !irqs_disabled()) { | ||
58 | WARN_ON(1); | ||
59 | warn_count--; | ||
60 | } | ||
61 | } | ||
62 | #endif | ||
63 | } | ||
64 | |||
65 | /* | 22 | /* |
66 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because | 23 | * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because |
67 | * no global lock is needed and because the kmap code must perform a global TLB | 24 | * no global lock is needed and because the kmap code must perform a global TLB |
@@ -81,7 +38,7 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | |||
81 | if (!PageHighMem(page)) | 38 | if (!PageHighMem(page)) |
82 | return page_address(page); | 39 | return page_address(page); |
83 | 40 | ||
84 | debug_kmap_atomic_prot(type); | 41 | debug_kmap_atomic(type); |
85 | 42 | ||
86 | idx = type + KM_TYPE_NR*smp_processor_id(); | 43 | idx = type + KM_TYPE_NR*smp_processor_id(); |
87 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 44 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); |
diff --git a/include/linux/highmem.h b/include/linux/highmem.h index 13875ce9112a..7ff5c55f9b55 100644 --- a/include/linux/highmem.h +++ b/include/linux/highmem.h | |||
@@ -187,4 +187,16 @@ static inline void copy_highpage(struct page *to, struct page *from) | |||
187 | kunmap_atomic(vto, KM_USER1); | 187 | kunmap_atomic(vto, KM_USER1); |
188 | } | 188 | } |
189 | 189 | ||
190 | #if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_TRACE_IRQFLAGS_SUPPORT) | ||
191 | |||
192 | void debug_kmap_atomic(enum km_type type); | ||
193 | |||
194 | #else | ||
195 | |||
196 | static inline void debug_kmap_atomic(enum km_type type) | ||
197 | { | ||
198 | } | ||
199 | |||
200 | #endif | ||
201 | |||
190 | #endif /* _LINUX_HIGHMEM_H */ | 202 | #endif /* _LINUX_HIGHMEM_H */ |
diff --git a/mm/highmem.c b/mm/highmem.c index 910198037bf5..68eb1d9b63fa 100644 --- a/mm/highmem.c +++ b/mm/highmem.c | |||
@@ -422,3 +422,48 @@ void __init page_address_init(void) | |||
422 | } | 422 | } |
423 | 423 | ||
424 | #endif /* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */ | 424 | #endif /* defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) */ |
425 | |||
426 | #if defined(CONFIG_DEBUG_HIGHMEM) && defined(CONFIG_TRACE_IRQFLAGS_SUPPORT) | ||
427 | |||
428 | void debug_kmap_atomic(enum km_type type) | ||
429 | { | ||
430 | static unsigned warn_count = 10; | ||
431 | |||
432 | if (unlikely(warn_count == 0)) | ||
433 | return; | ||
434 | |||
435 | if (unlikely(in_interrupt())) { | ||
436 | if (in_irq()) { | ||
437 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
438 | type != KM_BIO_SRC_IRQ && type != KM_BIO_DST_IRQ && | ||
439 | type != KM_BOUNCE_READ) { | ||
440 | WARN_ON(1); | ||
441 | warn_count--; | ||
442 | } | ||
443 | } else if (!irqs_disabled()) { /* softirq */ | ||
444 | if (type != KM_IRQ0 && type != KM_IRQ1 && | ||
445 | type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 && | ||
446 | type != KM_SKB_SUNRPC_DATA && | ||
447 | type != KM_SKB_DATA_SOFTIRQ && | ||
448 | type != KM_BOUNCE_READ) { | ||
449 | WARN_ON(1); | ||
450 | warn_count--; | ||
451 | } | ||
452 | } | ||
453 | } | ||
454 | |||
455 | if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ || | ||
456 | type == KM_BIO_SRC_IRQ || type == KM_BIO_DST_IRQ) { | ||
457 | if (!irqs_disabled()) { | ||
458 | WARN_ON(1); | ||
459 | warn_count--; | ||
460 | } | ||
461 | } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) { | ||
462 | if (irq_count() == 0 && !irqs_disabled()) { | ||
463 | WARN_ON(1); | ||
464 | warn_count--; | ||
465 | } | ||
466 | } | ||
467 | } | ||
468 | |||
469 | #endif | ||