Merge branch 'linus' into core/softlockup

Conflicts:

	kernel/softlockup.c

Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Ingo Molnar
2008-07-15 23:12:58 +02:00
2669 zmienionych plików z 173740 dodań i 98825 usunięć

Wyświetl plik

@@ -443,7 +443,6 @@ config DEBUG_LOCKING_API_SELFTESTS
config STACKTRACE
bool
depends on DEBUG_KERNEL
depends on STACKTRACE_SUPPORT
config DEBUG_KOBJECT
@@ -587,6 +586,9 @@ config BACKTRACE_SELF_TEST
for distributions or general kernels, but only for kernel
developers working on architecture code.
Note that if you want to also test saved backtraces, you will
have to enable STACKTRACE as well.
Say N if you are unsure.
config LKDTM
@@ -658,6 +660,8 @@ config LATENCYTOP
Enable this option if you want to use the LatencyTOP tool
to find out which userspace is blocking on what kernel operations.
source kernel/trace/Kconfig
config PROVIDE_OHCI1394_DMA_INIT
bool "Remote debugging over FireWire early on boot"
depends on PCI && X86

Wyświetl plik

@@ -8,6 +8,15 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
sha1.o irq_regs.o reciprocal_div.o argv_split.o \
proportions.o prio_heap.o ratelimit.o
ifdef CONFIG_FTRACE
# Do not profile string.o, since it may be used in early boot or vdso
CFLAGS_REMOVE_string.o = -pg
# Also do not profile any debug utilities
CFLAGS_REMOVE_spinlock_debug.o = -pg
CFLAGS_REMOVE_list_debug.o = -pg
CFLAGS_REMOVE_debugobjects.o = -pg
endif
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o

Wyświetl plik

@@ -37,6 +37,7 @@
*/
#include <linux/list.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/bug.h>
#include <linux/sched.h>
@@ -149,6 +150,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
(void *)bugaddr);
show_regs(regs);
add_taint(TAINT_WARN);
return BUG_TRAP_TYPE_WARN;
}

Wyświetl plik

@@ -68,6 +68,7 @@ static int fill_pool(void)
{
gfp_t gfp = GFP_ATOMIC | __GFP_NORETRY | __GFP_NOWARN;
struct debug_obj *new;
unsigned long flags;
if (likely(obj_pool_free >= ODEBUG_POOL_MIN_LEVEL))
return obj_pool_free;
@@ -81,10 +82,10 @@ static int fill_pool(void)
if (!new)
return obj_pool_free;
spin_lock(&pool_lock);
spin_lock_irqsave(&pool_lock, flags);
hlist_add_head(&new->node, &obj_pool);
obj_pool_free++;
spin_unlock(&pool_lock);
spin_unlock_irqrestore(&pool_lock, flags);
}
return obj_pool_free;
}
@@ -110,16 +111,13 @@ static struct debug_obj *lookup_object(void *addr, struct debug_bucket *b)
}
/*
* Allocate a new object. If the pool is empty and no refill possible,
* switch off the debugger.
* Allocate a new object. If the pool is empty, switch off the debugger.
*/
static struct debug_obj *
alloc_object(void *addr, struct debug_bucket *b, struct debug_obj_descr *descr)
{
struct debug_obj *obj = NULL;
int retry = 0;
repeat:
spin_lock(&pool_lock);
if (obj_pool.first) {
obj = hlist_entry(obj_pool.first, typeof(*obj), node);
@@ -141,9 +139,6 @@ repeat:
}
spin_unlock(&pool_lock);
if (fill_pool() && !obj && !retry++)
goto repeat;
return obj;
}
@@ -261,6 +256,8 @@ __debug_object_init(void *addr, struct debug_obj_descr *descr, int onstack)
struct debug_obj *obj;
unsigned long flags;
fill_pool();
db = get_bucket((unsigned long) addr);
spin_lock_irqsave(&db->lock, flags);

Wyświetl plik

@@ -52,7 +52,7 @@ EXPORT_SYMBOL(__percpu_counter_add);
* Add up all the per-cpu counts, return the result. This is a more accurate
* but much slower version of percpu_counter_read_positive()
*/
s64 __percpu_counter_sum(struct percpu_counter *fbc)
s64 __percpu_counter_sum(struct percpu_counter *fbc, int set)
{
s64 ret;
int cpu;
@@ -62,7 +62,12 @@ s64 __percpu_counter_sum(struct percpu_counter *fbc)
for_each_online_cpu(cpu) {
s32 *pcount = per_cpu_ptr(fbc->counters, cpu);
ret += *pcount;
if (set)
*pcount = 0;
}
if (set)
fbc->count = ret;
spin_unlock(&fbc->lock);
return ret;
}

Wyświetl plik

