summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig.debug60
-rw-r--r--lib/Makefile3
-rw-r--r--lib/bitmap.c2
-rw-r--r--lib/bsearch.c53
-rw-r--r--lib/btree.c4
-rw-r--r--lib/decompress_unxz.c2
-rw-r--r--lib/dma-debug.c18
-rw-r--r--lib/flex_array.c24
-rw-r--r--lib/kstrtox.c9
-rw-r--r--lib/parser.c2
-rw-r--r--lib/string.c29
-rw-r--r--lib/test-kstrtox.c32
-rw-r--r--lib/timerqueue.c2
-rw-r--r--lib/vsprintf.c11
-rw-r--r--lib/xz/xz_dec_lzma2.c6
15 files changed, 171 insertions, 86 deletions
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index df9234c5f9d1..0efcdca9751a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -7,7 +7,8 @@ config PRINTK_TIME
included in printk output. This allows you to measure
the interval between kernel operations, including bootup
operations. This is useful for identifying long delays
- in kernel startup.
+ in kernel startup. Or add printk.time=1 at boot-time.
+ See Documentation/kernel-parameters.txt
config DEFAULT_MESSAGE_LOGLEVEL
int "Default message log level (1-7)"
@@ -238,6 +239,21 @@ config DETECT_HUNG_TASK
enabled then all held locks will also be reported. This
feature has negligible overhead.
+config DEFAULT_HUNG_TASK_TIMEOUT
+ int "Default timeout for hung task detection (in seconds)"
+ depends on DETECT_HUNG_TASK
+ default 120
+ help
+ This option controls the default timeout (in seconds) used
+ to determine when a task has become non-responsive and should
+ be considered hung.
+
+ It can be adjusted at runtime via the kernel.hung_task_timeout
+ sysctl or by writing a value to /proc/sys/kernel/hung_task_timeout.
+
+ A timeout of 0 disables the check. The default is two minutes.
+ Keeping the default should be fine in most cases.
+
config BOOTPARAM_HUNG_TASK_PANIC
bool "Panic (Reboot) On Hung Tasks"
depends on DETECT_HUNG_TASK
@@ -337,7 +353,7 @@ config DEBUG_OBJECTS_WORK
config DEBUG_OBJECTS_RCU_HEAD
bool "Debug RCU callbacks objects"
- depends on DEBUG_OBJECTS && PREEMPT
+ depends on DEBUG_OBJECTS
help
Enable this to turn on debugging of RCU list heads (call_rcu() usage).
@@ -398,9 +414,9 @@ config SLUB_STATS
config DEBUG_KMEMLEAK
bool "Kernel memory leak detector"
depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \
- (X86 || ARM || PPC || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE)
+ (X86 || ARM || PPC || MIPS || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE)
- select DEBUG_FS if SYSFS
+ select DEBUG_FS
select STACKTRACE if STACKTRACE_SUPPORT
select KALLSYMS
select CRC32
@@ -434,11 +450,9 @@ config DEBUG_KMEMLEAK_EARLY_LOG_SIZE
config DEBUG_KMEMLEAK_TEST
tristate "Simple test for the kernel memory leak detector"
- depends on DEBUG_KMEMLEAK
+ depends on DEBUG_KMEMLEAK && m
help
- Say Y or M here to build a test for the kernel memory leak
- detector. This option enables a module that explicitly leaks
- memory.
+ This option enables a module that explicitly leaks memory.
If unsure, say N.
@@ -877,22 +891,9 @@ config RCU_TORTURE_TEST_RUNNABLE
Say N here if you want the RCU torture tests to start only
after being manually enabled via /proc.
-config RCU_CPU_STALL_DETECTOR
- bool "Check for stalled CPUs delaying RCU grace periods"
- depends on TREE_RCU || TREE_PREEMPT_RCU
- default y
- help
- This option causes RCU to printk information on which
- CPUs are delaying the current grace period, but only when
- the grace period extends for excessive time periods.
-
- Say N if you want to disable such checks.
-
- Say Y if you are unsure.
-
config RCU_CPU_STALL_TIMEOUT
int "RCU CPU stall timeout in seconds"
- depends on RCU_CPU_STALL_DETECTOR
+ depends on TREE_RCU || TREE_PREEMPT_RCU
range 3 300
default 60
help
@@ -901,22 +902,9 @@ config RCU_CPU_STALL_TIMEOUT
RCU grace period persists, additional CPU stall warnings are
printed at more widely spaced intervals.
-config RCU_CPU_STALL_DETECTOR_RUNNABLE
- bool "RCU CPU stall checking starts automatically at boot"
- depends on RCU_CPU_STALL_DETECTOR
- default y
- help
- If set, start checking for RCU CPU stalls immediately on
- boot. Otherwise, RCU CPU stall checking must be manually
- enabled.
-
- Say Y if you are unsure.
-
- Say N if you wish to suppress RCU CPU stall checking during boot.
-
config RCU_CPU_STALL_VERBOSE
bool "Print additional per-task information for RCU_CPU_STALL_DETECTOR"
- depends on RCU_CPU_STALL_DETECTOR && TREE_PREEMPT_RCU
+ depends on TREE_PREEMPT_RCU
default y
help
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
obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \
bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \
- string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o
+ string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o \
+ bsearch.o
obj-y += kstrtox.o
obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
diff --git a/lib/bitmap.c b/lib/bitmap.c
index 741fae905ae3..91e0ccfdb424 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -830,7 +830,7 @@ EXPORT_SYMBOL(bitmap_bitremap);
* @orig (i.e. bits 3, 5, 7 and 9) were also set.
*
* When bit 11 is set in @orig, it means turn on the bit in
- * @dst corresponding to whatever is the twelth bit that is
+ * @dst corresponding to whatever is the twelfth bit that is
* turned on in @relmap. In the above example, there were
* only ten bits turned on in @relmap (30..39), so that bit
* 11 was set in @orig had no affect on @dst.
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 @@
+/*
+ * A generic implementation of binary search for the Linux kernel
+ *
+ * Copyright (C) 2008-2009 Ksplice, Inc.
+ * Author: Tim Abbott <tabbott@ksplice.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2.
+ */
+
+#include <linux/module.h>
+#include <linux/bsearch.h>
+
+/*
+ * bsearch - binary search an array of elements
+ * @key: pointer to item being searched for
+ * @base: pointer to first element to search
+ * @num: number of elements
+ * @size: size of each element
+ * @cmp: pointer to comparison function
+ *
+ * This function does a binary search on the given array. The
+ * contents of the array should already be in ascending sorted order
+ * under the provided comparison function.
+ *
+ * Note that the key need not have the same type as the elements in
+ * the array, e.g. key could be a string and the comparison function
+ * could compare the string with the struct's name field. However, if
+ * the key and elements in the array are of the same type, you can use
+ * the same comparison function for both sort() and bsearch().
+ */
+void *bsearch(const void *key, const void *base, size_t num, size_t size,
+ int (*cmp)(const void *key, const void *elt))
+{
+ size_t start = 0, end = num;
+ int result;
+
+ while (start < end) {
+ size_t mid = start + (end - start) / 2;
+
+ result = cmp(key, base + mid * size);
+ if (result < 0)
+ end = mid;
+ else if (result > 0)
+ start = mid + 1;
+ else
+ return (void *)base + mid * size;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(bsearch);
diff --git a/lib/btree.c b/lib/btree.c
index c9c6f0351526..2a34392bcecc 100644
--- a/lib/btree.c
+++ b/lib/btree.c
@@ -11,7 +11,7 @@
* see http://programming.kicks-ass.net/kernel-patches/vma_lookup/btree.patch
*
* A relatively simple B+Tree implementation. I have written it as a learning
- * excercise to understand how B+Trees work. Turned out to be useful as well.
+ * exercise to understand how B+Trees work. Turned out to be useful as well.
*
* B+Trees can be used similar to Linux radix trees (which don't have anything
* in common with textbook radix trees, beware). Prerequisite for them working
@@ -541,7 +541,7 @@ static void rebalance(struct btree_head *head, struct btree_geo *geo,
int i, no_left, no_right;
if (fill == 0) {
- /* Because we don't steal entries from a neigbour, this case
+ /* Because we don't steal entries from a neighbour, this case
* can happen. Parent node contains a single child, this
* node, so merging with a sibling never happens.
*/
diff --git a/lib/decompress_unxz.c b/lib/decompress_unxz.c
index cecd23df2b9a..9f34eb56854d 100644
--- a/lib/decompress_unxz.c
+++ b/lib/decompress_unxz.c
@@ -83,7 +83,7 @@
* safety_margin = 128 + uncompressed_size * 8 / 32768 + 65536
* = 128 + (uncompressed_size >> 12) + 65536
*
- * For comparision, according to arch/x86/boot/compressed/misc.c, the
+ * For comparison, according to arch/x86/boot/compressed/misc.c, the
* equivalent formula for Deflate is this:
*
* safety_margin = 18 + (uncompressed_size >> 12) + 32768
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:
return -ENOMEM;
}
-static int device_dma_allocations(struct device *dev)
+static int device_dma_allocations(struct device *dev, struct dma_debug_entry **out_entry)
{
struct dma_debug_entry *entry;
unsigned long flags;
@@ -660,8 +660,10 @@ static int device_dma_allocations(struct device *dev)
for (i = 0; i < HASH_SIZE; ++i) {
spin_lock(&dma_entry_hash[i].lock);
list_for_each_entry(entry, &dma_entry_hash[i].list, list) {
- if (entry->dev == dev)
+ if (entry->dev == dev) {
count += 1;
+ *out_entry = entry;
+ }
}
spin_unlock(&dma_entry_hash[i].lock);
}
@@ -674,6 +676,7 @@ static int device_dma_allocations(struct device *dev)
static int dma_debug_device_change(struct notifier_block *nb, unsigned long action, void *data)
{
struct device *dev = data;
+ struct dma_debug_entry *uninitialized_var(entry);
int count;
if (global_disable)
@@ -681,12 +684,17 @@ static int dma_debug_device_change(struct notifier_block *nb, unsigned long acti
switch (action) {
case BUS_NOTIFY_UNBOUND_DRIVER:
- count = device_dma_allocations(dev);
+ count = device_dma_allocations(dev, &entry);
if (count == 0)
break;
- err_printk(dev, NULL, "DMA-API: device driver has pending "
+ err_printk(dev, entry, "DMA-API: device driver has pending "
"DMA allocations while released from device "
- "[count=%d]\n", count);
+ "[count=%d]\n"
+ "One of leaked entries details: "
+ "[device address=0x%016llx] [size=%llu bytes] "
+ "[mapped with %s] [mapped as %s]\n",
+ count, entry->dev_addr, entry->size,
+ dir2name[entry->direction], type2name[entry->type]);
break;
default:
break;
diff --git a/lib/flex_array.c b/lib/flex_array.c
index c0ea40ba2082..854b57bd7d9d 100644
--- a/lib/flex_array.c
+++ b/lib/flex_array.c
@@ -232,10 +232,10 @@ EXPORT_SYMBOL(flex_array_clear);
/**
* flex_array_prealloc - guarantee that array space exists
- * @fa: the flex array for which to preallocate parts
- * @start: index of first array element for which space is allocated
- * @end: index of last (inclusive) element for which space is allocated
- * @flags: page allocation flags
+ * @fa: the flex array for which to preallocate parts
+ * @start: index of first array element for which space is allocated
+ * @nr_elements: number of elements for which space is allocated
+ * @flags: page allocation flags
*
* This will guarantee that no future calls to flex_array_put()
* will allocate memory. It can be used if you are expecting to
@@ -245,14 +245,24 @@ EXPORT_SYMBOL(flex_array_clear);
* Locking must be provided by the caller.
*/
int flex_array_prealloc(struct flex_array *fa, unsigned int start,
- unsigned int end, gfp_t flags)
+ unsigned int nr_elements, gfp_t flags)
{
int start_part;
int end_part;
int part_nr;
+ unsigned int end;
struct flex_array_part *part;
- if (start >= fa->total_nr_elements || end >= fa->total_nr_elements)
+ if (!start && !nr_elements)
+ return 0;
+ if (start >= fa->total_nr_elements)
+ return -ENOSPC;
+ if (!nr_elements)
+ return 0;
+
+ end = start + nr_elements - 1;
+
+ if (end >= fa->total_nr_elements)
return -ENOSPC;
if (elements_fit_in_base(fa))
return 0;
@@ -343,6 +353,8 @@ int flex_array_shrink(struct flex_array *fa)
int part_nr;
int ret = 0;
+ if (!fa->total_nr_elements)
+ return 0;
if (elements_fit_in_base(fa))
return ret;
for (part_nr = 0; part_nr < FLEX_ARRAY_NR_BASE_PTRS; part_nr++) {
diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index 05672e819f8c..a235f3cc471c 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -49,12 +49,9 @@ static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res)
val = *s - '0';
else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f')
val = _tolower(*s) - 'a' + 10;
- else if (*s == '\n') {
- if (*(s + 1) == '\0')
- break;
- else
- return -EINVAL;
- } else
+ else if (*s == '\n' && *(s + 1) == '\0')
+ break;
+ else
return -EINVAL;
if (val >= base)
diff --git a/lib/parser.c b/lib/parser.c
index 6e89eca5cca0..dcbaaef6cf11 100644
--- a/lib/parser.c
+++ b/lib/parser.c
@@ -13,7 +13,7 @@
/**
* match_one: - Determines if a string matches a simple pattern
- * @s: the string to examine for presense of the pattern
+ * @s: the string to examine for presence of the pattern
* @p: the string containing the pattern
* @args: array of %MAX_OPT_ARGS &substring_t elements. Used to return match
* locations.
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)
}
EXPORT_SYMBOL(sysfs_streq);
+/**
+ * strtobool - convert common user inputs into boolean values
+ * @s: input string
+ * @res: result
+ *
+ * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
+ * Otherwise it will return -EINVAL. Value pointed to by res is
+ * updated upon finding a match.
+ */
+int strtobool(const char *s, bool *res)
+{
+ switch (s[0]) {
+ case 'y':
+ case 'Y':
+ case '1':
+ *res = true;
+ break;
+ case 'n':
+ case 'N':
+ case '0':
+ *res = false;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(strtobool);
+
#ifndef __HAVE_ARCH_MEMSET
/**
* memset - Fill a region of memory with the given value
diff --git a/lib/test-kstrtox.c b/lib/test-kstrtox.c
index 325c2f9ecebd..d55769d63cb8 100644
--- a/lib/test-kstrtox.c
+++ b/lib/test-kstrtox.c
@@ -315,12 +315,12 @@ static void __init test_kstrtou64_ok(void)
{"65537", 10, 65537},
{"2147483646", 10, 2147483646},
{"2147483647", 10, 2147483647},
- {"2147483648", 10, 2147483648},
- {"2147483649", 10, 2147483649},
- {"4294967294", 10, 4294967294},
- {"4294967295", 10, 4294967295},
- {"4294967296", 10, 4294967296},
- {"4294967297", 10, 4294967297},
+ {"2147483648", 10, 2147483648ULL},
+ {"2147483649", 10, 2147483649ULL},
+ {"4294967294", 10, 4294967294ULL},
+ {"4294967295", 10, 4294967295ULL},
+ {"4294967296", 10, 4294967296ULL},
+ {"4294967297", 10, 4294967297ULL},
{"9223372036854775806", 10, 9223372036854775806ULL},
{"9223372036854775807", 10, 9223372036854775807ULL},
{"9223372036854775808", 10, 9223372036854775808ULL},
@@ -369,12 +369,12 @@ static void __init test_kstrtos64_ok(void)
{"65537", 10, 65537},
{"2147483646", 10, 2147483646},
{"2147483647", 10, 2147483647},
- {"2147483648", 10, 2147483648},
- {"2147483649", 10, 2147483649},
- {"4294967294", 10, 4294967294},
- {"4294967295", 10, 4294967295},
- {"4294967296", 10, 4294967296},
- {"4294967297", 10, 4294967297},
+ {"2147483648", 10, 2147483648LL},
+ {"2147483649", 10, 2147483649LL},
+ {"4294967294", 10, 4294967294LL},
+ {"4294967295", 10, 4294967295LL},
+ {"4294967296", 10, 4294967296LL},
+ {"4294967297", 10, 4294967297LL},
{"9223372036854775806", 10, 9223372036854775806LL},
{"9223372036854775807", 10, 9223372036854775807LL},
};
@@ -418,10 +418,10 @@ static void __init test_kstrtou32_ok(void)
{"65537", 10, 65537},
{"2147483646", 10, 2147483646},
{"2147483647", 10, 2147483647},
- {"2147483648", 10, 2147483648},
- {"2147483649", 10, 2147483649},
- {"4294967294", 10, 4294967294},
- {"4294967295", 10, 4294967295},
+ {"2147483648", 10, 2147483648U},
+ {"2147483649", 10, 2147483649U},
+ {"4294967294", 10, 4294967294U},
+ {"4294967295", 10, 4294967295U},
};
TEST_OK(kstrtou32, u32, "%u", test_u32_ok);
}
diff --git a/lib/timerqueue.c b/lib/timerqueue.c
index e3a1050e6820..191176a43e9a 100644
--- a/lib/timerqueue.c
+++ b/lib/timerqueue.c
@@ -5,7 +5,7 @@
* Uses rbtrees for quick list adds and expiration.
*
* NOTE: All of the following functions need to be serialized
- * to avoid races. No locking is done by this libary code.
+ * to avoid races. No locking is done by this library code.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
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,
return string(buf, end, uuid, spec);
}
-int kptr_restrict = 1;
+int kptr_restrict __read_mostly;
/*
* Show a '%p' thing. A kernel extension is that the '%p' is followed
@@ -1161,8 +1161,7 @@ qualifier:
* return is greater than or equal to @size, the resulting
* string is truncated.
*
- * Call this function if you are already dealing with a va_list.
- * You probably want snprintf() instead.
+ * If you're not already dealing with a va_list consider using snprintf().
*/
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
@@ -1336,8 +1335,7 @@ EXPORT_SYMBOL(vsnprintf);
* the @buf not including the trailing '\0'. If @size is == 0 the function
* returns 0.
*
- * Call this function if you are already dealing with a va_list.
- * You probably want scnprintf() instead.
+ * If you're not already dealing with a va_list consider using scnprintf().
*
* See the vsnprintf() documentation for format string extensions over C99.
*/
@@ -1416,8 +1414,7 @@ EXPORT_SYMBOL(scnprintf);
* into @buf. Use vsnprintf() or vscnprintf() in order to avoid
* buffer overflows.
*
- * Call this function if you are already dealing with a va_list.
- * You probably want sprintf() instead.
+ * If you're not already dealing with a va_list consider using sprintf().
*
* See the vsnprintf() documentation for format string extensions over C99.
*/
diff --git a/lib/xz/xz_dec_lzma2.c b/lib/xz/xz_dec_lzma2.c
index ea5fa4fe9d67..a6cdc969ea42 100644
--- a/lib/xz/xz_dec_lzma2.c
+++ b/lib/xz/xz_dec_lzma2.c
@@ -969,6 +969,9 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
*/
tmp = b->in[b->in_pos++];
+ if (tmp == 0x00)
+ return XZ_STREAM_END;
+
if (tmp >= 0xE0 || tmp == 0x01) {
s->lzma2.need_props = true;
s->lzma2.need_dict_reset = false;
@@ -1001,9 +1004,6 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
lzma_reset(s);
}
} else {
- if (tmp == 0x00)
- return XZ_STREAM_END;
-
if (tmp > 0x02)
return XZ_DATA_ERROR;