diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/Kconfig.debug | 54 | ||||
| -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 | 11 |
6 files changed, 123 insertions, 45 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index c768bcdda1b7..0efcdca9751a 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -7,7 +7,8 @@ config PRINTK_TIME | |||
| 7 | included in printk output. This allows you to measure | 7 | included in printk output. This allows you to measure |
| 8 | the interval between kernel operations, including bootup | 8 | the interval between kernel operations, including bootup |
| 9 | operations. This is useful for identifying long delays | 9 | operations. This is useful for identifying long delays |
| 10 | in kernel startup. | 10 | in kernel startup. Or add printk.time=1 at boot-time. |
| 11 | See Documentation/kernel-parameters.txt | ||
| 11 | 12 | ||
| 12 | config DEFAULT_MESSAGE_LOGLEVEL | 13 | config DEFAULT_MESSAGE_LOGLEVEL |
| 13 | int "Default message log level (1-7)" | 14 | int "Default message log level (1-7)" |
| @@ -238,6 +239,21 @@ config DETECT_HUNG_TASK | |||
| 238 | enabled then all held locks will also be reported. This | 239 | enabled then all held locks will also be reported. This |
| 239 | feature has negligible overhead. | 240 | feature has negligible overhead. |
| 240 | 241 | ||
| 242 | config DEFAULT_HUNG_TASK_TIMEOUT | ||
| 243 | int "Default timeout for hung task detection (in seconds)" | ||
| 244 | depends on DETECT_HUNG_TASK | ||
| 245 | default 120 | ||
| 246 | help | ||
| 247 | This option controls the default timeout (in seconds) used | ||
| 248 | to determine when a task has become non-responsive and should | ||
| 249 | be considered hung. | ||
| 250 | |||
| 251 | It can be adjusted at runtime via the kernel.hung_task_timeout | ||
| 252 | sysctl or by writing a value to /proc/sys/kernel/hung_task_timeout. | ||
| 253 | |||
| 254 | A timeout of 0 disables the check. The default is two minutes. | ||
| 255 | Keeping the default should be fine in most cases. | ||
| 256 | |||
| 241 | config BOOTPARAM_HUNG_TASK_PANIC | 257 | config BOOTPARAM_HUNG_TASK_PANIC |
| 242 | bool "Panic (Reboot) On Hung Tasks" | 258 | bool "Panic (Reboot) On Hung Tasks" |
| 243 | depends on DETECT_HUNG_TASK | 259 | depends on DETECT_HUNG_TASK |
| @@ -337,7 +353,7 @@ config DEBUG_OBJECTS_WORK | |||
| 337 | 353 | ||
| 338 | config DEBUG_OBJECTS_RCU_HEAD | 354 | config DEBUG_OBJECTS_RCU_HEAD |
| 339 | bool "Debug RCU callbacks objects" | 355 | bool "Debug RCU callbacks objects" |
| 340 | depends on DEBUG_OBJECTS && PREEMPT | 356 | depends on DEBUG_OBJECTS |
| 341 | help | 357 | help |
| 342 | Enable this to turn on debugging of RCU list heads (call_rcu() usage). | 358 | Enable this to turn on debugging of RCU list heads (call_rcu() usage). |
| 343 | 359 | ||
| @@ -398,9 +414,9 @@ config SLUB_STATS | |||
| 398 | config DEBUG_KMEMLEAK | 414 | config DEBUG_KMEMLEAK |
| 399 | bool "Kernel memory leak detector" | 415 | bool "Kernel memory leak detector" |
| 400 | depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ | 416 | depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \ |
| 401 | (X86 || ARM || PPC || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE) | 417 | (X86 || ARM || PPC || MIPS || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE) |
| 402 | 418 | ||
| 403 | select DEBUG_FS if SYSFS | 419 | select DEBUG_FS |
| 404 | select STACKTRACE if STACKTRACE_SUPPORT | 420 | select STACKTRACE if STACKTRACE_SUPPORT |
| 405 | select KALLSYMS | 421 | select KALLSYMS |
| 406 | select CRC32 | 422 | select CRC32 |
| @@ -875,22 +891,9 @@ config RCU_TORTURE_TEST_RUNNABLE | |||
| 875 | Say N here if you want the RCU torture tests to start only | 891 | Say N here if you want the RCU torture tests to start only |
| 876 | after being manually enabled via /proc. | 892 | after being manually enabled via /proc. |
| 877 | 893 | ||
| 878 | config RCU_CPU_STALL_DETECTOR | ||
| 879 | bool "Check for stalled CPUs delaying RCU grace periods" | ||
| 880 | depends on TREE_RCU || TREE_PREEMPT_RCU | ||
| 881 | default y | ||
| 882 | help | ||
| 883 | This option causes RCU to printk information on which | ||
| 884 | CPUs are delaying the current grace period, but only when | ||
| 885 | the grace period extends for excessive time periods. | ||
| 886 | |||
| 887 | Say N if you want to disable such checks. | ||
| 888 | |||
| 889 | Say Y if you are unsure. | ||
| 890 | |||
| 891 | config RCU_CPU_STALL_TIMEOUT | 894 | config RCU_CPU_STALL_TIMEOUT |
| 892 | int "RCU CPU stall timeout in seconds" | 895 | int "RCU CPU stall timeout in seconds" |
| 893 | depends on RCU_CPU_STALL_DETECTOR | 896 | depends on TREE_RCU || TREE_PREEMPT_RCU |
| 894 | range 3 300 | 897 | range 3 300 |
| 895 | default 60 | 898 | default 60 |
| 896 | help | 899 | help |
| @@ -899,22 +902,9 @@ config RCU_CPU_STALL_TIMEOUT | |||
| 899 | RCU grace period persists, additional CPU stall warnings are | 902 | RCU grace period persists, additional CPU stall warnings are |
| 900 | printed at more widely spaced intervals. | 903 | printed at more widely spaced intervals. |
| 901 | 904 | ||
| 902 | config RCU_CPU_STALL_DETECTOR_RUNNABLE | ||
| 903 | bool "RCU CPU stall checking starts automatically at boot" | ||
| 904 | depends on RCU_CPU_STALL_DETECTOR | ||
| 905 | default y | ||
| 906 | help | ||
| 907 | If set, start checking for RCU CPU stalls immediately on | ||
| 908 | boot. Otherwise, RCU CPU stall checking must be manually | ||
| 909 | enabled. | ||
| 910 | |||
| 911 | Say Y if you are unsure. | ||
| 912 | |||
| 913 | Say N if you wish to suppress RCU CPU stall checking during boot. | ||
| 914 | |||
| 915 | config RCU_CPU_STALL_VERBOSE | 905 | config RCU_CPU_STALL_VERBOSE |
| 916 | bool "Print additional per-task information for RCU_CPU_STALL_DETECTOR" | 906 | bool "Print additional per-task information for RCU_CPU_STALL_DETECTOR" |
| 917 | depends on RCU_CPU_STALL_DETECTOR && TREE_PREEMPT_RCU | 907 | depends on TREE_PREEMPT_RCU |
| 918 | default y | 908 | default y |
| 919 | help | 909 | help |
| 920 | This option causes RCU to printk detailed per-task information | 910 | This option causes RCU to printk detailed per-task information |
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..1d659d7bb0f8 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 |
| @@ -1161,8 +1161,7 @@ qualifier: | |||
| 1161 | * return is greater than or equal to @size, the resulting | 1161 | * return is greater than or equal to @size, the resulting |
| 1162 | * string is truncated. | 1162 | * string is truncated. |
| 1163 | * | 1163 | * |
| 1164 | * Call this function if you are already dealing with a va_list. | 1164 | * If you're not already dealing with a va_list consider using snprintf(). |
| 1165 | * You probably want snprintf() instead. | ||
| 1166 | */ | 1165 | */ |
| 1167 | int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | 1166 | int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) |
| 1168 | { | 1167 | { |
| @@ -1336,8 +1335,7 @@ EXPORT_SYMBOL(vsnprintf); | |||
| 1336 | * the @buf not including the trailing '\0'. If @size is == 0 the function | 1335 | * the @buf not including the trailing '\0'. If @size is == 0 the function |
| 1337 | * returns 0. | 1336 | * returns 0. |
| 1338 | * | 1337 | * |
| 1339 | * Call this function if you are already dealing with a va_list. | 1338 | * If you're not already dealing with a va_list consider using scnprintf(). |
| 1340 | * You probably want scnprintf() instead. | ||
| 1341 | * | 1339 | * |
| 1342 | * See the vsnprintf() documentation for format string extensions over C99. | 1340 | * See the vsnprintf() documentation for format string extensions over C99. |
| 1343 | */ | 1341 | */ |
| @@ -1416,8 +1414,7 @@ EXPORT_SYMBOL(scnprintf); | |||
| 1416 | * into @buf. Use vsnprintf() or vscnprintf() in order to avoid | 1414 | * into @buf. Use vsnprintf() or vscnprintf() in order to avoid |
| 1417 | * buffer overflows. | 1415 | * buffer overflows. |
| 1418 | * | 1416 | * |
| 1419 | * Call this function if you are already dealing with a va_list. | 1417 | * If you're not already dealing with a va_list consider using sprintf(). |
| 1420 | * You probably want sprintf() instead. | ||
| 1421 | * | 1418 | * |
| 1422 | * See the vsnprintf() documentation for format string extensions over C99. | 1419 | * See the vsnprintf() documentation for format string extensions over C99. |
| 1423 | */ | 1420 | */ |
