23 Oct, 2010

1 commit

  • For quite some time there have been problems with memory barriers and
    various races with NMI on multi processor systems using the kernel
    debugger. The algorithm for entering the kernel debug core and
    resuming kernel execution was racy and had several known edge case
    problems with attempting to debug something on a heavily loaded system
    using breakpoints that are hit repeatedly and quickly.

    The prior "locking" design entry worked as follows:

    * The atomic counter kgdb_active was used with atomic exchange in
    order to elect a master cpu out of all the cpus that may have
    taken a debug exception.
    * The master cpu increments all elements of passive_cpu_wait[].
    * The master cpu issues the round up cpus message.
    * Each "slave cpu" that enters the debug core increments its own
    element in cpu_in_kgdb[].
    * Each "slave cpu" spins on passive_cpu_wait[] until it becomes 0.
    * The master cpu debugs the system.

    The new scheme removes the two arrays of atomic counters and replaces
    them with 2 single counters. One counter is used to count the number
    of cpus waiting to become a master cpu (because one or more hit an
    exception). The second counter is use to indicate how many cpus have
    entered as slave cpus.

    The new entry logic works as follows:

    * One or more cpus enters via kgdb_handle_exception() and increments
    the masters_in_kgdb. Each cpu attempts to get the spin lock called
    dbg_master_lock.
    * The master cpu sets kgdb_active to the current cpu.
    * The master cpu takes the spinlock dbg_slave_lock.
    * The master cpu asks to round up all the other cpus.
    * Each slave cpu that is not already in kgdb_handle_exception()
    will enter and increment slaves_in_kgdb. Each slave will now spin
    try_locking on dbg_slave_lock.
    * The master cpu waits for the sum of masters_in_kgdb and slaves_in_kgdb
    to be equal to the sum of the online cpus.
    * The master cpu debugs the system.

    In the new design the kgdb_active can only be changed while holding
    dbg_master_lock. Stress testing has not turned up any further
    entry/exit races that existed in the prior locking design. The prior
    locking design suffered from atomic variables not being truly atomic
    (in the capacity as used by kgdb) along with memory barrier races.

    Signed-off-by: Jason Wessel
    Acked-by: Dongdong Deng

    Jason Wessel
     

21 May, 2010

3 commits

  • One of the driving forces behind integrating another front end (kdb)
    to the debug core is to allow front end commands to be accessible via
    gdb's monitor command. It is true that you could write gdb macros to
    get certain data, but you may want to just use gdb to access the
    commands that are available in the kdb front end.

    This patch implements the Rcmd gdb stub packet. In gdb you access
    this with the "monitor" command. For instance you could type "monitor
    help", "monitor lsmod" or "monitor ps A" etc...

    There is no error checking or command restrictions on what you can and
    cannot access at this point. Doing something like trying to set
    breakpoints with the monitor command is going to cause nothing but
    problems. Perhaps in the future only the commands that are actually
    known to work with the gdb monitor command will be available.

    Signed-off-by: Jason Wessel

    Jason Wessel
     
  • These are the minimum changes to the kgdb core in order to enable an
    API to connect a new front end (kdb) to the debug core.

    This patch introduces the dbg_kdb_mode variable controls where the
    user level I/O is routed. It will be routed to the gdbstub (kgdb) or
    to the kdb front end which is a simple shell available over the kgdboc
    connection.

    You can switch back and forth between kdb or the gdb stub mode of
    operation dynamically. From gdb stub mode you can blindly type
    "$3#33", or from the kdb mode you can enter "kgdb" to switch to the
    gdb stub.

    The logic in the debug core depends on kdb to look for the typical gdb
    connection sequences and return immediately with KGDB_PASS_EVENT if a
    gdb serial command sequence is detected. That should allow a
    reasonably seamless transition between kdb -> gdb without leaving the
    kernel exception state. The two gdb serial queries that kdb is
    responsible for detecting are the "?" and "qSupported" packets.

    CC: Ingo Molnar
    Signed-off-by: Jason Wessel
    Acked-by: Martin Hicks

    Jason Wessel
     
  • Split the former kernel/kgdb.c into debug_core.c which contains the
    kernel debugger exception logic and to the gdbstub.c which contains
    the logic for allowing gdb to talk to the debug core.

    This also created a private include file called debug_core.h which
    contains all the definitions to glue the debug_core to any other
    debugger connections.

    CC: Ingo Molnar
    Signed-off-by: Jason Wessel

    Jason Wessel