diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Kconfig | 3 | ||||
| -rw-r--r-- | lib/Kconfig.debug | 5 | ||||
| -rw-r--r-- | lib/Makefile | 3 | ||||
| -rw-r--r-- | lib/bitmap.c | 19 | ||||
| -rw-r--r-- | lib/crc32.c | 30 | ||||
| -rw-r--r-- | lib/list_sort.c | 263 | ||||
| -rw-r--r-- | lib/show_mem.c | 14 | ||||
| -rw-r--r-- | lib/string.c | 40 |
8 files changed, 242 insertions, 135 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 97b136ff117e..8034c46327cb 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
| @@ -160,6 +160,9 @@ config TEXTSEARCH_BM | |||
| 160 | config TEXTSEARCH_FSM | 160 | config TEXTSEARCH_FSM |
| 161 | tristate | 161 | tristate |
| 162 | 162 | ||
| 163 | config LIST_SORT | ||
| 164 | boolean | ||
| 165 | |||
| 163 | config HAS_IOMEM | 166 | config HAS_IOMEM |
| 164 | boolean | 167 | boolean |
| 165 | depends on !NO_IOMEM | 168 | depends on !NO_IOMEM |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 5e3407d997b2..b520ec1f33c5 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -864,8 +864,7 @@ config DEBUG_FORCE_WEAK_PER_CPU | |||
| 864 | 864 | ||
| 865 | config LKDTM | 865 | config LKDTM |
| 866 | tristate "Linux Kernel Dump Test Tool Module" | 866 | tristate "Linux Kernel Dump Test Tool Module" |
| 867 | depends on DEBUG_KERNEL | 867 | depends on DEBUG_FS |
| 868 | depends on KPROBES | ||
| 869 | depends on BLOCK | 868 | depends on BLOCK |
| 870 | default n | 869 | default n |
| 871 | help | 870 | help |
| @@ -876,7 +875,7 @@ config LKDTM | |||
| 876 | called lkdtm. | 875 | called lkdtm. |
| 877 | 876 | ||
| 878 | Documentation on how to use the module can be found in | 877 | Documentation on how to use the module can be found in |
| 879 | drivers/misc/lkdtm.c | 878 | Documentation/fault-injection/provoke-crashes.txt |
| 880 | 879 | ||
| 881 | config FAULT_INJECTION | 880 | config FAULT_INJECTION |
| 882 | bool "Fault-injection framework" | 881 | bool "Fault-injection framework" |
diff --git a/lib/Makefile b/lib/Makefile index 3b0b4a696db9..e39c361b0be3 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
| @@ -21,7 +21,7 @@ lib-y += kobject.o kref.o klist.o | |||
| 21 | 21 | ||
| 22 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ | 22 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ |
| 23 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ | 23 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ |
| 24 | string_helpers.o gcd.o list_sort.o | 24 | string_helpers.o gcd.o |
| 25 | 25 | ||
| 26 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) | 26 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) |
| 27 | CFLAGS_kobject.o += -DDEBUG | 27 | CFLAGS_kobject.o += -DDEBUG |
| @@ -40,6 +40,7 @@ lib-$(CONFIG_GENERIC_FIND_FIRST_BIT) += find_next_bit.o | |||
| 40 | lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o | 40 | lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o |
| 41 | obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o | 41 | obj-$(CONFIG_GENERIC_FIND_LAST_BIT) += find_last_bit.o |
| 42 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o | 42 | obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o |
| 43 | obj-$(CONFIG_LIST_SORT) += list_sort.o | ||
| 43 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o | 44 | obj-$(CONFIG_LOCK_KERNEL) += kernel_lock.o |
| 44 | obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o | 45 | obj-$(CONFIG_DEBUG_PREEMPT) += smp_processor_id.o |
| 45 | obj-$(CONFIG_DEBUG_LIST) += list_debug.o | 46 | obj-$(CONFIG_DEBUG_LIST) += list_debug.o |
diff --git a/lib/bitmap.c b/lib/bitmap.c index 11bf49750583..ffb78c916ccd 100644 --- a/lib/bitmap.c +++ b/lib/bitmap.c | |||
| @@ -487,7 +487,7 @@ int __bitmap_parse(const char *buf, unsigned int buflen, | |||
| 487 | EXPORT_SYMBOL(__bitmap_parse); | 487 | EXPORT_SYMBOL(__bitmap_parse); |
| 488 | 488 | ||
| 489 | /** | 489 | /** |
| 490 | * bitmap_parse_user() | 490 | * bitmap_parse_user - convert an ASCII hex string in a user buffer into a bitmap |
| 491 | * | 491 | * |
| 492 | * @ubuf: pointer to user buffer containing string. | 492 | * @ubuf: pointer to user buffer containing string. |
| 493 | * @ulen: buffer size in bytes. If string is smaller than this | 493 | * @ulen: buffer size in bytes. If string is smaller than this |
| @@ -619,7 +619,7 @@ int bitmap_parselist(const char *bp, unsigned long *maskp, int nmaskbits) | |||
| 619 | EXPORT_SYMBOL(bitmap_parselist); | 619 | EXPORT_SYMBOL(bitmap_parselist); |
| 620 | 620 | ||
| 621 | /** | 621 | /** |
| 622 | * bitmap_pos_to_ord(buf, pos, bits) | 622 | * bitmap_pos_to_ord - find ordinal of set bit at given position in bitmap |
| 623 | * @buf: pointer to a bitmap | 623 | * @buf: pointer to a bitmap |
| 624 | * @pos: a bit position in @buf (0 <= @pos < @bits) | 624 | * @pos: a bit position in @buf (0 <= @pos < @bits) |
| 625 | * @bits: number of valid bit positions in @buf | 625 | * @bits: number of valid bit positions in @buf |
| @@ -655,7 +655,7 @@ static int bitmap_pos_to_ord(const unsigned long *buf, int pos, int bits) | |||
| 655 | } | 655 | } |
| 656 | 656 | ||
| 657 | /** | 657 | /** |
| 658 | * bitmap_ord_to_pos(buf, ord, bits) | 658 | * bitmap_ord_to_pos - find position of n-th set bit in bitmap |
| 659 | * @buf: pointer to bitmap | 659 | * @buf: pointer to bitmap |
| 660 | * @ord: ordinal bit position (n-th set bit, n >= 0) | 660 | * @ord: ordinal bit position (n-th set bit, n >= 0) |
| 661 | * @bits: number of valid bit positions in @buf | 661 | * @bits: number of valid bit positions in @buf |
| @@ -733,10 +733,9 @@ void bitmap_remap(unsigned long *dst, const unsigned long *src, | |||
| 733 | bitmap_zero(dst, bits); | 733 | bitmap_zero(dst, bits); |
| 734 | 734 | ||
| 735 | w = bitmap_weight(new, bits); | 735 | w = bitmap_weight(new, bits); |
| 736 | for (oldbit = find_first_bit(src, bits); | 736 | for_each_set_bit(oldbit, src, bits) { |
| 737 | oldbit < bits; | ||
| 738 | oldbit = find_next_bit(src, bits, oldbit + 1)) { | ||
| 739 | int n = bitmap_pos_to_ord(old, oldbit, bits); | 737 | int n = bitmap_pos_to_ord(old, oldbit, bits); |
| 738 | |||
| 740 | if (n < 0 || w == 0) | 739 | if (n < 0 || w == 0) |
| 741 | set_bit(oldbit, dst); /* identity map */ | 740 | set_bit(oldbit, dst); /* identity map */ |
| 742 | else | 741 | else |
| @@ -903,9 +902,7 @@ void bitmap_onto(unsigned long *dst, const unsigned long *orig, | |||
| 903 | */ | 902 | */ |
| 904 | 903 | ||
| 905 | m = 0; | 904 | m = 0; |
| 906 | for (n = find_first_bit(relmap, bits); | 905 | for_each_set_bit(n, relmap, bits) { |
| 907 | n < bits; | ||
| 908 | n = find_next_bit(relmap, bits, n + 1)) { | ||
| 909 | /* m == bitmap_pos_to_ord(relmap, n, bits) */ | 906 | /* m == bitmap_pos_to_ord(relmap, n, bits) */ |
| 910 | if (test_bit(m, orig)) | 907 | if (test_bit(m, orig)) |
| 911 | set_bit(n, dst); | 908 | set_bit(n, dst); |
| @@ -934,9 +931,7 @@ void bitmap_fold(unsigned long *dst, const unsigned long *orig, | |||
| 934 | return; | 931 | return; |
| 935 | bitmap_zero(dst, bits); | 932 | bitmap_zero(dst, bits); |
| 936 | 933 | ||
| 937 | for (oldbit = find_first_bit(orig, bits); | 934 | for_each_set_bit(oldbit, orig, bits) |
| 938 | oldbit < bits; | ||
| 939 | oldbit = find_next_bit(orig, bits, oldbit + 1)) | ||
| 940 | set_bit(oldbit % sz, dst); | 935 | set_bit(oldbit % sz, dst); |
| 941 | } | 936 | } |
| 942 | EXPORT_SYMBOL(bitmap_fold); | 937 | EXPORT_SYMBOL(bitmap_fold); |
diff --git a/lib/crc32.c b/lib/crc32.c index 02e3b31b3a79..0f45fbff34cb 100644 --- a/lib/crc32.c +++ b/lib/crc32.c | |||
| @@ -30,11 +30,15 @@ | |||
| 30 | #include <asm/atomic.h> | 30 | #include <asm/atomic.h> |
| 31 | #include "crc32defs.h" | 31 | #include "crc32defs.h" |
| 32 | #if CRC_LE_BITS == 8 | 32 | #if CRC_LE_BITS == 8 |
| 33 | #define tole(x) __constant_cpu_to_le32(x) | 33 | # define tole(x) __constant_cpu_to_le32(x) |
| 34 | #define tobe(x) __constant_cpu_to_be32(x) | ||
| 35 | #else | 34 | #else |
| 36 | #define tole(x) (x) | 35 | # define tole(x) (x) |
| 37 | #define tobe(x) (x) | 36 | #endif |
| 37 | |||
| 38 | #if CRC_BE_BITS == 8 | ||
| 39 | # define tobe(x) __constant_cpu_to_be32(x) | ||
| 40 | #else | ||
| 41 | # define tobe(x) (x) | ||
| 38 | #endif | 42 | #endif |
| 39 | #include "crc32table.h" | 43 | #include "crc32table.h" |
| 40 | 44 | ||
| @@ -52,20 +56,19 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab) | |||
| 52 | # else | 56 | # else |
| 53 | # define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) | 57 | # define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8) |
| 54 | # endif | 58 | # endif |
| 55 | const u32 *b = (const u32 *)buf; | 59 | const u32 *b; |
| 56 | size_t rem_len; | 60 | size_t rem_len; |
| 57 | 61 | ||
| 58 | /* Align it */ | 62 | /* Align it */ |
| 59 | if (unlikely((long)b & 3 && len)) { | 63 | if (unlikely((long)buf & 3 && len)) { |
| 60 | u8 *p = (u8 *)b; | ||
| 61 | do { | 64 | do { |
| 62 | DO_CRC(*p++); | 65 | DO_CRC(*buf++); |
| 63 | } while ((--len) && ((long)p)&3); | 66 | } while ((--len) && ((long)buf)&3); |
| 64 | b = (u32 *)p; | ||
| 65 | } | 67 | } |
| 66 | rem_len = len & 3; | 68 | rem_len = len & 3; |
| 67 | /* load data 32 bits wide, xor data 32 bits wide. */ | 69 | /* load data 32 bits wide, xor data 32 bits wide. */ |
| 68 | len = len >> 2; | 70 | len = len >> 2; |
| 71 | b = (const u32 *)buf; | ||
| 69 | for (--b; len; --len) { | 72 | for (--b; len; --len) { |
| 70 | crc ^= *++b; /* use pre increment for speed */ | 73 | crc ^= *++b; /* use pre increment for speed */ |
| 71 | DO_CRC(0); | 74 | DO_CRC(0); |
| @@ -82,6 +85,7 @@ crc32_body(u32 crc, unsigned char const *buf, size_t len, const u32 *tab) | |||
| 82 | } while (--len); | 85 | } while (--len); |
| 83 | } | 86 | } |
| 84 | return crc; | 87 | return crc; |
| 88 | #undef DO_CRC | ||
| 85 | } | 89 | } |
| 86 | #endif | 90 | #endif |
| 87 | /** | 91 | /** |
| @@ -119,9 +123,6 @@ u32 __pure crc32_le(u32 crc, unsigned char const *p, size_t len) | |||
| 119 | crc = __cpu_to_le32(crc); | 123 | crc = __cpu_to_le32(crc); |
| 120 | crc = crc32_body(crc, p, len, tab); | 124 | crc = crc32_body(crc, p, len, tab); |
| 121 | return __le32_to_cpu(crc); | 125 | return __le32_to_cpu(crc); |
| 122 | #undef ENDIAN_SHIFT | ||
| 123 | #undef DO_CRC | ||
| 124 | |||
| 125 | # elif CRC_LE_BITS == 4 | 126 | # elif CRC_LE_BITS == 4 |
| 126 | while (len--) { | 127 | while (len--) { |
| 127 | crc ^= *p++; | 128 | crc ^= *p++; |
| @@ -179,9 +180,6 @@ u32 __pure crc32_be(u32 crc, unsigned char const *p, size_t len) | |||
| 179 | crc = __cpu_to_be32(crc); | 180 | crc = __cpu_to_be32(crc); |
| 180 | crc = crc32_body(crc, p, len, tab); | 181 | crc = crc32_body(crc, p, len, tab); |
| 181 | return __be32_to_cpu(crc); | 182 | return __be32_to_cpu(crc); |
| 182 | #undef ENDIAN_SHIFT | ||
| 183 | #undef DO_CRC | ||
| 184 | |||
| 185 | # elif CRC_BE_BITS == 4 | 183 | # elif CRC_BE_BITS == 4 |
| 186 | while (len--) { | 184 | while (len--) { |
| 187 | crc ^= *p++ << 24; | 185 | crc ^= *p++ << 24; |
diff --git a/lib/list_sort.c b/lib/list_sort.c index 19d11e0bb958..4b5cb794c38b 100644 --- a/lib/list_sort.c +++ b/lib/list_sort.c | |||
| @@ -4,99 +4,214 @@ | |||
| 4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
| 5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
| 6 | 6 | ||
| 7 | #define MAX_LIST_LENGTH_BITS 20 | ||
| 8 | |||
| 9 | /* | ||
| 10 | * Returns a list organized in an intermediate format suited | ||
| 11 | * to chaining of merge() calls: null-terminated, no reserved or | ||
| 12 | * sentinel head node, "prev" links not maintained. | ||
| 13 | */ | ||
| 14 | static struct list_head *merge(void *priv, | ||
| 15 | int (*cmp)(void *priv, struct list_head *a, | ||
| 16 | struct list_head *b), | ||
| 17 | struct list_head *a, struct list_head *b) | ||
| 18 | { | ||
| 19 | struct list_head head, *tail = &head; | ||
| 20 | |||
| 21 | while (a && b) { | ||
| 22 | /* if equal, take 'a' -- important for sort stability */ | ||
| 23 | if ((*cmp)(priv, a, b) <= 0) { | ||
| 24 | tail->next = a; | ||
| 25 | a = a->next; | ||
| 26 | } else { | ||
| 27 | tail->next = b; | ||
| 28 | b = b->next; | ||
| 29 | } | ||
| 30 | tail = tail->next; | ||
| 31 | } | ||
| 32 | tail->next = a?:b; | ||
| 33 | return head.next; | ||
| 34 | } | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Combine final list merge with restoration of standard doubly-linked | ||
| 38 | * list structure. This approach duplicates code from merge(), but | ||
| 39 | * runs faster than the tidier alternatives of either a separate final | ||
| 40 | * prev-link restoration pass, or maintaining the prev links | ||
| 41 | * throughout. | ||
| 42 | */ | ||
| 43 | static void merge_and_restore_back_links(void *priv, | ||
| 44 | int (*cmp)(void *priv, struct list_head *a, | ||
| 45 | struct list_head *b), | ||
| 46 | struct list_head *head, | ||
| 47 | struct list_head *a, struct list_head *b) | ||
| 48 | { | ||
| 49 | struct list_head *tail = head; | ||
| 50 | |||
| 51 | while (a && b) { | ||
| 52 | /* if equal, take 'a' -- important for sort stability */ | ||
| 53 | if ((*cmp)(priv, a, b) <= 0) { | ||
| 54 | tail->next = a; | ||
| 55 | a->prev = tail; | ||
| 56 | a = a->next; | ||
| 57 | } else { | ||
| 58 | tail->next = b; | ||
| 59 | b->prev = tail; | ||
| 60 | b = b->next; | ||
| 61 | } | ||
| 62 | tail = tail->next; | ||
| 63 | } | ||
| 64 | tail->next = a ? : b; | ||
| 65 | |||
| 66 | do { | ||
| 67 | /* | ||
| 68 | * In worst cases this loop may run many iterations. | ||
| 69 | * Continue callbacks to the client even though no | ||
| 70 | * element comparison is needed, so the client's cmp() | ||
| 71 | * routine can invoke cond_resched() periodically. | ||
| 72 | */ | ||
| 73 | (*cmp)(priv, tail, tail); | ||
| 74 | |||
| 75 | tail->next->prev = tail; | ||
| 76 | tail = tail->next; | ||
| 77 | } while (tail->next); | ||
| 78 | |||
| 79 | tail->next = head; | ||
| 80 | head->prev = tail; | ||
| 81 | } | ||
| 82 | |||
| 7 | /** | 83 | /** |
| 8 | * list_sort - sort a list. | 84 | * list_sort - sort a list |
| 9 | * @priv: private data, passed to @cmp | 85 | * @priv: private data, opaque to list_sort(), passed to @cmp |
| 10 | * @head: the list to sort | 86 | * @head: the list to sort |
| 11 | * @cmp: the elements comparison function | 87 | * @cmp: the elements comparison function |
| 12 | * | 88 | * |
| 13 | * This function has been implemented by Mark J Roberts <mjr@znex.org>. It | 89 | * This function implements "merge sort", which has O(nlog(n)) |
| 14 | * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted | 90 | * complexity. |
| 15 | * in ascending order. | ||
| 16 | * | 91 | * |
| 17 | * The comparison function @cmp is supposed to return a negative value if @a is | 92 | * The comparison function @cmp must return a negative value if @a |
| 18 | * less than @b, and a positive value if @a is greater than @b. If @a and @b | 93 | * should sort before @b, and a positive value if @a should sort after |
| 19 | * are equivalent, then it does not matter what this function returns. | 94 | * @b. If @a and @b are equivalent, and their original relative |
| 95 | * ordering is to be preserved, @cmp must return 0. | ||
| 20 | */ | 96 | */ |
| 21 | void list_sort(void *priv, struct list_head *head, | 97 | void list_sort(void *priv, struct list_head *head, |
| 22 | int (*cmp)(void *priv, struct list_head *a, | 98 | int (*cmp)(void *priv, struct list_head *a, |
| 23 | struct list_head *b)) | 99 | struct list_head *b)) |
| 24 | { | 100 | { |
| 25 | struct list_head *p, *q, *e, *list, *tail, *oldhead; | 101 | struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists |
| 26 | int insize, nmerges, psize, qsize, i; | 102 | -- last slot is a sentinel */ |
| 103 | int lev; /* index into part[] */ | ||
| 104 | int max_lev = 0; | ||
| 105 | struct list_head *list; | ||
| 27 | 106 | ||
| 28 | if (list_empty(head)) | 107 | if (list_empty(head)) |
| 29 | return; | 108 | return; |
| 30 | 109 | ||
| 110 | memset(part, 0, sizeof(part)); | ||
| 111 | |||
| 112 | head->prev->next = NULL; | ||
| 31 | list = head->next; | 113 | list = head->next; |
| 32 | list_del(head); | ||
| 33 | insize = 1; | ||
| 34 | for (;;) { | ||
| 35 | p = oldhead = list; | ||
| 36 | list = tail = NULL; | ||
| 37 | nmerges = 0; | ||
| 38 | |||
| 39 | while (p) { | ||
| 40 | nmerges++; | ||
| 41 | q = p; | ||
| 42 | psize = 0; | ||
| 43 | for (i = 0; i < insize; i++) { | ||
| 44 | psize++; | ||
| 45 | q = q->next == oldhead ? NULL : q->next; | ||
| 46 | if (!q) | ||
| 47 | break; | ||
| 48 | } | ||
| 49 | 114 | ||
| 50 | qsize = insize; | 115 | while (list) { |
| 51 | while (psize > 0 || (qsize > 0 && q)) { | 116 | struct list_head *cur = list; |
| 52 | if (!psize) { | 117 | list = list->next; |
| 53 | e = q; | 118 | cur->next = NULL; |
| 54 | q = q->next; | 119 | |
| 55 | qsize--; | 120 | for (lev = 0; part[lev]; lev++) { |
| 56 | if (q == oldhead) | 121 | cur = merge(priv, cmp, part[lev], cur); |
| 57 | q = NULL; | 122 | part[lev] = NULL; |
| 58 | } else if (!qsize || !q) { | 123 | } |
| 59 | e = p; | 124 | if (lev > max_lev) { |
| 60 | p = p->next; | 125 | if (unlikely(lev >= ARRAY_SIZE(part)-1)) { |
| 61 | psize--; | 126 | printk_once(KERN_DEBUG "list passed to" |
| 62 | if (p == oldhead) | 127 | " list_sort() too long for" |
| 63 | p = NULL; | 128 | " efficiency\n"); |
| 64 | } else if (cmp(priv, p, q) <= 0) { | 129 | lev--; |
| 65 | e = p; | ||
| 66 | p = p->next; | ||
| 67 | psize--; | ||
| 68 | if (p == oldhead) | ||
| 69 | p = NULL; | ||
| 70 | } else { | ||
| 71 | e = q; | ||
| 72 | q = q->next; | ||
| 73 | qsize--; | ||
| 74 | if (q == oldhead) | ||
| 75 | q = NULL; | ||
| 76 | } | ||
| 77 | if (tail) | ||
| 78 | tail->next = e; | ||
| 79 | else | ||
| 80 | list = e; | ||
| 81 | e->prev = tail; | ||
| 82 | tail = e; | ||
| 83 | } | 130 | } |
| 84 | p = q; | 131 | max_lev = lev; |
| 85 | } | 132 | } |
| 133 | part[lev] = cur; | ||
| 134 | } | ||
| 86 | 135 | ||
| 87 | tail->next = list; | 136 | for (lev = 0; lev < max_lev; lev++) |
| 88 | list->prev = tail; | 137 | if (part[lev]) |
| 138 | list = merge(priv, cmp, part[lev], list); | ||
| 89 | 139 | ||
| 90 | if (nmerges <= 1) | 140 | merge_and_restore_back_links(priv, cmp, head, part[max_lev], list); |
| 91 | break; | 141 | } |
| 142 | EXPORT_SYMBOL(list_sort); | ||
| 92 | 143 | ||
| 93 | insize *= 2; | 144 | #ifdef DEBUG_LIST_SORT |
| 94 | } | 145 | struct debug_el { |
| 146 | struct list_head l_h; | ||
| 147 | int value; | ||
| 148 | unsigned serial; | ||
| 149 | }; | ||
| 95 | 150 | ||
| 96 | head->next = list; | 151 | static int cmp(void *priv, struct list_head *a, struct list_head *b) |
| 97 | head->prev = list->prev; | 152 | { |
| 98 | list->prev->next = head; | 153 | return container_of(a, struct debug_el, l_h)->value |
| 99 | list->prev = head; | 154 | - container_of(b, struct debug_el, l_h)->value; |
| 100 | } | 155 | } |
| 101 | 156 | ||
| 102 | EXPORT_SYMBOL(list_sort); | 157 | /* |
| 158 | * The pattern of set bits in the list length determines which cases | ||
| 159 | * are hit in list_sort(). | ||
| 160 | */ | ||
| 161 | #define LIST_SORT_TEST_LENGTH (512+128+2) /* not including head */ | ||
| 162 | |||
| 163 | static int __init list_sort_test(void) | ||
| 164 | { | ||
| 165 | int i, r = 1, count; | ||
| 166 | struct list_head *head = kmalloc(sizeof(*head), GFP_KERNEL); | ||
| 167 | struct list_head *cur; | ||
| 168 | |||
| 169 | printk(KERN_WARNING "testing list_sort()\n"); | ||
| 170 | |||
| 171 | cur = head; | ||
| 172 | for (i = 0; i < LIST_SORT_TEST_LENGTH; i++) { | ||
| 173 | struct debug_el *el = kmalloc(sizeof(*el), GFP_KERNEL); | ||
| 174 | BUG_ON(!el); | ||
| 175 | /* force some equivalencies */ | ||
| 176 | el->value = (r = (r * 725861) % 6599) % (LIST_SORT_TEST_LENGTH/3); | ||
| 177 | el->serial = i; | ||
| 178 | |||
| 179 | el->l_h.prev = cur; | ||
| 180 | cur->next = &el->l_h; | ||
| 181 | cur = cur->next; | ||
| 182 | } | ||
| 183 | head->prev = cur; | ||
| 184 | |||
| 185 | list_sort(NULL, head, cmp); | ||
| 186 | |||
| 187 | count = 1; | ||
| 188 | for (cur = head->next; cur->next != head; cur = cur->next) { | ||
| 189 | struct debug_el *el = container_of(cur, struct debug_el, l_h); | ||
| 190 | int cmp_result = cmp(NULL, cur, cur->next); | ||
| 191 | if (cur->next->prev != cur) { | ||
| 192 | printk(KERN_EMERG "list_sort() returned " | ||
| 193 | "a corrupted list!\n"); | ||
| 194 | return 1; | ||
| 195 | } else if (cmp_result > 0) { | ||
| 196 | printk(KERN_EMERG "list_sort() failed to sort!\n"); | ||
| 197 | return 1; | ||
| 198 | } else if (cmp_result == 0 && | ||
| 199 | el->serial >= container_of(cur->next, | ||
| 200 | struct debug_el, l_h)->serial) { | ||
| 201 | printk(KERN_EMERG "list_sort() failed to preserve order" | ||
| 202 | " of equivalent elements!\n"); | ||
| 203 | return 1; | ||
| 204 | } | ||
| 205 | kfree(cur->prev); | ||
| 206 | count++; | ||
| 207 | } | ||
| 208 | kfree(cur); | ||
| 209 | if (count != LIST_SORT_TEST_LENGTH) { | ||
| 210 | printk(KERN_EMERG "list_sort() returned list of" | ||
| 211 | "different length!\n"); | ||
| 212 | return 1; | ||
| 213 | } | ||
| 214 | return 0; | ||
| 215 | } | ||
| 216 | module_init(list_sort_test); | ||
| 217 | #endif | ||
diff --git a/lib/show_mem.c b/lib/show_mem.c index 238e72a18ce1..fdc77c82f922 100644 --- a/lib/show_mem.c +++ b/lib/show_mem.c | |||
| @@ -15,7 +15,7 @@ void show_mem(void) | |||
| 15 | unsigned long total = 0, reserved = 0, shared = 0, | 15 | unsigned long total = 0, reserved = 0, shared = 0, |
| 16 | nonshared = 0, highmem = 0; | 16 | nonshared = 0, highmem = 0; |
| 17 | 17 | ||
| 18 | printk(KERN_INFO "Mem-Info:\n"); | 18 | printk("Mem-Info:\n"); |
| 19 | show_free_areas(); | 19 | show_free_areas(); |
| 20 | 20 | ||
| 21 | for_each_online_pgdat(pgdat) { | 21 | for_each_online_pgdat(pgdat) { |
| @@ -49,15 +49,15 @@ void show_mem(void) | |||
| 49 | pgdat_resize_unlock(pgdat, &flags); | 49 | pgdat_resize_unlock(pgdat, &flags); |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | printk(KERN_INFO "%lu pages RAM\n", total); | 52 | printk("%lu pages RAM\n", total); |
| 53 | #ifdef CONFIG_HIGHMEM | 53 | #ifdef CONFIG_HIGHMEM |
| 54 | printk(KERN_INFO "%lu pages HighMem\n", highmem); | 54 | printk("%lu pages HighMem\n", highmem); |
| 55 | #endif | 55 | #endif |
| 56 | printk(KERN_INFO "%lu pages reserved\n", reserved); | 56 | printk("%lu pages reserved\n", reserved); |
| 57 | printk(KERN_INFO "%lu pages shared\n", shared); | 57 | printk("%lu pages shared\n", shared); |
| 58 | printk(KERN_INFO "%lu pages non-shared\n", nonshared); | 58 | printk("%lu pages non-shared\n", nonshared); |
| 59 | #ifdef CONFIG_QUICKLIST | 59 | #ifdef CONFIG_QUICKLIST |
| 60 | printk(KERN_INFO "%lu pages in pagetable cache\n", | 60 | printk("%lu pages in pagetable cache\n", |
| 61 | quicklist_total_size()); | 61 | quicklist_total_size()); |
| 62 | #endif | 62 | #endif |
| 63 | } | 63 | } |
diff --git a/lib/string.c b/lib/string.c index a1cdcfcc42d0..f71bead1be3e 100644 --- a/lib/string.c +++ b/lib/string.c | |||
| @@ -36,25 +36,21 @@ int strnicmp(const char *s1, const char *s2, size_t len) | |||
| 36 | /* Yes, Virginia, it had better be unsigned */ | 36 | /* Yes, Virginia, it had better be unsigned */ |
| 37 | unsigned char c1, c2; | 37 | unsigned char c1, c2; |
| 38 | 38 | ||
| 39 | c1 = c2 = 0; | 39 | if (!len) |
| 40 | if (len) { | 40 | return 0; |
| 41 | do { | 41 | |
| 42 | c1 = *s1; | 42 | do { |
| 43 | c2 = *s2; | 43 | c1 = *s1++; |
| 44 | s1++; | 44 | c2 = *s2++; |
| 45 | s2++; | 45 | if (!c1 || !c2) |
| 46 | if (!c1) | 46 | break; |
| 47 | break; | 47 | if (c1 == c2) |
| 48 | if (!c2) | 48 | continue; |
| 49 | break; | 49 | c1 = tolower(c1); |
| 50 | if (c1 == c2) | 50 | c2 = tolower(c2); |
| 51 | continue; | 51 | if (c1 != c2) |
| 52 | c1 = tolower(c1); | 52 | break; |
| 53 | c2 = tolower(c2); | 53 | } while (--len); |
| 54 | if (c1 != c2) | ||
| 55 | break; | ||
| 56 | } while (--len); | ||
| 57 | } | ||
| 58 | return (int)c1 - (int)c2; | 54 | return (int)c1 - (int)c2; |
| 59 | } | 55 | } |
| 60 | EXPORT_SYMBOL(strnicmp); | 56 | EXPORT_SYMBOL(strnicmp); |
| @@ -693,13 +689,13 @@ EXPORT_SYMBOL(strstr); | |||
| 693 | */ | 689 | */ |
| 694 | char *strnstr(const char *s1, const char *s2, size_t len) | 690 | char *strnstr(const char *s1, const char *s2, size_t len) |
| 695 | { | 691 | { |
| 696 | size_t l1 = len, l2; | 692 | size_t l2; |
| 697 | 693 | ||
| 698 | l2 = strlen(s2); | 694 | l2 = strlen(s2); |
| 699 | if (!l2) | 695 | if (!l2) |
| 700 | return (char *)s1; | 696 | return (char *)s1; |
| 701 | while (l1 >= l2) { | 697 | while (len >= l2) { |
| 702 | l1--; | 698 | len--; |
| 703 | if (!memcmp(s1, s2, l2)) | 699 | if (!memcmp(s1, s2, l2)) |
| 704 | return (char *)s1; | 700 | return (char *)s1; |
| 705 | s1++; | 701 | s1++; |
