diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig.debug | 19 | ||||
-rw-r--r-- | lib/Makefile | 3 | ||||
-rw-r--r-- | lib/bsearch.c | 53 | ||||
-rw-r--r-- | lib/dma-debug.c | 18 | ||||
-rw-r--r-- | lib/string.c | 29 | ||||
-rw-r--r-- | lib/vsprintf.c | 2 |
6 files changed, 115 insertions, 9 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c768bcdda1b7..9b1707b5f646 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -238,6 +238,21 @@ config DETECT_HUNG_TASK | |||
238 | enabled then all held locks will also be reported. This | 238 | enabled then all held locks will also be reported. This |
239 | feature has negligible overhead. | 239 | feature has negligible overhead. |
240 | 240 | ||
241 | config DEFAULT_HUNG_TASK_TIMEOUT | ||
242 | int "Default timeout for hung task detection (in seconds)" | ||
243 | depends on DETECT_HUNG_TASK | ||
244 | default 120 | ||
245 | help | ||
246 | This option controls the default timeout (in seconds) used | ||
247 | to determine when a task has become non-responsive and should | ||
248 | be considered hung. | ||
249 | |||
250 | It can be adjusted at runtime via the kernel.hung_task_timeout | ||
251 | sysctl or by writing a value to /proc/sys/kernel/hung_task_timeout. | ||
252 | |||
253 | A timeout of 0 disables the check. The default is two minutes. | ||
254 | Keeping the default should be fine in most cases. | ||
255 | |||
241 | config BOOTPARAM_HUNG_TASK_PANIC | 256 | config BOOTPARAM_HUNG_TASK_PANIC |
242 | bool "Panic (Reboot) On Hung Tasks" | 257 | bool "Panic (Reboot) On Hung Tasks" |
243 | depends on DETECT_HUNG_TASK | 258 | depends on DETECT_HUNG_TASK |
@@ -398,9 +413,9 @@ config SLUB_STATS | |||
398 | config DEBUG_KMEMLEAK | 413 | config DEBUG_KMEMLEAK |
399 | bool "Kernel memory leak detector" | 414 | bool "Kernel memory leak detector" |
400 | depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ | 415 | depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ |
401 | (X86 || ARM || PPC || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE) | 416 | (X86 || ARM || PPC || MIPS || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE) |
402 | 417 | ||
403 | select DEBUG_FS if SYSFS | 418 | select DEBUG_FS |
404 | select STACKTRACE if STACKTRACE_SUPPORT | 419 | select STACKTRACE if STACKTRACE_SUPPORT |
405 | select KALLSYMS | 420 | select KALLSYMS |
406 | select CRC32 | 421 | select CRC32 |
diff --git a/lib/Makefile b/lib/Makefile index ef0f28571156..4b49a249064b 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
@@ -21,7 +21,8 @@ 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 lcm.o list_sort.o uuid.o flex_array.o | 24 | string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \ |
25 | bsearch.o | ||
25 | obj-y += kstrtox.o | 26 | obj-y += kstrtox.o |
26 | obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o | 27 | obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o |
27 | 28 | ||
diff --git a/lib/bsearch.c b/lib/bsearch.c new file mode 100644 index 000000000000..5b54758e2afb --- /dev/null +++ b/lib/bsearch.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * A generic implementation of binary search for the Linux kernel | ||
3 | * | ||
4 | * Copyright (C) 2008-2009 Ksplice, Inc. | ||
5 | * Author: Tim Abbott <tabbott@ksplice.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation; version 2. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/bsearch.h> | ||
14 | |||
15 | /* | ||
16 | * bsearch - binary search an array of elements | ||
17 | * @key: pointer to item being searched for | ||
18 | * @base: pointer to first element to search | ||
19 | * @num: number of elements | ||
20 | * @size: size of each element | ||
21 | * @cmp: pointer to comparison function | ||
22 | * | ||
23 | * This function does a binary search on the given array. The | ||
24 | * contents of the array should already be in ascending sorted order | ||
25 | * under the provided comparison function. | ||
26 | * | ||
27 | * Note that the key need not have the same type as the elements in | ||
28 | * the array, e.g. key could be a string and the comparison function | ||
29 | * could compare the string with the struct's name field. However, if | ||
30 | * the key and elements in the array are of the same type, you can use | ||
31 | * the same comparison function for both sort() and bsearch(). | ||
32 | */ | ||
33 | void *bsearch(const void *key, const void *base, size_t num, size_t size, | ||
34 | int (*cmp)(const void *key, const void *elt)) | ||
35 | { | ||
36 | size_t start = 0, end = num; | ||
37 | int result; | ||
38 | |||
39 | while (start < end) { | ||
40 | size_t mid = start + (end - start) / 2; | ||
41 | |||
42 | result = cmp(key, base + mid * size); | ||
43 | if (result < 0) | ||
44 | end = mid; | ||
45 | else if (result > 0) | ||
46 | start = mid + 1; | ||
47 | else | ||
48 | return (void *)base + mid * size; | ||
49 | } | ||
50 | |||
51 | return NULL; | ||
52 | } | ||
53 | EXPORT_SYMBOL(bsearch); | ||
diff --git a/lib/dma-debug.c b/lib/dma-debug.c index 4bfb0471f106..db07bfd9298e 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c | |||
@@ -649,7 +649,7 @@ out_err: | |||
649 | return -ENOMEM; | 649 | return -ENOMEM; |
650 | } | 650 | } |
651 | 651 | ||
652 | static int device_dma_allocations(struct device *dev) | 652 | static int device_dma_allocations(struct device *dev, struct dma_debug_entry **out_entry) |
653 | { | 653 | { |
654 | struct dma_debug_entry *entry; | 654 | struct dma_debug_entry *entry; |
655 | unsigned long flags; | 655 | unsigned long flags; |
@@ -660,8 +660,10 @@ static int device_dma_allocations(struct device *dev) | |||
660 | for (i = 0; i < HASH_SIZE; ++i) { | 660 | for (i = 0; i < HASH_SIZE; ++i) { |
661 | spin_lock(&dma_entry_hash[i].lock); | 661 | spin_lock(&dma_entry_hash[i].lock); |
662 | list_for_each_entry(entry, &dma_entry_hash[i].list, list) { | 662 | list_for_each_entry(entry, &dma_entry_hash[i].list, list) { |
663 | if (entry->dev == dev) | 663 | if (entry->dev == dev) { |
664 | count += 1; | 664 | count += 1; |
665 | *out_entry = entry; | ||
666 | } | ||
665 | } | 667 | } |
666 | spin_unlock(&dma_entry_hash[i].lock); | 668 | spin_unlock(&dma_entry_hash[i].lock); |
667 | } | 669 | } |
@@ -674,6 +676,7 @@ static int device_dma_allocations(struct device *dev) | |||
674 | static int dma_debug_device_change(struct notifier_block *nb, unsigned long action, void *data) | 676 | static int dma_debug_device_change(struct notifier_block *nb, unsigned long action, void *data) |
675 | { | 677 | { |
676 | struct device *dev = data; | 678 | struct device *dev = data; |
679 | struct dma_debug_entry *uninitialized_var(entry); | ||
677 | int count; | 680 | int count; |
678 | 681 | ||
679 | if (global_disable) | 682 | if (global_disable) |
@@ -681,12 +684,17 @@ static int dma_debug_device_change(struct notifier_block *nb, unsigned long acti | |||
681 | 684 | ||
682 | switch (action) { | 685 | switch (action) { |
683 | case BUS_NOTIFY_UNBOUND_DRIVER: | 686 | case BUS_NOTIFY_UNBOUND_DRIVER: |
684 | count = device_dma_allocations(dev); | 687 | count = device_dma_allocations(dev, &entry); |
685 | if (count == 0) | 688 | if (count == 0) |
686 | break; | 689 | break; |
687 | err_printk(dev, NULL, "DMA-API: device driver has pending " | 690 | err_printk(dev, entry, "DMA-API: device driver has pending " |
688 | "DMA allocations while released from device " | 691 | "DMA allocations while released from device " |
689 | "[count=%d]\n", count); | 692 | "[count=%d]\n" |
693 | "One of leaked entries details: " | ||
694 | "[device address=0x%016llx] [size=%llu bytes] " | ||
695 | "[mapped with %s] [mapped as %s]\n", | ||
696 | count, entry->dev_addr, entry->size, | ||
697 | dir2name[entry->direction], type2name[entry->type]); | ||
690 | break; | 698 | break; |
691 | default: | 699 | default: |
692 | break; | 700 | break; |
diff --git a/lib/string.c b/lib/string.c index f71bead1be3e..01fad9b203e1 100644 --- a/lib/string.c +++ b/lib/string.c | |||
@@ -535,6 +535,35 @@ bool sysfs_streq(const char *s1, const char *s2) | |||
535 | } | 535 | } |
536 | EXPORT_SYMBOL(sysfs_streq); | 536 | EXPORT_SYMBOL(sysfs_streq); |
537 | 537 | ||
538 | /** | ||
539 | * strtobool - convert common user inputs into boolean values | ||
540 | * @s: input string | ||
541 | * @res: result | ||
542 | * | ||
543 | * This routine returns 0 iff the first character is one of 'Yy1Nn0'. | ||
544 | * Otherwise it will return -EINVAL. Value pointed to by res is | ||
545 | * updated upon finding a match. | ||
546 | */ | ||
547 | int strtobool(const char *s, bool *res) | ||
548 | { | ||
549 | switch (s[0]) { | ||
550 | case 'y': | ||
551 | case 'Y': | ||
552 | case '1': | ||
553 | *res = true; | ||
554 | break; | ||
555 | case 'n': | ||
556 | case 'N': | ||
557 | case '0': | ||
558 | *res = false; | ||
559 | break; | ||
560 | default: | ||
561 | return -EINVAL; | ||
562 | } | ||
563 | return 0; | ||
564 | } | ||
565 | EXPORT_SYMBOL(strtobool); | ||
566 | |||
538 | #ifndef __HAVE_ARCH_MEMSET | 567 | #ifndef __HAVE_ARCH_MEMSET |
539 | /** | 568 | /** |
540 | * memset - Fill a region of memory with the given value | 569 | * memset - Fill a region of memory with the given value |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index bc0ac6b333dc..dfd60192bc2e 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -797,7 +797,7 @@ char *uuid_string(char *buf, char *end, const u8 *addr, | |||
797 | return string(buf, end, uuid, spec); | 797 | return string(buf, end, uuid, spec); |
798 | } | 798 | } |
799 | 799 | ||
800 | int kptr_restrict = 1; | 800 | int kptr_restrict __read_mostly; |
801 | 801 | ||
802 | /* | 802 | /* |
803 | * Show a '%p' thing. A kernel extension is that the '%p' is followed | 803 | * Show a '%p' thing. A kernel extension is that the '%p' is followed |