aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2011-10-31 20:08:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-31 20:30:47 -0400
commit798248206b59acc6e1238c778281419c041891a7 (patch)
treeff8564431367b442b18bca4a0a9732e5799e2391 /mm
parent77311139f364d7f71fc9ba88f59fd90e60205007 (diff)
lib/string.c: introduce memchr_inv()
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> Acked-by: Christoph Lameter <cl@linux-foundation.org> Acked-by: Pekka Enberg <penberg@kernel.org> Cc: Matt Mackall <mpm@selenic.com> Acked-by: Joern Engel <joern@logfs.org> Cc: Marcin Slusarz <marcin.slusarz@gmail.com> Cc: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm')
-rw-r--r--mm/slub.c47
1 files changed, 2 insertions, 45 deletions
diff --git a/mm/slub.c b/mm/slub.c
index 95215aa6a75e..7d2a996c307e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -655,49 +655,6 @@ static void init_object(struct kmem_cache *s, void *object, u8 val)
655 memset(p + s->objsize, val, s->inuse - s->objsize); 655 memset(p + s->objsize, val, s->inuse - s->objsize);
656} 656}
657 657
658static u8 *check_bytes8(u8 *start, u8 value, unsigned int bytes)
659{
660 while (bytes) {
661 if (*start != value)
662 return start;
663 start++;
664 bytes--;
665 }
666 return NULL;
667}
668
669static u8 *check_bytes(u8 *start, u8 value, unsigned int bytes)
670{
671 u64 value64;
672 unsigned int words, prefix;
673
674 if (bytes <= 16)
675 return check_bytes8(start, value, bytes);
676
677 value64 = value | value << 8 | value << 16 | value << 24;
678 value64 = (value64 & 0xffffffff) | value64 << 32;
679 prefix = 8 - ((unsigned long)start) % 8;
680
681 if (prefix) {
682 u8 *r = check_bytes8(start, value, prefix);
683 if (r)
684 return r;
685 start += prefix;
686 bytes -= prefix;
687 }
688
689 words = bytes / 8;
690
691 while (words) {
692 if (*(u64 *)start != value64)
693 return check_bytes8(start, value, 8);
694 start += 8;
695 words--;
696 }
697
698 return check_bytes8(start, value, bytes % 8);
699}
700
701static void restore_bytes(struct kmem_cache *s, char *message, u8 data, 658static void restore_bytes(struct kmem_cache *s, char *message, u8 data,
702 void *from, void *to) 659 void *from, void *to)
703{ 660{
@@ -712,7 +669,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
712 u8 *fault; 669 u8 *fault;
713 u8 *end; 670 u8 *end;
714 671
715 fault = check_bytes(start, value, bytes); 672 fault = memchr_inv(start, value, bytes);
716 if (!fault) 673 if (!fault)
717 return 1; 674 return 1;
718 675
@@ -805,7 +762,7 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page)
805 if (!remainder) 762 if (!remainder)
806 return 1; 763 return 1;
807 764
808 fault = check_bytes(end - remainder, POISON_INUSE, remainder); 765 fault = memchr_inv(end - remainder, POISON_INUSE, remainder);
809 if (!fault) 766 if (!fault)
810 return 1; 767 return 1;
811 while (end > fault && end[-1] == POISON_INUSE) 768 while (end > fault && end[-1] == POISON_INUSE)