From: Marko O. <d0...@us...> - 2009-10-26 17:05:41
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "kdfs". The branch, make_kdfs_compile has been updated via a555410defc36ea806183bcb78b8f2ab4b50996e (commit) via d6e23fb32b8e9765d0d0afa11b4e9959938d872d (commit) via a19e999ecf51d928bb1cab259ca1534eeca731b4 (commit) from 9567af3f521aeecb16c274127db8e39ef9527c48 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a555410defc36ea806183bcb78b8f2ab4b50996e Author: Marko Obrovac <mar...@in...> Date: Mon Oct 26 17:01:16 2009 +0000 Second part of the patch, forgot to attach unversioned files in the previous commit. diff --git a/Documentation/kgdb/kgdboe-reboot b/Documentation/kgdb/kgdboe-reboot new file mode 100755 index 0000000..83ef8c4 --- /dev/null +++ b/Documentation/kgdb/kgdboe-reboot @@ -0,0 +1,11 @@ +#!/bin/bash + +ADDR=$1 +PORT=6443 +if [ $# -ge 2 ]; then + PORT=$2 +fi + +echo -ne '\003' | nc -u -q 0 $ADDR $PORT > /dev/null +echo -ne '$R0#82' | nc -u -q 0 $ADDR $PORT > /dev/null +echo -ne '+' | nc -u -q 0 $ADDR $PORT > /dev/null diff --git a/Documentation/kgdb/krg-gdbinit b/Documentation/kgdb/krg-gdbinit new file mode 100644 index 0000000..a265f9c --- /dev/null +++ b/Documentation/kgdb/krg-gdbinit @@ -0,0 +1,122 @@ +define offset_of + print &((struct $arg0 *) 0)->$arg1 +end + +define ps + set $inittask = &init_task + set $mthread = &init_task + set $tasks_off = (size_t)&((struct task_struct*) 0)->tasks + set $thread_group_off = (size_t)&((struct task_struct*) 0)->thread_group + set $cont = 1 + while $cont == 1 + set $athread = $mthread + set $subcont = 1 + while $subcont == 1 + printf "%d %s\n", $athread->pid, (char*)$athread->comm + if (int)$athread->thread_group.next == 0 + set $subcont = 0 + else + set $athread = (struct task_struct*)((char*)$athread->thread_group.next-$thread_group_off) + if $athread == $mthread + set $subcont = 0 + end + end + end + set $mthread = (struct task_struct*)((char*)$mthread->tasks.next-$tasks_off) + if $mthread == $inittask + set $cont = 0 + end + end +end +document ps + list all threads and processes in the system +end + +define dmesg + set $i = 0 + set $end_idx = (log_end - 1) & (log_buf_len - 1) + + while ($i < logged_chars) + set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1) + + if ($idx + 100 <= $end_idx) || \ + ($end_idx <= $idx && $idx + 100 < log_buf_len) + printf "%.100s", &log_buf[$idx] + set $i = $i + 100 + else + printf "%c", log_buf[$idx] + set $i = $i + 1 + end + end +end +document dmesg + print the kernel ring buffer +end + +define task + set $t = (struct task_struct *) $arg0 + + printf "Task %d %s:\n", $t->pid, $t->comm + printf " task_struct:\t0x%lx\n", $t + printf " stack:\t0x%lx\n", $t->stack + printf " signal:\t0x%lx\n", $t->signal + printf " sighand:\t0x%lx\n", $t->sighand + printf " mm:\t\t0x%lx\n", $t->mm + printf " files:\t0x%lx\n", $t->files + printf " fs:\t\t0x%lx\n", $t->fs + printf " state:\t0x%lx\n", $t->state + printf " flags:\t0x%x\n", $t->flags +end +document task + print informations on a task given its task_struct address +end + +define taskpid + set $nr = $arg0 + set $s = pidhash_shift + set $hash = $nr + (unsigned long)&init_pid_ns + set $n = $hash + + set $n <<= 18 + set $hash -= $n + set $n <<= 33 + set $hash -= $n + set $n <<= 3 + set $hash += $n + set $n <<= 3 + set $hash -= $n + set $n <<= 4 + set $hash += $n + set $n <<= 2 + set $hash += $n + + set $hash >>= (64 - $s) + + set $pos = pid_hash[$hash].first + while $pos != 0 + set $upid = (struct upid *)((char *)$pos - (char *)&((struct upid *)0)->pid_chain) + if $upid->nr == $nr && $upid->ns == &init_pid_ns + set $pid = (struct pid *)((char *)$upid - (char *)&(((struct pid *)0)->numbers[0])) + loop_break + end + + set $pos = $pos->next + end + + set $t = 0 + if $pos != 0 + set $t = $pid->tasks[0].first + if $t != 0 + set $t = (struct task_struct *)((char *)$t - (char *)&((struct task_struct *)0)->pids[0].node) + end + end + + if $t == 0 + printf "no such task\n" + else + task $t + end +end +document taskpid + print informations on a task given its pid +end diff --git a/Documentation/krg-gdbinit b/Documentation/krg-gdbinit new file mode 100644 index 0000000..f58c9b7 --- /dev/null +++ b/Documentation/krg-gdbinit @@ -0,0 +1,54 @@ +define offset_of + print &((struct $arg0 *) 0)->$arg1 +end + +define ps + set $inittask = &init_task + set $mthread = &init_task + set $tasks_off = (size_t)&((struct task_struct*) 0)->tasks + set $thread_group_off = (size_t)&((struct task_struct*) 0)->thread_group + set $cont = 1 + while $cont == 1 + set $athread = $mthread + set $subcont = 1 + while $subcont == 1 + printf "%d %s\n", $athread->pid, (char*)$athread->comm + if (int)$athread->thread_group.next == 0 + set $subcont = 0 + else + set $athread = (struct task_struct*)((char*)$athread->thread_group.next-$thread_group_off) + if $athread == $mthread + set $subcont = 0 + end + end + end + set $mthread = (struct task_struct*)((char*)$mthread->tasks.next-$tasks_off) + if $mthread == $inittask + set $cont = 0 + end + end +end +document ps + list all threads and processes in the system +end + +define dmesg + set $i = 0 + set $end_idx = (log_end - 1) & (log_buf_len - 1) + + while ($i < logged_chars) + set $idx = (log_end - 1 - logged_chars + $i) & (log_buf_len - 1) + + if ($idx + 100 <= $end_idx) || \ + ($end_idx <= $idx && $idx + 100 < log_buf_len) + printf "%.100s", &log_buf[$idx] + set $i = $i + 100 + else + printf "%c", log_buf[$idx] + set $i = $i + 1 + end + end +end +document dmesg + print the kernel ring buffer +end diff --git a/drivers/net/kgdboe.c b/drivers/net/kgdboe.c new file mode 100644 index 0000000..939797a --- /dev/null +++ b/drivers/net/kgdboe.c @@ -0,0 +1,286 @@ +/* + * drivers/net/kgdboe.c + * + * A network interface for GDB. + * Based upon 'gdbserial' by David Grothe <da...@gc...> + * and Scott Foehner <sfo...@en...> + * + * Maintainer: Jason Wessel <jas...@wi...> + * + * 2004 (c) Amit S. Kale <ami...@li...> + * 2004-2005 (c) MontaVista Software, Inc. + * 2005-2008 (c) Wind River Systems, Inc. + * + * Contributors at various stages not listed above: + * San Mehat <net...@bi...>, Robert Walsh <rj...@du...>, + * wangdi <wa...@cl...>, Matt Mackall <mp...@se...>, + * Pavel Machek <pa...@su...>, Jason Wessel <jas...@wi...> + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include <linux/kernel.h> +#include <linux/interrupt.h> +#include <linux/string.h> +#include <linux/kgdb.h> +#include <linux/netpoll.h> +#include <linux/init.h> + +#include <asm/atomic.h> + +#define IN_BUF_SIZE 512 /* power of 2, please */ +#define OUT_BUF_SIZE 30 /* We don't want to send too big of a packet. */ +#define MAX_CONFIG_LEN 256 + +static char in_buf[IN_BUF_SIZE], out_buf[OUT_BUF_SIZE]; +static int in_head, in_tail, out_count; +static atomic_t in_count; +/* 0 = unconfigured, 1 = netpoll options parsed, 2 = fully configured. */ +static int configured; +static struct kgdb_io local_kgdb_io_ops; +static int use_dynamic_mac; + +MODULE_DESCRIPTION("KGDB driver for network interfaces"); +MODULE_LICENSE("GPL"); +static char config[MAX_CONFIG_LEN]; +static struct kparam_string kps = { + .string = config, + .maxlen = MAX_CONFIG_LEN, +}; + +static void rx_hook(struct netpoll *np, int port, char *msg, int len, + struct sk_buff *skb) +{ + int i; + + np->remote_port = port; + + /* Copy the MAC address if we need to. */ + if (use_dynamic_mac) { + memcpy(np->remote_mac, eth_hdr(skb)->h_source, + sizeof(np->remote_mac)); + use_dynamic_mac = 0; + } + + /* + * This could be GDB trying to attach. But it could also be GDB + * finishing up a session, with kgdb_connected=0 but GDB sending + * an ACK for the final packet. To make sure we don't try and + * make a breakpoint when GDB is leaving, make sure that if + * !kgdb_connected the only len == 1 packet we allow is ^C. + */ + if (!kgdb_connected && (len != 1 || msg[0] == 3)) + kgdb_schedule_breakpoint(); + + for (i = 0; i < len; i++) { + if (msg[i] == 3) + kgdb_schedule_breakpoint(); + + if (atomic_read(&in_count) >= IN_BUF_SIZE) { + /* buffer overflow, clear it */ + in_head = 0; + in_tail = 0; + atomic_set(&in_count, 0); + break; + } + in_buf[in_head++] = msg[i]; + in_head &= (IN_BUF_SIZE - 1); + atomic_inc(&in_count); + } +} + +static struct netpoll np = { + .dev_name = "eth0", + .name = "kgdboe", + .rx_hook = rx_hook, + .local_port = 6443, + .remote_port = 6442, + .remote_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, +}; + +static void eth_pre_exception_handler(void) +{ + /* Increment the module count when the debugger is active */ + if (!kgdb_connected) + try_module_get(THIS_MODULE); + netpoll_set_trap(1); +} + +static void eth_post_exception_handler(void) +{ + /* decrement the module count when the debugger detaches */ + if (!kgdb_connected) + module_put(THIS_MODULE); + netpoll_set_trap(0); +} + +static int eth_get_char(void) +{ + int chr; + + while (atomic_read(&in_count) == 0) + netpoll_poll(&np); + + chr = in_buf[in_tail++]; + in_tail &= (IN_BUF_SIZE - 1); + atomic_dec(&in_count); + return chr; +} + +static void eth_flush_buf(void) +{ + if (out_count && np.dev) { + netpoll_send_udp(&np, out_buf, out_count); + memset(out_buf, 0, sizeof(out_buf)); + out_count = 0; + } +} + +static void eth_put_char(u8 chr) +{ + out_buf[out_count++] = chr; + if (out_count == OUT_BUF_SIZE) + eth_flush_buf(); +} + +static int option_setup(char *opt) +{ + char opt_scratch[MAX_CONFIG_LEN]; + + configured = 0; + /* If we're being given a new configuration, copy it in. */ + if (opt != config) + strcpy(config, opt); + + if (opt[0] == '\0') + return 1; + + /* But work on a copy as netpoll_parse_options will eat it. */ + strcpy(opt_scratch, opt); + configured = !netpoll_parse_options(&np, opt_scratch); + + use_dynamic_mac = 1; + + return 0; +} +__setup("kgdboe=", option_setup); + +/* With our config string set by some means, configure kgdboe. */ +static int configure_kgdboe(void) +{ + if (option_setup(config)) + return 0; + + if (!configured) { + printk(KERN_ERR "kgdboe: configuration incorrect - kgdboe not " + "loaded.\n"); + printk(KERN_ERR " Usage: kgdboe=[src-port]@[src-ip]/[dev]," + "[tgt-port]@<tgt-ip>/<tgt-macaddr>\n"); + return -EINVAL; + } + + /* Bring it up. */ + if (netpoll_setup(&np)) { + printk(KERN_ERR "kgdboe: netpoll_setup failed kgdboe failed\n"); + return -EINVAL; + } + + if (kgdb_register_io_module(&local_kgdb_io_ops)) { + netpoll_cleanup(&np); + return -EINVAL; + } + + configured = 2; + + return 0; +} + +static int init_kgdboe(void) +{ + int ret; + + /* Already done? */ + if (configured == 2) + return 0; + + /* OK, go ahead and do it. */ + ret = configure_kgdboe(); + + if (configured == 2) + printk(KERN_INFO "kgdboe: debugging over ethernet enabled\n"); + + return ret; +} + +static void cleanup_kgdboe(void) +{ + netpoll_cleanup(&np); + configured = 0; + kgdb_unregister_io_module(&local_kgdb_io_ops); +} + +static int param_set_kgdboe_var(const char *kmessage, struct kernel_param *kp) +{ + char kmessage_save[MAX_CONFIG_LEN]; + int len = strlen(kmessage); + + if (len >= MAX_CONFIG_LEN) { + printk(KERN_ERR "kgdboc: config string too long\n"); + return -ENOSPC; + } + + if (kgdb_connected) { + printk(KERN_ERR "kgdboe: Cannot reconfigure while KGDB is " + "connected.\n"); + return 0; + } + + /* Start the reconfiguration process by saving the old string */ + strncpy(kmessage_save, config, sizeof(kmessage_save)); + + + /* Copy in the new param and strip out invalid characters so we + * can optionally specify the MAC. + */ + strcpy(config, kmessage); + /* Chop out \n char as a result of echo */ + if (config[len - 1] == '\n') + config[len - 1] = '\0'; + + len--; + while (len > 0 && (config[len] < ',' || config[len] > 'f')) { + config[len] = '\0'; + len--; + } + + if (configured == 2) { + cleanup_kgdboe(); + configured = 0; + } + if (config[0] == '\0') + return 0; + + configure_kgdboe(); + + if (configured != 2) + return -EINVAL; + + return 0; +} + +static struct kgdb_io local_kgdb_io_ops = { + .name = "kgdboe", + .read_char = eth_get_char, + .write_char = eth_put_char, + .flush = eth_flush_buf, + .pre_exception = eth_pre_exception_handler, + .post_exception = eth_post_exception_handler +}; + +module_init(init_kgdboe); +module_exit(cleanup_kgdboe); +module_param_call(kgdboe, param_set_kgdboe_var, param_get_string, &kps, 0644); +MODULE_PARM_DESC(kgdboe, "[src-port]@[src-ip]/[dev]," + "[tgt-port]@<tgt-ip>/<tgt-macaddr>"); commit d6e23fb32b8e9765d0d0afa11b4e9959938d872d Author: Marko Obrovac <mar...@in...> Date: Mon Oct 26 16:59:40 2009 +0000 Apply patches that will allow us to manipulate the kgdb stuff over ethernet, rather then over rs232 diff --git a/Documentation/DocBook/kgdb.tmpl b/Documentation/DocBook/kgdb.tmpl index 5cff41a..4010f59 100644 --- a/Documentation/DocBook/kgdb.tmpl +++ b/Documentation/DocBook/kgdb.tmpl @@ -216,6 +216,61 @@ </para> </sect2> </sect1> + <sect1 id="kgdboe"> + <title>Kernel parameter: kgdboe</title> + <para> + The term kgdboe is meant to stand for kgdb over ethernet. To use + kgdboe, the ethernet driver must have implemented the NETPOLL API, + and the kernel must be compiled with NETPOLL support. Also kgdboe + uses unicast udp. This means your debug host needs to be on the + same lan as the target system you wish to debug. + </para> + <para> + NOTE: Even though an ethernet driver may implement the NETPOLL API + it is possible that kgdboe will not work as a robust debug method. + Trying to debug the network stack for instance, would likely hang + the kernel. Also certain IRQ resources cannot be easily shared + between the normal kernel operation and the "polled context" where + the system is stopped by kgdb. Using kgdboe with preemptible IRQ + handlers for the device kgdboe is using is known to have with the + system hanging for instance. + </para> + <para> + The kgdboe parameter string is as follows: + <constant>kgdboe=[src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]</constant> + where: + <itemizedlist> + <listitem><para>src-port (optional): source for UDP packets (defaults to <constant>6443</constant>)</para></listitem> + <listitem><para>src-ip (optional unless from boot): source IP to use (interface address)</para></listitem> + <listitem><para>dev (optional): network interface (<constant>eth0</constant>)</para></listitem> + <listitem><para>tgt-port (optional): port GDB will use (defaults to <constant>6442</constant>)</para></listitem> + <listitem><para>tgt-ip: IP address GDB will be connecting from</para></listitem> + <listitem><para>tgt-macaddr (optional): ethernet MAC address for logging agent (default is broadcast)</para></listitem> + </itemizedlist> + </para> + <para> + What follows are several examples of how to configure kgdboe in various ways. + <itemizedlist> + <listitem><para>From boot with target ip = 10.0.2.15 and debug host ip = 10.0.2.2</para> + <para><constant>kgdboe=@10.0.2.15/,@10.0.2.2/</constant></para> + </listitem> + <listitem><para>From boot using eth1, with target ip = 10.0.2.15 and debug host ip = 10.0.2.2</para> + <para><constant>kgdboe=@10.0.2.15/eth1,@10.0.2.2/</constant></para> + </listitem> + <listitem><para>As a module, with target ip = 10.0.2.15 and debug host ip = 10.0.2.2. NOTE: The src ip is only required when booting with kgdboe enabled</para> + <para><constant>kgdboe=@/,@10.0.2.2/</constant></para> + </listitem> + </itemizedlist> + </para> + <para> + You can also reconfigure kgdboe dynamically at run time as follows: + <itemizedlist> + <listitem> + <para><constant>echo "@/,@10.0.2.2/" > /sys/module/kgdboe/paramters/kgdboe</constant></para> + </listitem> + </itemizedlist> + </para> + </sect1> <sect1 id="kgdbcon"> <title>Kernel parameter: kgdbcon</title> <para> @@ -240,7 +295,7 @@ </para> <para> IMPORTANT NOTE: Using this option with kgdb over the console - (kgdboc) is not supported. + (kgdboc) or kgdb over ethernet (kgdboe) is not supported. </para> </sect1> </chapter> @@ -273,6 +328,13 @@ (gdb) target remote 192.168.2.2:2012 </programlisting> <para> + Example (kgdb over ethernet): + </para> + <programlisting> + % gdb ./vmlinux + (gdb) target remote udp:192.168.2.2:6443 + </programlisting> + <para> Once connected, you can debug a kernel the way you would debug an application program. </para> diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fd5cac0..4e36df0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1068,6 +1068,13 @@ and is between 256 and 4096 characters. It is defined in the file (only serial suported for now) Format: <serial_device>[,baud] + kgdboe= [HW] Setup the local ip information and host ip + information when the network driver supports + NETPOLL and kgdboe is configured as a built in. + Options are: + [src-port]@<src-ip>/[dev],[tgt-port]@<tgt-ip>/<tgt-mac> + IE: kgdboe=@10.0.1.2/,@10.0.0.1.3/ + kmac= [MIPS] korina ethernet MAC address. Configure the RouterBoard 532 series on-chip Ethernet adapter MAC address. diff --git a/drivers/net/Makefile b/drivers/net/Makefile index a1c25cb..2f80256 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -262,6 +262,7 @@ obj-$(CONFIG_ETRAX_ETHERNET) += cris/ obj-$(CONFIG_ENP2611_MSF_NET) += ixp2000/ obj-$(CONFIG_NETCONSOLE) += netconsole.o +obj-$(CONFIG_KGDBOE) += kgdboe.o obj-$(CONFIG_FS_ENET) += fs_enet/ diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h index 6adcc29..8fdd3cb 100644 --- a/include/linux/kgdb.h +++ b/include/linux/kgdb.h @@ -279,5 +279,6 @@ extern int kgdb_nmicallback(int cpu, void *regs); extern int kgdb_single_step; extern atomic_t kgdb_active; +extern void kgdb_schedule_breakpoint(void); #endif /* _KGDB_H_ */ diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 2524267..fec2dd2 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h @@ -16,7 +16,7 @@ struct netpoll { struct net_device *dev; char dev_name[IFNAMSIZ]; const char *name; - void (*rx_hook)(struct netpoll *, int, char *, int); + void (*rx_hook)(struct netpoll *, int, char *, int, struct sk_buff *); __be32 local_ip, remote_ip; u16 local_port, remote_port; diff --git a/kernel/kgdb.c b/kernel/kgdb.c index 9147a31..e39f886 100644 --- a/kernel/kgdb.c +++ b/kernel/kgdb.c @@ -123,6 +123,7 @@ atomic_t kgdb_active = ATOMIC_INIT(-1); */ static atomic_t passive_cpu_wait[NR_CPUS]; static atomic_t cpu_in_kgdb[NR_CPUS]; +static atomic_t kgdb_break_tasklet_var; atomic_t kgdb_setting_breakpoint; struct task_struct *kgdb_usethread; @@ -828,6 +829,12 @@ static int kgdb_io_ready(int print_wait) * where KGDB is communicating with an external debugger */ +/* Handle the '!' extended mode request */ +static void gdb_cmd_extended(struct kgdb_state *ks) +{ + strcpy(remcom_out_buffer, "OK"); +} + /* Handle the '?' status packets */ static void gdb_cmd_status(struct kgdb_state *ks) { @@ -1251,6 +1258,9 @@ static int gdb_serial_stub(struct kgdb_state *ks) get_packet(remcom_in_buffer); switch (remcom_in_buffer[0]) { + case '!': /* extended mode */ + gdb_cmd_extended(ks); + break; case '?': /* gdbserial status */ gdb_cmd_status(ks); break; @@ -1588,11 +1598,49 @@ static struct sysrq_key_op sysrq_gdb_op = { }; #endif +static int +kgdb_notify_reboot(struct notifier_block *this, unsigned long code, void *x) +{ + unsigned long flags; + + if (!kgdb_connected) + return 0; + + if (code == SYS_RESTART || code == SYS_HALT || code == SYS_POWER_OFF) { + local_irq_save(flags); + if (kgdb_io_ops->write_char) { + /* Do not use put_packet to avoid hanging + * in case the attached debugger disappeared + * or does not respond timely. + */ + kgdb_io_ops->write_char('$'); + kgdb_io_ops->write_char('X'); + kgdb_io_ops->write_char('0'); + kgdb_io_ops->write_char('0'); + kgdb_io_ops->write_char('#'); + kgdb_io_ops->write_char('b'); + kgdb_io_ops->write_char('8'); + if (kgdb_io_ops->flush) + kgdb_io_ops->flush(); + } + kgdb_connected = 0; + local_irq_restore(flags); + } + return NOTIFY_DONE; +} + +static struct notifier_block kgdb_reboot_notifier = { + .notifier_call = kgdb_notify_reboot, + .next = NULL, + .priority = INT_MAX, +}; + static void kgdb_register_callbacks(void) { if (!kgdb_io_module_registered) { kgdb_io_module_registered = 1; kgdb_arch_init(); + register_reboot_notifier(&kgdb_reboot_notifier); #ifdef CONFIG_MAGIC_SYSRQ register_sysrq_key('g', &sysrq_gdb_op); #endif @@ -1611,6 +1659,7 @@ static void kgdb_unregister_callbacks(void) * break exceptions at the time. */ if (kgdb_io_module_registered) { + unregister_reboot_notifier(&kgdb_reboot_notifier); kgdb_io_module_registered = 0; kgdb_arch_exit(); #ifdef CONFIG_MAGIC_SYSRQ @@ -1623,6 +1672,31 @@ static void kgdb_unregister_callbacks(void) } } +/* + * There are times a tasklet needs to be used vs a compiled in in + * break point so as to cause an exception outside a kgdb I/O module, + * such as is the case with kgdboe, where calling a breakpoint in the + * I/O driver itself would be fatal. + */ +static void kgdb_tasklet_bpt(unsigned long ing) +{ + kgdb_breakpoint(); + atomic_set(&kgdb_break_tasklet_var, 0); +} + +static DECLARE_TASKLET(kgdb_tasklet_breakpoint, kgdb_tasklet_bpt, 0); + +void kgdb_schedule_breakpoint(void) +{ + if (atomic_read(&kgdb_break_tasklet_var) || + atomic_read(&kgdb_active) != -1 || + atomic_read(&kgdb_setting_breakpoint)) + return; + atomic_inc(&kgdb_break_tasklet_var); + tasklet_schedule(&kgdb_tasklet_breakpoint); +} +EXPORT_SYMBOL_GPL(kgdb_schedule_breakpoint); + static void kgdb_initial_breakpoint(void) { kgdb_break_asap = 0; diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index 9b5d1d7..fe5010b 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb @@ -27,6 +27,17 @@ config KGDB_SERIAL_CONSOLE Share a serial console with kgdb. Sysrq-g must be used to break in initially. +config KGDBOE + tristate "KGDB: On ethernet" + depends on KGDB + select NETPOLL + select NETPOLL_TRAP + help + Uses the NETPOLL API to communicate with the host GDB via UDP. + In order for this to work, the ethernet interface specified must + support the NETPOLL API, and this must be initialized at boot. + See the documentation for syntax. + config KGDB_TESTS bool "KGDB: internal test suite" default n diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 64f51ee..f703332 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -546,7 +546,8 @@ int __netpoll_rx(struct sk_buff *skb) np->rx_hook(np, ntohs(uh->source), (char *)(uh+1), - ulen - sizeof(struct udphdr)); + ulen - sizeof(struct udphdr), + skb); kfree_skb(skb); return 1; commit a19e999ecf51d928bb1cab259ca1534eeca731b4 Author: Marko Obrovac <mar...@in...> Date: Mon Oct 26 16:55:52 2009 +0000 Fixed a minor semantic bug which prevented us from seeing any debug from kDFS diff --git a/fs/kdfs/debug_kdfs.h b/fs/kdfs/debug_kdfs.h index 51bf3b0..a5a377c 100644 --- a/fs/kdfs/debug_kdfs.h +++ b/fs/kdfs/debug_kdfs.h @@ -40,7 +40,7 @@ #else # define DEBUG(level, format, args...) \ do { \ - if (KDFS_DEBUG_LEVEL <= level || level == DBG_PANIC) { \ + if (KDFS_DEBUG_LEVEL >= level || level == DBG_PANIC) { \ pr_debug("%s - (%s) - %d : ", KDFS_PART, __PRETTY_FUNCTION__, \ current->pid) ; \ pr_debug(format, ## args) ; \ ----------------------------------------------------------------------- Summary of changes: Documentation/DocBook/kgdb.tmpl | 64 ++++++++- Documentation/kernel-parameters.txt | 7 + Documentation/kgdb/kgdboe-reboot | 11 ++ Documentation/kgdb/krg-gdbinit | 122 +++++++++++++++ Documentation/krg-gdbinit | 54 +++++++ drivers/net/Makefile | 1 + drivers/net/kgdboe.c | 286 +++++++++++++++++++++++++++++++++++ fs/kdfs/debug_kdfs.h | 2 +- include/linux/kgdb.h | 1 + include/linux/netpoll.h | 2 +- kernel/kgdb.c | 74 +++++++++ lib/Kconfig.kgdb | 11 ++ net/core/netpoll.c | 3 +- 13 files changed, 634 insertions(+), 4 deletions(-) create mode 100755 Documentation/kgdb/kgdboe-reboot create mode 100644 Documentation/kgdb/krg-gdbinit create mode 100644 Documentation/krg-gdbinit create mode 100644 drivers/net/kgdboe.c hooks/post-receive -- kdfs |