26 Jan, 2008

1 commit

  • this patch extends the soft-lockup detector to automatically
    detect hung TASK_UNINTERRUPTIBLE tasks. Such hung tasks are
    printed the following way:

    ------------------>
    INFO: task prctl:3042 blocked for more than 120 seconds.
    "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message
    prctl D fd5e3793 0 3042 2997
    f6050f38 00000046 00000001 fd5e3793 00000009 c06d8264 c06dae80 00000286
    f6050f40 f6050f00 f7d34d90 f7d34fc8 c1e1be80 00000001 f6050000 00000000
    f7e92d00 00000286 f6050f18 c0489d1a f6050f40 00006605 00000000 c0133a5b
    Call Trace:
    [] schedule_timeout+0x6d/0x8b
    [] schedule_timeout_uninterruptible+0x15/0x17
    [] msleep+0x10/0x16
    [] sys_prctl+0x30/0x1e2
    [] sysenter_past_esp+0x5f/0xa5
    =======================
    2 locks held by prctl/3042:
    #0: (&sb->s_type->i_mutex_key#5){--..}, at: [] do_fsync+0x38/0x7a
    #1: (jbd_handle){--..}, at: [] journal_start+0xc7/0xe9
    : CPU hotplug fixes. ]
    [ Andrew Morton : build warning fix. ]

    Signed-off-by: Ingo Molnar
    Signed-off-by: Arjan van de Ven

    Ingo Molnar
     

25 Jan, 2008

1 commit

  • Michael Wu noticed in his lkml post at

    http://marc.info/?l=linux-kernel&m=119396182726091&w=2

    that certain wireless drivers ended up having their name in module
    memory, which would then crash the kernel on module unload.

    The patch he proposed was a bit clumsy in that it increased the size of
    a lockdep entry significantly; the patch below tries another approach,
    it checks, on module teardown, if the name of a class is in module space
    and then zaps the class. This is very similar to what we already do
    with keys that are in module space.

    Signed-off-by: Arjan van de Ven
    Signed-off-by: Ingo Molnar
    Acked-by: Peter Zijlstra
    Signed-off-by: Linus Torvalds

    Arjan van de Ven
     

16 Jan, 2008

1 commit


08 Dec, 2007

1 commit


05 Dec, 2007

