* [PATCH 0/4] debug-pagealloc improvements
@ 2011-08-22 16:29 Akinobu Mita
2011-08-22 16:29 ` [PATCH 1/4] debug-pagealloc: use plain __ratelimit() instead of printk_ratelimit() Akinobu Mita
` (3 more replies)
0 siblings, 4 replies; 14+ messages in thread
From: Akinobu Mita @ 2011-08-22 16:29 UTC (permalink / raw)
To: linux-kernel, linux-mm, akpm; +Cc: Akinobu Mita
This patch series includes three improvements for the debug-pagealloc
feature for no-architecture support (!ARCH_SUPPORTS_DEBUG_PAGEALLOC) and
one introduction of the new string library function (memchr_inv).
Akinobu Mita (4):
debug-pagealloc: use plain __ratelimit() instead of
printk_ratelimit()
debug-pagealloc: add support for highmem pages
string: introduce memchr_inv
debug-pagealloc: use memchr_inv
fs/logfs/logfs.h | 1 -
fs/logfs/super.c | 22 --------------
include/linux/string.h | 1 +
lib/string.c | 54 +++++++++++++++++++++++++++++++++++
mm/debug-pagealloc.c | 73 +++++++++++++++++++++++------------------------
mm/slub.c | 47 +-----------------------------
6 files changed, 93 insertions(+), 105 deletions(-)
--
1.7.4.4
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH 1/4] debug-pagealloc: use plain __ratelimit() instead of printk_ratelimit() 2011-08-22 16:29 [PATCH 0/4] debug-pagealloc improvements Akinobu Mita @ 2011-08-22 16:29 ` Akinobu Mita 2011-08-22 16:29 ` [PATCH 2/4] debug-pagealloc: add support for highmem pages Akinobu Mita ` (2 subsequent siblings) 3 siblings, 0 replies; 14+ messages in thread From: Akinobu Mita @ 2011-08-22 16:29 UTC (permalink / raw) To: linux-kernel, linux-mm, akpm; +Cc: Akinobu Mita printk_ratelimit() should not be used, because it shares ratelimiting state with all other unrelated printk_ratelimit() callsites. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> --- mm/debug-pagealloc.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/mm/debug-pagealloc.c b/mm/debug-pagealloc.c index a1e3324..a4b6d70 100644 --- a/mm/debug-pagealloc.c +++ b/mm/debug-pagealloc.c @@ -2,6 +2,7 @@ #include <linux/mm.h> #include <linux/page-debug-flags.h> #include <linux/poison.h> +#include <linux/ratelimit.h> static inline void set_page_poison(struct page *page) { @@ -59,6 +60,7 @@ static bool single_bit_flip(unsigned char a, unsigned char b) static void check_poison_mem(unsigned char *mem, size_t bytes) { + static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 10); unsigned char *start; unsigned char *end; @@ -74,7 +76,7 @@ static void check_poison_mem(unsigned char *mem, size_t bytes) break; } - if (!printk_ratelimit()) + if (!__ratelimit(&ratelimit)) return; else if (start == end && single_bit_flip(*start, PAGE_POISON)) printk(KERN_ERR "pagealloc: single bit error\n"); -- 1.7.4.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH 2/4] debug-pagealloc: add support for highmem pages 2011-08-22 16:29 [PATCH 0/4] debug-pagealloc improvements Akinobu Mita 2011-08-22 16:29 ` [PATCH 1/4] debug-pagealloc: use plain __ratelimit() instead of printk_ratelimit() Akinobu Mita @ 2011-08-22 16:29 ` Akinobu Mita 2011-08-22 20:43 ` Andrew Morton 2011-08-22 16:29 ` [PATCH 3/4] string: introduce memchr_inv Akinobu Mita 2011-08-22 16:29 ` [PATCH 4/4] debug-pagealloc: use memchr_inv Akinobu Mita 3 siblings, 1 reply; 14+ messages in thread From: Akinobu Mita @ 2011-08-22 16:29 UTC (permalink / raw) To: linux-kernel, linux-mm, akpm; +Cc: Akinobu Mita This adds support for highmem pages poisoning and verification to the debug-pagealloc feature for no-architecture support. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> --- mm/debug-pagealloc.c | 61 ++++++++++++++++++++++++------------------------- 1 files changed, 30 insertions(+), 31 deletions(-) diff --git a/mm/debug-pagealloc.c b/mm/debug-pagealloc.c index a4b6d70..5afe80c 100644 --- a/mm/debug-pagealloc.c +++ b/mm/debug-pagealloc.c @@ -1,5 +1,6 @@ #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/highmem.h> #include <linux/page-debug-flags.h> #include <linux/poison.h> #include <linux/ratelimit.h> @@ -19,28 +20,25 @@ static inline bool page_poison(struct page *page) return test_bit(PAGE_DEBUG_FLAG_POISON, &page->debug_flags); } -static void poison_highpage(struct page *page) -{ - /* - * Page poisoning for highmem pages is not implemented. - * - * This can be called from interrupt contexts. - * So we need to create a new kmap_atomic slot for this - * application and it will need interrupt protection. - */ -} - static void poison_page(struct page *page) { void *addr; - - if (PageHighMem(page)) { - poison_highpage(page); - return; + unsigned long flags; + bool highmem = PageHighMem(page); + + if (highmem) { + local_irq_save(flags); + addr = kmap_atomic(page); + } else { + addr = page_address(page); } set_page_poison(page); - addr = page_address(page); memset(addr, PAGE_POISON, PAGE_SIZE); + + if (highmem) { + kunmap_atomic(addr); + local_irq_restore(flags); + } } static void poison_pages(struct page *page, int n) @@ -88,26 +86,27 @@ static void check_poison_mem(unsigned char *mem, size_t bytes) dump_stack(); } -static void unpoison_highpage(struct page *page) -{ - /* - * See comment in poison_highpage(). - * Highmem pages should not be poisoned for now - */ - BUG_ON(page_poison(page)); -} - static void unpoison_page(struct page *page) { - if (PageHighMem(page)) { - unpoison_highpage(page); + void *addr; + unsigned long flags; + bool highmem = PageHighMem(page); + + if (!page_poison(page)) return; + + if (highmem) { + local_irq_save(flags); + addr = kmap_atomic(page); + } else { + addr = page_address(page); } - if (page_poison(page)) { - void *addr = page_address(page); + check_poison_mem(addr, PAGE_SIZE); + clear_page_poison(page); - check_poison_mem(addr, PAGE_SIZE); - clear_page_poison(page); + if (highmem) { + kunmap_atomic(addr); + local_irq_restore(flags); } } -- 1.7.4.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 2/4] debug-pagealloc: add support for highmem pages 2011-08-22 16:29 ` [PATCH 2/4] debug-pagealloc: add support for highmem pages Akinobu Mita @ 2011-08-22 20:43 ` Andrew Morton 2011-08-23 15:26 ` Akinobu Mita 0 siblings, 1 reply; 14+ messages in thread From: Andrew Morton @ 2011-08-22 20:43 UTC (permalink / raw) To: Akinobu Mita; +Cc: linux-kernel, linux-mm On Tue, 23 Aug 2011 01:29:06 +0900 Akinobu Mita <akinobu.mita@gmail.com> wrote: > This adds support for highmem pages poisoning and verification to the > debug-pagealloc feature for no-architecture support. > > ... > > static void poison_page(struct page *page) > { > void *addr; > - > - if (PageHighMem(page)) { > - poison_highpage(page); > - return; > + unsigned long flags; > + bool highmem = PageHighMem(page); > + > + if (highmem) { > + local_irq_save(flags); > + addr = kmap_atomic(page); > + } else { > + addr = page_address(page); > } > set_page_poison(page); > - addr = page_address(page); > memset(addr, PAGE_POISON, PAGE_SIZE); > + > + if (highmem) { > + kunmap_atomic(addr); > + local_irq_restore(flags); > + } > } This seems more complicated than is needed. Couldn't we just do static void poison_page(struct page *page) { void *addr; preempt_disable(); addr = kmap_atomic(page); set_page_poison(page); memset(addr, PAGE_POISON, PAGE_SIZE); kunmap_atomic(addr); preempt_enable(); } ? > + addr = kmap_atomic(page); That reminds me - we need to convert every "kmap_atomic(p, foo)" to "kmap_atomic(p)" then remove the kmap_atomic back-compatibility macro. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 2/4] debug-pagealloc: add support for highmem pages 2011-08-22 20:43 ` Andrew Morton @ 2011-08-23 15:26 ` Akinobu Mita 0 siblings, 0 replies; 14+ messages in thread From: Akinobu Mita @ 2011-08-23 15:26 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-kernel, linux-mm 2011/8/23 Andrew Morton <akpm@linux-foundation.org>: > This seems more complicated than is needed. Couldn't we just do > > static void poison_page(struct page *page) > { > void *addr; > > preempt_disable(); > addr = kmap_atomic(page); > set_page_poison(page); > memset(addr, PAGE_POISON, PAGE_SIZE); > kunmap_atomic(addr); > preempt_enable(); > } > > ? This code looks much better. I'll update the patch. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 3/4] string: introduce memchr_inv 2011-08-22 16:29 [PATCH 0/4] debug-pagealloc improvements Akinobu Mita 2011-08-22 16:29 ` [PATCH 1/4] debug-pagealloc: use plain __ratelimit() instead of printk_ratelimit() Akinobu Mita 2011-08-22 16:29 ` [PATCH 2/4] debug-pagealloc: add support for highmem pages Akinobu Mita @ 2011-08-22 16:29 ` Akinobu Mita 2011-08-22 16:57 ` Pekka Enberg ` (2 more replies) 2011-08-22 16:29 ` [PATCH 4/4] debug-pagealloc: use memchr_inv Akinobu Mita 3 siblings, 3 replies; 14+ messages in thread From: Akinobu Mita @ 2011-08-22 16:29 UTC (permalink / raw) To: linux-kernel, linux-mm, akpm Cc: Akinobu Mita, Christoph Lameter, Pekka Enberg, Matt Mackall, Joern Engel, logfs, Marcin Slusarz, Eric Dumazet memchr_inv() is mainly used to check whether the whole buffer is filled with just a specified byte. The function name and prototype are stolen from logfs and the implementation is from SLUB. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: Pekka Enberg <penberg@kernel.org> Cc: Matt Mackall <mpm@selenic.com> Cc: linux-mm@kvack.org Cc: Joern Engel <joern@logfs.org> Cc: logfs@logfs.org Cc: Marcin Slusarz <marcin.slusarz@gmail.com> Cc: Eric Dumazet <eric.dumazet@gmail.com> --- fs/logfs/logfs.h | 1 - fs/logfs/super.c | 22 ------------------- include/linux/string.h | 1 + lib/string.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ mm/slub.c | 47 +---------------------------------------- 5 files changed, 57 insertions(+), 68 deletions(-) diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index f22d108..398ecff 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h @@ -618,7 +618,6 @@ static inline int logfs_buf_recover(struct logfs_area *area, u64 ofs, struct page *emergency_read_begin(struct address_space *mapping, pgoff_t index); void emergency_read_end(struct page *page); void logfs_crash_dump(struct super_block *sb); -void *memchr_inv(const void *s, int c, size_t n); int logfs_statfs(struct dentry *dentry, struct kstatfs *stats); int logfs_check_ds(struct logfs_disk_super *ds); int logfs_write_sb(struct super_block *sb); diff --git a/fs/logfs/super.c b/fs/logfs/super.c index ce03a18..f2697e4 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c @@ -91,28 +91,6 @@ void logfs_crash_dump(struct super_block *sb) } /* - * TODO: move to lib/string.c - */ -/** - * memchr_inv - Find a character in an area of memory. - * @s: The memory area - * @c: The byte to search for - * @n: The size of the area. - * - * returns the address of the first character other than @c, or %NULL - * if the whole buffer contains just @c. - */ -void *memchr_inv(const void *s, int c, size_t n) -{ - const unsigned char *p = s; - while (n-- != 0) - if ((unsigned char)c != *p++) - return (void *)(p - 1); - - return NULL; -} - -/* * FIXME: There should be a reserve for root, similar to ext2. */ int logfs_statfs(struct dentry *dentry, struct kstatfs *stats) diff --git a/include/linux/string.h b/include/linux/string.h index a176db2..e033564 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -114,6 +114,7 @@ extern int memcmp(const void *,const void *,__kernel_size_t); #ifndef __HAVE_ARCH_MEMCHR extern void * memchr(const void *,int,__kernel_size_t); #endif +void *memchr_inv(const void *s, int c, size_t n); extern char *kstrdup(const char *s, gfp_t gfp); extern char *kstrndup(const char *s, size_t len, gfp_t gfp); diff --git a/lib/string.c b/lib/string.c index 01fad9b..18f5111 100644 --- a/lib/string.c +++ b/lib/string.c @@ -756,3 +756,57 @@ void *memchr(const void *s, int c, size_t n) } EXPORT_SYMBOL(memchr); #endif + +static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes) +{ + while (bytes) { + if (*start != value) + return (void *)start; + start++; + bytes--; + } + return NULL; +} + +/** + * memchr_inv - Find a character in an area of memory. + * @s: The memory area + * @c: The byte to search for + * @n: The size of the area. + * + * returns the address of the first character other than @c, or %NULL + * if the whole buffer contains just @c. + */ +void *memchr_inv(const void *start, int c, size_t bytes) +{ + u8 value = c; + u64 value64; + unsigned int words, prefix; + + if (bytes <= 16) + return check_bytes8(start, value, bytes); + + value64 = value | value << 8 | value << 16 | value << 24; + value64 = (value64 & 0xffffffff) | value64 << 32; + prefix = 8 - ((unsigned long)start) % 8; + + if (prefix) { + u8 *r = check_bytes8(start, value, prefix); + if (r) + return r; + start += prefix; + bytes -= prefix; + } + + words = bytes / 8; + + while (words) { + if (*(u64 *)start != value64) + return check_bytes8(start, value, 8); + start += 8; + words--; + } + + return check_bytes8(start, value, bytes % 8); +} +EXPORT_SYMBOL(memchr_inv); diff --git a/mm/slub.c b/mm/slub.c index 9f662d7..692fe34 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -681,49 +681,6 @@ static void init_object(struct kmem_cache *s, void *object, u8 val) memset(p + s->objsize, val, s->inuse - s->objsize); } -static u8 *check_bytes8(u8 *start, u8 value, unsigned int bytes) -{ - while (bytes) { - if (*start != value) - return start; - start++; - bytes--; - } - return NULL; -} - -static u8 *check_bytes(u8 *start, u8 value, unsigned int bytes) -{ - u64 value64; - unsigned int words, prefix; - - if (bytes <= 16) - return check_bytes8(start, value, bytes); - - value64 = value | value << 8 | value << 16 | value << 24; - value64 = (value64 & 0xffffffff) | value64 << 32; - prefix = 8 - ((unsigned long)start) % 8; - - if (prefix) { - u8 *r = check_bytes8(start, value, prefix); - if (r) - return r; - start += prefix; - bytes -= prefix; - } - - words = bytes / 8; - - while (words) { - if (*(u64 *)start != value64) - return check_bytes8(start, value, 8); - start += 8; - words--; - } - - return check_bytes8(start, value, bytes % 8); -} - static void restore_bytes(struct kmem_cache *s, char *message, u8 data, void *from, void *to) { @@ -738,7 +695,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page, u8 *fault; u8 *end; - fault = check_bytes(start, value, bytes); + fault = memchr_inv(start, value, bytes); if (!fault) return 1; @@ -831,7 +788,7 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page) if (!remainder) return 1; - fault = check_bytes(end - remainder, POISON_INUSE, remainder); + fault = memchr_inv(end - remainder, POISON_INUSE, remainder); if (!fault) return 1; while (end > fault && end[-1] == POISON_INUSE) -- 1.7.4.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] string: introduce memchr_inv 2011-08-22 16:29 ` [PATCH 3/4] string: introduce memchr_inv Akinobu Mita @ 2011-08-22 16:57 ` Pekka Enberg 2011-08-22 17:09 ` Jörn Engel 2011-08-22 20:52 ` Andrew Morton 2011-08-22 20:59 ` Geert Uytterhoeven 2 siblings, 1 reply; 14+ messages in thread From: Pekka Enberg @ 2011-08-22 16:57 UTC (permalink / raw) To: Akinobu Mita Cc: linux-kernel, linux-mm, akpm, Christoph Lameter, Matt Mackall, Joern Engel, logfs, Marcin Slusarz, Eric Dumazet On Tue, 2011-08-23 at 01:29 +0900, Akinobu Mita wrote: > memchr_inv() is mainly used to check whether the whole buffer is filled > with just a specified byte. > > The function name and prototype are stolen from logfs and the > implementation is from SLUB. > > Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> > Cc: Christoph Lameter <cl@linux-foundation.org> > Cc: Pekka Enberg <penberg@kernel.org> > Cc: Matt Mackall <mpm@selenic.com> > Cc: linux-mm@kvack.org > Cc: Joern Engel <joern@logfs.org> > Cc: logfs@logfs.org > Cc: Marcin Slusarz <marcin.slusarz@gmail.com> > Cc: Eric Dumazet <eric.dumazet@gmail.com> Acked-by: Pekka Enberg <penberg@kernel.org> -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] string: introduce memchr_inv 2011-08-22 16:57 ` Pekka Enberg @ 2011-08-22 17:09 ` Jörn Engel 0 siblings, 0 replies; 14+ messages in thread From: Jörn Engel @ 2011-08-22 17:09 UTC (permalink / raw) To: Pekka Enberg Cc: Akinobu Mita, linux-kernel, linux-mm, akpm, Christoph Lameter, Matt Mackall, logfs, Marcin Slusarz, Eric Dumazet On Mon, 22 August 2011 19:57:50 +0300, Pekka Enberg wrote: > On Tue, 2011-08-23 at 01:29 +0900, Akinobu Mita wrote: > > memchr_inv() is mainly used to check whether the whole buffer is filled > > with just a specified byte. > > > > The function name and prototype are stolen from logfs and the > > implementation is from SLUB. > > > > Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> > > Cc: Christoph Lameter <cl@linux-foundation.org> > > Cc: Pekka Enberg <penberg@kernel.org> > > Cc: Matt Mackall <mpm@selenic.com> > > Cc: linux-mm@kvack.org > > Cc: Joern Engel <joern@logfs.org> > > Cc: logfs@logfs.org > > Cc: Marcin Slusarz <marcin.slusarz@gmail.com> > > Cc: Eric Dumazet <eric.dumazet@gmail.com> > > Acked-by: Pekka Enberg <penberg@kernel.org> Acked-by: Joern Engel <joern@logfs.org> JA?rn -- He who knows that enough is enough will always have enough. -- Lao Tsu -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] string: introduce memchr_inv 2011-08-22 16:29 ` [PATCH 3/4] string: introduce memchr_inv Akinobu Mita 2011-08-22 16:57 ` Pekka Enberg @ 2011-08-22 20:52 ` Andrew Morton 2011-08-22 21:50 ` Andrew Morton 2011-08-22 21:56 ` Eric Dumazet 2011-08-22 20:59 ` Geert Uytterhoeven 2 siblings, 2 replies; 14+ messages in thread From: Andrew Morton @ 2011-08-22 20:52 UTC (permalink / raw) To: Akinobu Mita Cc: linux-kernel, linux-mm, Christoph Lameter, Pekka Enberg, Matt Mackall, Joern Engel, logfs, Marcin Slusarz, Eric Dumazet, linux-arch On Tue, 23 Aug 2011 01:29:07 +0900 Akinobu Mita <akinobu.mita@gmail.com> wrote: > memchr_inv() is mainly used to check whether the whole buffer is filled > with just a specified byte. > > The function name and prototype are stolen from logfs and the > implementation is from SLUB. > > ... > > +/** > + * memchr_inv - Find a character in an area of memory. > + * @s: The memory area > + * @c: The byte to search for > + * @n: The size of the area. This text seems to be stolen from memchr(). I guess it's close enough. > + * returns the address of the first character other than @c, or %NULL > + * if the whole buffer contains just @c. > + */ > +void *memchr_inv(const void *start, int c, size_t bytes) > +{ > + u8 value = c; > + u64 value64; > + unsigned int words, prefix; > + > + if (bytes <= 16) > + return check_bytes8(start, value, bytes); > + > + value64 = value | value << 8 | value << 16 | value << 24; > + value64 = (value64 & 0xffffffff) | value64 << 32; > + prefix = 8 - ((unsigned long)start) % 8; > + > + if (prefix) { > + u8 *r = check_bytes8(start, value, prefix); > + if (r) > + return r; > + start += prefix; > + bytes -= prefix; > + } > + > + words = bytes / 8; > + > + while (words) { > + if (*(u64 *)start != value64) OK, problem. This will explode if passed a misaligned address on certain (non-x86) architectures. This is nasty because people will develop and test code on x86 and it works. Much later, the alpha/ia64/etc guys discover the problem. One fix would be to use get_unaligned(). This might be slow on some architectures, I don't know. Another fix is to restrict the caller's alignment freedom; document this and add a runtime WARN_ON(). > + return check_bytes8(start, value, 8); > + start += 8; > + words--; > + } > + > + return check_bytes8(start, value, bytes % 8); > +} > +EXPORT_SYMBOL(memchr_inv); -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] string: introduce memchr_inv 2011-08-22 20:52 ` Andrew Morton @ 2011-08-22 21:50 ` Andrew Morton 2011-08-22 21:56 ` Eric Dumazet 1 sibling, 0 replies; 14+ messages in thread From: Andrew Morton @ 2011-08-22 21:50 UTC (permalink / raw) To: Akinobu Mita, linux-kernel, linux-mm, Christoph Lameter, Pekka Enberg, Matt Mackall, Joern Engel, logfs, Marcin Slusarz, Eric Dumazet, linux-arch On Mon, 22 Aug 2011 13:52:18 -0700 Andrew Morton <akpm@linux-foundation.org> wrote: > > + value64 = value | value << 8 | value << 16 | value << 24; > > + value64 = (value64 & 0xffffffff) | value64 << 32; > > + prefix = 8 - ((unsigned long)start) % 8; > > + > > + if (prefix) { > > + u8 *r = check_bytes8(start, value, prefix); > > + if (r) > > + return r; > > + start += prefix; > > + bytes -= prefix; > > + } > > + > > + words = bytes / 8; > > + > > + while (words) { > > + if (*(u64 *)start != value64) > > OK, problem. This will explode if passed a misaligned address on > certain (non-x86) architectures. pls ignore. As Marcin points out, I can't read. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] string: introduce memchr_inv 2011-08-22 20:52 ` Andrew Morton 2011-08-22 21:50 ` Andrew Morton @ 2011-08-22 21:56 ` Eric Dumazet 1 sibling, 0 replies; 14+ messages in thread From: Eric Dumazet @ 2011-08-22 21:56 UTC (permalink / raw) To: Andrew Morton Cc: Akinobu Mita, linux-kernel, linux-mm, Christoph Lameter, Pekka Enberg, Matt Mackall, Joern Engel, logfs, Marcin Slusarz, linux-arch Le lundi 22 aoA>>t 2011 A 13:52 -0700, Andrew Morton a A(C)crit : > On Tue, 23 Aug 2011 01:29:07 +0900 > Akinobu Mita <akinobu.mita@gmail.com> wrote: > > > memchr_inv() is mainly used to check whether the whole buffer is filled > > with just a specified byte. > > > > The function name and prototype are stolen from logfs and the > > implementation is from SLUB. > > > > ... > > > > +/** > > + * memchr_inv - Find a character in an area of memory. > > + * @s: The memory area > > + * @c: The byte to search for > > + * @n: The size of the area. > > This text seems to be stolen from memchr(). I guess it's close enough. > > > + * returns the address of the first character other than @c, or %NULL > > + * if the whole buffer contains just @c. > > + */ > > +void *memchr_inv(const void *start, int c, size_t bytes) > > +{ > > + u8 value = c; > > + u64 value64; > > + unsigned int words, prefix; > > + > > + if (bytes <= 16) > > + return check_bytes8(start, value, bytes); > > + > > + value64 = value | value << 8 | value << 16 | value << 24; > > + value64 = (value64 & 0xffffffff) | value64 << 32; > > + prefix = 8 - ((unsigned long)start) % 8; > > + <snip> > > + if (prefix) { > > + u8 *r = check_bytes8(start, value, prefix); > > + if (r) > > + return r; > > + start += prefix; > > + bytes -= prefix; > > + } </snip> Please note Andrew the previous code just make sure 'start' is aligned on 8 bytes boundary. (It is suboptimal because if 'start' was already aligned, we call the slow check_bytes(start, value, 8)) Code should probably do prefix = (unsigned long)start % 8; if (prefix) { prefix = 8 - prefix; r = check_bytes8(start, value, prefix); ... > > + > > + words = bytes / 8; > > + > > + while (words) { > > + if (*(u64 *)start != value64) -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] string: introduce memchr_inv 2011-08-22 16:29 ` [PATCH 3/4] string: introduce memchr_inv Akinobu Mita 2011-08-22 16:57 ` Pekka Enberg 2011-08-22 20:52 ` Andrew Morton @ 2011-08-22 20:59 ` Geert Uytterhoeven 2011-08-23 14:31 ` Christoph Lameter 2 siblings, 1 reply; 14+ messages in thread From: Geert Uytterhoeven @ 2011-08-22 20:59 UTC (permalink / raw) To: Akinobu Mita Cc: linux-kernel, linux-mm, akpm, Christoph Lameter, Pekka Enberg, Matt Mackall, Joern Engel, logfs, Marcin Slusarz, Eric Dumazet On Mon, Aug 22, 2011 at 18:29, Akinobu Mita <akinobu.mita@gmail.com> wrote: > +/** > + * memchr_inv - Find a character in an area of memory. This description doesn't really match. > + * @s: The memory area > + * @c: The byte to search for > + * @n: The size of the area. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH 3/4] string: introduce memchr_inv 2011-08-22 20:59 ` Geert Uytterhoeven @ 2011-08-23 14:31 ` Christoph Lameter 0 siblings, 0 replies; 14+ messages in thread From: Christoph Lameter @ 2011-08-23 14:31 UTC (permalink / raw) To: Geert Uytterhoeven Cc: Akinobu Mita, linux-kernel, linux-mm, akpm, Pekka Enberg, Matt Mackall, Joern Engel, logfs, Marcin Slusarz, Eric Dumazet On Mon, 22 Aug 2011, Geert Uytterhoeven wrote: > On Mon, Aug 22, 2011 at 18:29, Akinobu Mita <akinobu.mita@gmail.com> wrote: > > +/** > > + * memchr_inv - Find a character in an area of memory. > > This description doesn't really match. Seconded. If you fix that then Acked-by: Christoph Lameter <cl@linux.com> -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH 4/4] debug-pagealloc: use memchr_inv 2011-08-22 16:29 [PATCH 0/4] debug-pagealloc improvements Akinobu Mita ` (2 preceding siblings ...) 2011-08-22 16:29 ` [PATCH 3/4] string: introduce memchr_inv Akinobu Mita @ 2011-08-22 16:29 ` Akinobu Mita 3 siblings, 0 replies; 14+ messages in thread From: Akinobu Mita @ 2011-08-22 16:29 UTC (permalink / raw) To: linux-kernel, linux-mm, akpm; +Cc: Akinobu Mita Use newly introduced memchr_inv for page verification. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> --- mm/debug-pagealloc.c | 8 +++----- 1 files changed, 3 insertions(+), 5 deletions(-) diff --git a/mm/debug-pagealloc.c b/mm/debug-pagealloc.c index 5afe80c..d8470d4 100644 --- a/mm/debug-pagealloc.c +++ b/mm/debug-pagealloc.c @@ -1,4 +1,5 @@ #include <linux/kernel.h> +#include <linux/string.h> #include <linux/mm.h> #include <linux/highmem.h> #include <linux/page-debug-flags.h> @@ -62,11 +63,8 @@ static void check_poison_mem(unsigned char *mem, size_t bytes) unsigned char *start; unsigned char *end; - for (start = mem; start < mem + bytes; start++) { - if (*start != PAGE_POISON) - break; - } - if (start == mem + bytes) + start = memchr_inv(mem, PAGE_POISON, bytes); + if (!start) return; for (end = mem + bytes - 1; end > start; end--) { -- 1.7.4.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply related [flat|nested] 14+ messages in thread
end of thread, other threads:[~2011-08-23 15:26 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2011-08-22 16:29 [PATCH 0/4] debug-pagealloc improvements Akinobu Mita 2011-08-22 16:29 ` [PATCH 1/4] debug-pagealloc: use plain __ratelimit() instead of printk_ratelimit() Akinobu Mita 2011-08-22 16:29 ` [PATCH 2/4] debug-pagealloc: add support for highmem pages Akinobu Mita 2011-08-22 20:43 ` Andrew Morton 2011-08-23 15:26 ` Akinobu Mita 2011-08-22 16:29 ` [PATCH 3/4] string: introduce memchr_inv Akinobu Mita 2011-08-22 16:57 ` Pekka Enberg 2011-08-22 17:09 ` Jörn Engel 2011-08-22 20:52 ` Andrew Morton 2011-08-22 21:50 ` Andrew Morton 2011-08-22 21:56 ` Eric Dumazet 2011-08-22 20:59 ` Geert Uytterhoeven 2011-08-23 14:31 ` Christoph Lameter 2011-08-22 16:29 ` [PATCH 4/4] debug-pagealloc: use memchr_inv Akinobu Mita
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).