@@ -1,7 +1,7 @@
/*
* Copyright (C) 2001 Momchil Velikov
* Portions Copyright (C) 2001 Christoph Hellwig
* Copyright (C) 2005 SGI, Christoph Lameter <clameter@sgi.com>
* Copyright (C) 2005 SGI, Christoph Lameter
* Copyright (C) 2006 Nick Piggin
*
* This program is free software; you can redistribute it and/or

Wyświetl plik

@@ -7,7 +7,7 @@
#include <linux/kallsyms.h>
#include <linux/sched.h>
unsigned int debug_smp_processor_id(void)
notrace unsigned int debug_smp_processor_id(void)
{
unsigned long preempt_count = preempt_count();
int this_cpu = raw_smp_processor_id();
@@ -37,7 +37,7 @@ unsigned int debug_smp_processor_id(void)
/*
* Avoid recursion:
*/
preempt_disable();
preempt_disable_notrace();
if (!printk_ratelimit())
goto out_enable;
@@ -49,7 +49,7 @@ unsigned int debug_smp_processor_id(void)
dump_stack();
out_enable:
preempt_enable_no_resched();
preempt_enable_no_resched_notrace();
out:
return this_cpu;
}

Wyświetl plik

@@ -63,7 +63,7 @@ static unsigned int bm_find(struct ts_config *conf, struct ts_state *state)
struct ts_bm *bm = ts_config_priv(conf);
unsigned int i, text_len, consumed = state->offset;
const u8 *text;
int shift = bm->patlen, bs;
int shift = bm->patlen - 1, bs;
for (;;) {
text_len = conf->get_next_block(consumed, &text, conf, state);

Wyświetl plik

@@ -22,6 +22,8 @@
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
#include <asm/page.h> /* for PAGE_SIZE */
#include <asm/div64.h>
@@ -482,6 +484,89 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
return buf;
}
static char *string(char *buf, char *end, char *s, int field_width, int precision, int flags)
{
int len, i;
if ((unsigned long)s < PAGE_SIZE)
s = "<NULL>";
len = strnlen(s, precision);
if (!(flags & LEFT)) {
while (len < field_width--) {
if (buf < end)
*buf = ' ';
++buf;
}
}
for (i = 0; i < len; ++i) {
if (buf < end)
*buf = *s;
++buf; ++s;
}
while (len < field_width--) {
if (buf < end)
*buf = ' ';
++buf;
}
return buf;
}
static inline void *dereference_function_descriptor(void *ptr)
{
#if defined(CONFIG_IA64) || defined(CONFIG_PPC64)
void *p;
if (!probe_kernel_address(ptr, p))
ptr = p;
#endif
return ptr;
}
static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags)
{
unsigned long value = (unsigned long) ptr;
#ifdef CONFIG_KALLSYMS
char sym[KSYM_SYMBOL_LEN];
sprint_symbol(sym, value);
return string(buf, end, sym, field_width, precision, flags);
#else
field_width = 2*sizeof(void *);
flags |= SPECIAL | SMALL | ZEROPAD;
return number(buf, end, value, 16, field_width, precision, flags);
#endif
}
/*
* Show a '%p' thing. A kernel extension is that the '%p' is followed
* by an extra set of alphanumeric characters that are extended format
* specifiers.
*
* Right now we just handle 'F' (for symbolic Function descriptor pointers)
* and 'S' (for Symbolic direct pointers), but this can easily be
* extended in the future (network address types etc).
*
* The difference between 'S' and 'F' is that on ia64 and ppc64 function
* pointers are really function descriptors, which contain a pointer the
* real address.
*/
static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags)
{
switch (*fmt) {
case 'F':
ptr = dereference_function_descriptor(ptr);
/* Fallthrough */
case 'S':
return symbol_string(buf, end, ptr, field_width, precision, flags);
}
flags |= SMALL;
if (field_width == -1) {
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
return number(buf, end, (unsigned long) ptr, 16, field_width, precision, flags);
}
/**
* vsnprintf - Format a string and place it in a buffer
* @buf: The buffer to place the result into
@@ -502,11 +587,9 @@ static char *number(char *buf, char *end, unsigned long long num, int base, int
*/
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
{
int len;
unsigned long long num;
int i, base;
int base;
char *str, *end, c;
const char *s;
int flags; /* flags to number() */
@@ -622,43 +705,18 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
continue;
case 's':
s = va_arg(args, char *);
if ((unsigned long)s < PAGE_SIZE)
s = "<NULL>";
len = strnlen(s, precision);
if (!(flags & LEFT)) {
while (len < field_width--) {
if (str < end)
*str = ' ';
++str;
}
}
for (i = 0; i < len; ++i) {
if (str < end)
*str = *s;
++str; ++s;
}
while (len < field_width--) {
if (str < end)
*str = ' ';
++str;
}
str = string(str, end, va_arg(args, char *), field_width, precision, flags);
continue;
case 'p':
flags |= SMALL;
if (field_width == -1) {
field_width = 2*sizeof(void *);
flags |= ZEROPAD;
}
str = number(str, end,
(unsigned long) va_arg(args, void *),
16, field_width, precision, flags);
str = pointer(fmt+1, str, end,
va_arg(args, void *),
field_width, precision, flags);
/* Skip all alphanumeric pointer suffixes */
while (isalnum(fmt[1]))
fmt++;
continue;
case 'n':
/* FIXME:
* What does C99 say about the overflow case here? */