2 commits

  • Torsten Kaiser wrote:

    | static inline int in_range(const void *start, const void *addr, const void *end)
    | {
    | return addr >= start && addr mem_to is the last byte of the freed range, that fits in_range
    | lock_from = (void *)hlock->instance;
    | -> first byte of the lock
    | lock_to = (void *)(hlock->instance + 1);
    | -> first byte of the next lock, not last byte of the lock that is being checked!
    |
    | The test is:
    | if (!in_range(mem_from, lock_from, mem_to) &&
    | !in_range(mem_from, lock_to, mem_to))
    | continue;
    | So it tests, if the first byte of the lock is in the range that is freed ->OK
    | And if the first byte of the *next* lock is in the range that is freed
    | -> Not OK.

    We can also simplify in_range checks, we need only 2 comparisons, not 4.
    If the lock is not in memory range, it should be either at the left of range
    or at the right.

    Signed-off-by: Oleg Nesterov
    Signed-off-by: Ingo Molnar
    Signed-off-by: Peter Zijlstra

    Oleg Nesterov
     
  • fix the oops that can be seen in:

    http://bugzilla.kernel.org/attachment.cgi?id=13828&action=view

    it is not safe to print the locks of running tasks.

    (even with this fix we have a small race - but this is a debug
    function after all.)

    Signed-off-by: Ingo Molnar
    Signed-off-by: Peter Zijlstra

    Ingo Molnar
     

29 Oct, 2007

1 commit


20 Oct, 2007

2 commits

  • The task_struct->pid member is going to be deprecated, so start
    using the helpers (task_pid_nr/task_pid_vnr/task_pid_nr_ns) in
    the kernel.

    The first thing to start with is the pid, printed to dmesg - in
    this case we may safely use task_pid_nr(). Besides, printks produce
    more (much more) than a half of all the explicit pid usage.

    [akpm@linux-foundation.org: git-drm went and changed lots of stuff]
    Signed-off-by: Pavel Emelyanov
    Cc: Dave Airlie
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Pavel Emelyanov
     
  • In the following scenario:

    code path 1:
    my_function() -> lock(L1); ...; flush_workqueue(); ...

    code path 2:
    run_workqueue() -> my_work() -> ...; lock(L1); ...

    you can get a deadlock when my_work() is queued or running
    but my_function() has acquired L1 already.

    This patch adds a pseudo-lock to each workqueue to make lockdep
    warn about this scenario.

    [akpm@linux-foundation.org: coding-style fixes]
    Signed-off-by: Johannes Berg
    Acked-by: Oleg Nesterov
    Acked-by: Ingo Molnar
    Acked-by: Peter Zijlstra
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Johannes Berg
     

12 Oct, 2007

2 commits

  • Provide a check to validate that we do not hold any locks when switching
    back to user-space.

    Signed-off-by: Peter Zijlstra
    Signed-off-by: Ingo Molnar

    Peter Zijlstra
     
  • It is possible for the current->curr_chain_key to become inconsistent with the
    current index if the chain fails to validate. The end result is that future
    lock_acquire() operations may inadvertently fail to find a hit in the cache
    resulting in a new node being added to the graph for every acquire.

    Signed-off-by: Gregory Haskins
    Signed-off-by: Peter Zijlstra
    Signed-off-by: Ingo Molnar

    Gregory Haskins
     

20 Jul, 2007

7 commits

  • When I started adding support for lockdep to 64-bit powerpc, I got a
    lockdep_init_error and with this patch was able to pinpoint why and where
    to put lockdep_init(). Let's support this generally for others adding
    lockdep support to their architecture.

    Signed-off-by: Johannes Berg
    Cc: Ingo Molnar
    Cc: Peter Zijlstra
    Cc: Arjan van de Ven
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Johannes Berg
     
  • __acquire
    |
    lock _____
    | \
    | __contended
    | |
    | wait
    | _______/
    |/
    |
    __acquired
    |
    __release
    |
    unlock

    We measure acquisition and contention bouncing.

    This is done by recording a cpu stamp in each lock instance.

    Contention bouncing requires the cpu stamp to be set on acquisition. Hence we
    move __acquired into the generic path.

    __acquired is then used to measure acquisition bouncing by comparing the
    current cpu with the old stamp before replacing it.

    __contended is used to measure contention bouncing (only useful for preemptable
    locks)

    [akpm@linux-foundation.org: cleanups]
    Signed-off-by: Peter Zijlstra
    Acked-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Peter Zijlstra
     
  • - update the copyright notices
    - use the default hash function
    - fix a thinko in a BUILD_BUG_ON
    - add a WARN_ON to spot inconsitent naming
    - fix a termination issue in /proc/lock_stat

    [akpm@linux-foundation.org: cleanups]
    Signed-off-by: Peter Zijlstra
    Acked-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Peter Zijlstra
     
  • Present all this fancy new lock statistics information:

    *warning, _wide_ output ahead*

    (output edited for purpose of brevity)

    # cat /proc/lock_stat
    lock_stat version 0.1
    -----------------------------------------------------------------------------------------------------------------------------------------------------------------
    class name contentions waittime-min waittime-max waittime-total acquisitions holdtime-min holdtime-max holdtime-total
    -----------------------------------------------------------------------------------------------------------------------------------------------------------------

    &inode->i_mutex: 14458 6.57 398832.75 2469412.23 6768876 0.34 11398383.65 339410830.89
    ---------------
    &inode->i_mutex 4486 [] pipe_wait+0x86/0x8d
    &inode->i_mutex 0 [] pipe_write_fasync+0x29/0x5d
    &inode->i_mutex 0 [] pipe_read+0x74/0x3a5
    &inode->i_mutex 0 [] do_lookup+0x81/0x1ae

    .................................................................................................................................................................

    &inode->i_data.tree_lock-W: 491 0.27 62.47 493.89 2477833 0.39 468.89 1146584.25
    &inode->i_data.tree_lock-R: 65 0.44 4.27 48.78 26288792 0.36 184.62 10197458.24
    --------------------------
    &inode->i_data.tree_lock 46 [] __do_page_cache_readahead+0x69/0x24f
    &inode->i_data.tree_lock 31 [] add_to_page_cache+0x31/0xba
    &inode->i_data.tree_lock 0 [] __do_page_cache_readahead+0xc2/0x24f
    &inode->i_data.tree_lock 0 [] find_get_page+0x1a/0x58

    .................................................................................................................................................................

    proc_inum_idr.lock: 0 0.00 0.00 0.00 36 0.00 65.60 148.26
    proc_subdir_lock: 0 0.00 0.00 0.00 3049859 0.00 106.81 1563212.42
    shrinker_rwsem-W: 0 0.00 0.00 0.00 5 0.00 1.73 3.68
    shrinker_rwsem-R: 0 0.00 0.00 0.00 633 2.57 246.57 10909.76

    'contentions' and 'acquisitions' are the number of such events measured (since
    the last reset). The waittime- and holdtime- (min, max, total) numbers are
    presented in microseconds.

    If there are any contention points, the lock class is presented in the block
    format (as i_mutex and tree_lock above), otherwise a single line of output is
    presented.

    The output is sorted on absolute number of contentions (read + write), this
    should get the worst offenders presented first, so that:

    # grep : /proc/lock_stat | head

    will quickly show who's bad.

    The stats can be reset using:

    # echo 0 > /proc/lock_stat

    [bunk@stusta.de: make 2 functions static]
    [akpm@linux-foundation.org: fix printk warning]
    Signed-off-by: Peter Zijlstra
    Acked-by: Ingo Molnar
    Acked-by: Jason Baron
    Signed-off-by: Adrian Bunk
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Peter Zijlstra
     
  • Introduce the core lock statistics code.

    Lock statistics provides lock wait-time and hold-time (as well as the count
    of corresponding contention and acquisitions events). Also, the first few
    call-sites that encounter contention are tracked.

    Lock wait-time is the time spent waiting on the lock. This provides insight
    into the locking scheme, that is, a heavily contended lock is indicative of
    a too coarse locking scheme.

    Lock hold-time is the duration the lock was held, this provides a reference for
    the wait-time numbers, so they can be put into perspective.

    1)
    lock
    2)
    ... do stuff ..
    unlock
    3)

    The time between 1 and 2 is the wait-time. The time between 2 and 3 is the
    hold-time.

    The lockdep held-lock tracking code is reused, because it already collects locks
    into meaningful groups (classes), and because it is an existing infrastructure
    for lock instrumentation.

    Currently lockdep tracks lock acquisition with two hooks:

    lock()
    lock_acquire()
    _lock()

    ... code protected by lock ...

    unlock()
    lock_release()
    _unlock()

    We need to extend this with two more hooks, in order to measure contention.

    lock_contended() - used to measure contention events
    lock_acquired() - completion of the contention

    These are then placed the following way:

    lock()
    lock_acquire()
    if (!_try_lock())
    lock_contended()
    _lock()
    lock_acquired()

    ... do locked stuff ...

    unlock()
    lock_release()
    _unlock()

    (Note: the try_lock() 'trick' is used to avoid instrumenting all platform
    dependent lock primitive implementations.)

    It is also possible to toggle the two lockdep features at runtime using:

    /proc/sys/kernel/prove_locking
    /proc/sys/kernel/lock_stat

    (esp. turning off the O(n^2) prove_locking functionaliy can help)

    [akpm@linux-foundation.org: build fixes]
    [akpm@linux-foundation.org: nuke unneeded ifdefs]
    Signed-off-by: Peter Zijlstra
    Acked-by: Ingo Molnar
    Acked-by: Jason Baron
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Peter Zijlstra
     
  • Move code around to get fewer but larger #ifdef sections. Break some
    in-function #ifdefs out into their own functions.

    Signed-off-by: Peter Zijlstra
    Acked-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Peter Zijlstra
     
  • Ensure that all of the lock dependency tracking code is under
    CONFIG_PROVE_LOCKING. This allows us to use the held lock tracking code for
    other purposes.

    Signed-off-by: Peter Zijlstra
    Acked-by: Ingo Molnar
    Acked-by: Jason Baron
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Peter Zijlstra
     

18 Jul, 2007

1 commit

  • KSYM_NAME_LEN is peculiar in that it does not include the space for the
    trailing '\0', forcing all users to use KSYM_NAME_LEN + 1 when allocating
    buffer. This is nonsense and error-prone. Moreover, when the caller
    forgets that it's very likely to subtly bite back by corrupting the stack
    because the last position of the buffer is always cleared to zero.

    This patch increments KSYM_NAME_LEN by one and updates code accordingly.

    * off-by-one bug in asm-powerpc/kprobes.h::kprobe_lookup_name() macro
    is fixed.

    * Where MODULE_NAME_LEN and KSYM_NAME_LEN were used together,
    MODULE_NAME_LEN was treated as if it didn't include space for the
    trailing '\0'. Fix it.

    Signed-off-by: Tejun Heo
    Acked-by: Paulo Marques
    Cc: Benjamin Herrenschmidt
    Cc: Paul Mackerras
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Tejun Heo
     

09 May, 2007

4 commits


23 Mar, 2007

1 commit

  • lockdep's data shouldn't be used when debug_locks == 0 because it's not
    updated after this, so it's more misleading than helpful.

    PS: probably lockdep's current-> fields should be reset after it turns
    debug_locks off: so, after printing a bug report, but before return from
    exported functions, but there are really a lot of these possibilities (e.g.
    after DEBUG_LOCKS_WARN_ON), so, something could be missed. (Of course
    direct use of this fields isn't recommended either.)

    Reported-by: Folkert van Heusden
    Inspired-by: Oleg Nesterov
    Signed-off-by: Jarek Poplawski
    Acked-by: Peter Zijlstra
    Cc: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jarek Poplawski
     

02 Mar, 2007

1 commit

  • lockdep_init() is marked __init but used in several places
    outside __init code. This causes following warnings:
    $ scripts/mod/modpost kernel/lockdep.o
    WARNING: kernel/built-in.o - Section mismatch: reference to .init.text:lockdep_init from .text.lockdep_init_map after 'lockdep_init_map' (at offset 0x105)
    WARNING: kernel/built-in.o - Section mismatch: reference to .init.text:lockdep_init from .text.lockdep_reset_lock after 'lockdep_reset_lock' (at offset 0x35)
    WARNING: kernel/built-in.o - Section mismatch: reference to .init.text:lockdep_init from .text.__lock_acquire after '__lock_acquire' (at offset 0xb2)

    The warnings are less obviously due to heavy inlining by gcc - this is not
    altered.

    Fix the section mismatch warnings by removing the __init marking, which
    seems obviously wrong.

    Signed-off-by: Sam Ravnborg
    Acked-by: Ingo Molnar
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sam Ravnborg
     

21 Feb, 2007

1 commit


12 Feb, 2007

2 commits

  • Generate locking graph information into /proc/lockdep, for lock hierarchy
    documentation and visualization purposes.

    sample output:

    c089fd5c OPS: 138 FD: 14 BD: 1 --..: &tty->termios_mutex
    -> [c07a3430] tty_ldisc_lock
    -> [c07a37f0] &port_lock_key
    -> [c07afdc0] &rq->rq_lock_key#2

    The lock classes listed are all the first-hop lock dependencies that
    lockdep has seen so far.

    Signed-off-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jason Baron
     
  • - returns after DEBUG_LOCKS_WARN_ON added in 3 places

    - debug_locks checking after lookup_chain_cache() added in
    __lock_acquire()

    - locking for testing and changing global variable max_lockdep_depth
    added in __lock_acquire()

    From: Ingo Molnar

    My __acquire_lock() cleanup introduced a locking bug: on SMP systems we'd
    release a non-owned graph lock. Fix this by moving the graph unlock back,
    and by leaving the max_lockdep_depth variable update possibly racy. (we
    dont care, it's just statistics)

    Also add some minimal debugging code to graph_unlock()/graph_lock(),
    which caught this locking bug.

    Signed-off-by: Jarek Poplawski
    Signed-off-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jarek Poplawski
     

31 Dec, 2006

1 commit

  • kernel/lockdep.c: In function `lookup_chain_cache':
    kernel/lockdep.c:1339: warning: long long unsigned int format, u64 arg (arg 2)
    kernel/lockdep.c:1344: warning: long long unsigned int format, u64 arg (arg 2)

    Cc: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrew Morton
     

14 Dec, 2006

7 commits

  • Jarek Poplawski noticed that lockdep global state could be accessed in a
    racy way if one CPU did a lockdep assert (shutting lockdep down), while the
    other CPU would try to do something that changes its global state.

    This patch fixes those races and cleans up lockdep's internal locking by
    adding a graph_lock()/graph_unlock()/debug_locks_off_graph_unlock helpers.

    (Also note that as we all know the Linux kernel is, by definition, bug-free
    and perfect, so this code never triggers, so these fixes are highly
    theoretical. I wrote this patch for aesthetic reasons alone.)

    [akpm@osdl.org: build fix]
    [jarkao2@o2.pl: build fix's refix]
    Signed-off-by: Ingo Molnar
    Signed-off-by: Jarek Poplawski
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     
  • When we print an assert due to scheduling-in-atomic bugs, and if lockdep
    is enabled, then the IRQ tracing information of lockdep can be printed
    to pinpoint the code location that disabled interrupts. This saved me
    quite a bit of debugging time in cases where the backtrace did not
    identify the irq-disabling site well enough.

    Signed-off-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     
  • CONFIG_DEBUG_LOCKDEP is unacceptably slow because it does not utilize
    the chain-hash. Turn the chain-hash back on in this case too.

    Signed-off-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     
  • Cleanup: the VERY_VERBOSE define was unnecessarily dependent on #ifdef VERBOSE
    - while the VERBOSE switch is 0 or 1 (always defined).

    Signed-off-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     
  • Clear all the chains during lockdep_reset(). This fixes some locking-selftest
    false positives i saw on -rt. (never saw those on mainline though, but it
    could happen.)

    Signed-off-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     
  • Make verbose lockdep messages (off by default) more informative by printing
    out the hash chain key. (this patch was what helped me catch the earlier
    lockdep hash-collision bug)

    Signed-off-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     
  • Fix typo in the class_filter() function. (filtering is not used by default so
    this only affects lockdep-internal debugging cases)

    Signed-off-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     

08 Dec, 2006

4 commits

  • * 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6: (156 commits)
    [PATCH] x86-64: Export smp_call_function_single
    [PATCH] i386: Clean up smp_tune_scheduling()
    [PATCH] unwinder: move .eh_frame to RODATA
    [PATCH] unwinder: fully support linker generated .eh_frame_hdr section
    [PATCH] x86-64: don't use set_irq_regs()
    [PATCH] x86-64: check vector in setup_ioapic_dest to verify if need setup_IO_APIC_irq
    [PATCH] x86-64: Make ix86 default to HIGHMEM4G instead of NOHIGHMEM
    [PATCH] i386: replace kmalloc+memset with kzalloc
    [PATCH] x86-64: remove remaining pc98 code
    [PATCH] x86-64: remove unused variable
    [PATCH] x86-64: Fix constraints in atomic_add_return()
    [PATCH] x86-64: fix asm constraints in i386 atomic_add_return
    [PATCH] x86-64: Correct documentation for bzImage protocol v2.05
    [PATCH] x86-64: replace kmalloc+memset with kzalloc in MTRR code
    [PATCH] x86-64: Fix numaq build error
    [PATCH] x86-64: include/asm-x86_64/cpufeature.h isn't a userspace header
    [PATCH] unwinder: Add debugging output to the Dwarf2 unwinder
    [PATCH] x86-64: Clarify error message in GART code
    [PATCH] x86-64: Fix interrupt race in idle callback (3rd try)
    [PATCH] x86-64: Remove unwind stack pointer alignment forcing again
    ...

    Fixed conflict in include/linux/uaccess.h manually

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     
  • The hash_lock must only ever be taken with irqs disabled. This happens in
    all the important places, except one codepath: register_lock_class(). The
    race should trigger rarely because register_lock_class() is quite rare and
    single-threaded (happens during init most of the time).

    The fix is to disable irqs.

    ( bug found live in -rt: there preemption is alot more agressive and
    preempting with the hash-lock held caused a lockup.)

    Signed-off-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ingo Molnar
     
  • Remove the no longer used lockdep_internal().

    Signed-off-by: Adrian Bunk
    Acked-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Adrian Bunk
     
  • - numeric string size replaced with constant in print_lock_name and
    print_lockdep_cache,

    - return on null pointer in print_lock_dependencies,

    - one more lockdep return with 0 with unlocking fix in mark_lock.

    Signed-off-by: Jarek Poplawski
    Acked-by: Ingo Molnar
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Jarek Poplawski