Skip to content

Commit 996fe06

Browse files
committedSep 7, 2021
Merge tag 'kgdb-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/danielt/linux
Pull kgdb updates from Daniel Thompson: "Changes for kgdb/kdb this cycle are dominated by a change from Sumit that removes as small (256K) private heap from kdb. This is change I've hoped for ever since I discovered how few users of this heap remained in the kernel, so many thanks to Sumit for hunting these down. The other change is an incremental step towards SPDX headers" * tag 'kgdb-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/danielt/linux: kernel: debug: Convert to SPDX identifier kdb: Rename members of struct kdbtab_t kdb: Simplify kdb_defcmd macro logic kdb: Get rid of redundant kdb_register_flags() kdb: Rename struct defcmd_set to struct kdb_macro kdb: Get rid of custom debug heap allocator
2 parents 0bcfe68 + f8416aa commit 996fe06

File tree

10 files changed

+387
-728
lines changed

10 files changed

+387
-728
lines changed
 

‎include/linux/kdb.h

+17-10
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
* Copyright (C) 2009 Jason Wessel <jason.wessel@windriver.com>
1414
*/
1515

16+
#include <linux/list.h>
17+
1618
/* Shifted versions of the command enable bits are be used if the command
1719
* has no arguments (see kdb_check_flags). This allows commands, such as
1820
* go, to have different permissions depending upon whether it is called
@@ -64,6 +66,17 @@ typedef enum {
6466

6567
typedef int (*kdb_func_t)(int, const char **);
6668

69+
/* The KDB shell command table */
70+
typedef struct _kdbtab {
71+
char *name; /* Command name */
72+
kdb_func_t func; /* Function to execute command */
73+
char *usage; /* Usage String for this command */
74+
char *help; /* Help message for this command */
75+
short minlen; /* Minimum legal # cmd chars required */
76+
kdb_cmdflags_t flags; /* Command behaviour flags */
77+
struct list_head list_node; /* Command list */
78+
} kdbtab_t;
79+
6780
#ifdef CONFIG_KGDB_KDB
6881
#include <linux/init.h>
6982
#include <linux/sched.h>
@@ -193,19 +206,13 @@ static inline const char *kdb_walk_kallsyms(loff_t *pos)
193206
#endif /* ! CONFIG_KALLSYMS */
194207

195208
/* Dynamic kdb shell command registration */
196-
extern int kdb_register(char *, kdb_func_t, char *, char *, short);
197-
extern int kdb_register_flags(char *, kdb_func_t, char *, char *,
198-
short, kdb_cmdflags_t);
199-
extern int kdb_unregister(char *);
209+
extern int kdb_register(kdbtab_t *cmd);
210+
extern void kdb_unregister(kdbtab_t *cmd);
200211
#else /* ! CONFIG_KGDB_KDB */
201212
static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; }
202213
static inline void kdb_init(int level) {}
203-
static inline int kdb_register(char *cmd, kdb_func_t func, char *usage,
204-
char *help, short minlen) { return 0; }
205-
static inline int kdb_register_flags(char *cmd, kdb_func_t func, char *usage,
206-
char *help, short minlen,
207-
kdb_cmdflags_t flags) { return 0; }
208-
static inline int kdb_unregister(char *cmd) { return 0; }
214+
static inline int kdb_register(kdbtab_t *cmd) { return 0; }
215+
static inline void kdb_unregister(kdbtab_t *cmd) {}
209216
#endif /* CONFIG_KGDB_KDB */
210217
enum {
211218
KDB_NOT_INITIALIZED,

‎kernel/debug/debug_core.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
12
/*
23
* Kernel Debug Core
34
*
@@ -22,10 +23,6 @@
2223
*
2324
* Original KGDB stub: David Grothe <dave@gcom.com>,
2425
* Tigran Aivazian <tigran@sco.com>
25-
*
26-
* This file is licensed under the terms of the GNU General Public License
27-
* version 2. This program is licensed "as is" without any warranty of any
28-
* kind, whether express or implied.
2926
*/
3027

3128
#define pr_fmt(fmt) "KGDB: " fmt

‎kernel/debug/gdbstub.c

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
12
/*
23
* Kernel Debug Core
34
*
@@ -22,10 +23,6 @@
2223
*
2324
* Original KGDB stub: David Grothe <dave@gcom.com>,
2425
* Tigran Aivazian <tigran@sco.com>
25-
*
26-
* This file is licensed under the terms of the GNU General Public License
27-
* version 2. This program is licensed "as is" without any warranty of any
28-
* kind, whether express or implied.
2926
*/
3027

3128
#include <linux/kernel.h>

‎kernel/debug/kdb/kdb_bp.c

+36-36
Original file line numberDiff line numberDiff line change
@@ -523,51 +523,51 @@ static int kdb_ss(int argc, const char **argv)
523523
}
524524

525525
static kdbtab_t bptab[] = {
526-
{ .cmd_name = "bp",
527-
.cmd_func = kdb_bp,
528-
.cmd_usage = "[<vaddr>]",
529-
.cmd_help = "Set/Display breakpoints",
530-
.cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
526+
{ .name = "bp",
527+
.func = kdb_bp,
528+
.usage = "[<vaddr>]",
529+
.help = "Set/Display breakpoints",
530+
.flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
531531
},
532-
{ .cmd_name = "bl",
533-
.cmd_func = kdb_bp,
534-
.cmd_usage = "[<vaddr>]",
535-
.cmd_help = "Display breakpoints",
536-
.cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
532+
{ .name = "bl",
533+
.func = kdb_bp,
534+
.usage = "[<vaddr>]",
535+
.help = "Display breakpoints",
536+
.flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
537537
},
538-
{ .cmd_name = "bc",
539-
.cmd_func = kdb_bc,
540-
.cmd_usage = "<bpnum>",
541-
.cmd_help = "Clear Breakpoint",
542-
.cmd_flags = KDB_ENABLE_FLOW_CTRL,
538+
{ .name = "bc",
539+
.func = kdb_bc,
540+
.usage = "<bpnum>",
541+
.help = "Clear Breakpoint",
542+
.flags = KDB_ENABLE_FLOW_CTRL,
543543
},
544-
{ .cmd_name = "be",
545-
.cmd_func = kdb_bc,
546-
.cmd_usage = "<bpnum>",
547-
.cmd_help = "Enable Breakpoint",
548-
.cmd_flags = KDB_ENABLE_FLOW_CTRL,
544+
{ .name = "be",
545+
.func = kdb_bc,
546+
.usage = "<bpnum>",
547+
.help = "Enable Breakpoint",
548+
.flags = KDB_ENABLE_FLOW_CTRL,
549549
},
550-
{ .cmd_name = "bd",
551-
.cmd_func = kdb_bc,
552-
.cmd_usage = "<bpnum>",
553-
.cmd_help = "Disable Breakpoint",
554-
.cmd_flags = KDB_ENABLE_FLOW_CTRL,
550+
{ .name = "bd",
551+
.func = kdb_bc,
552+
.usage = "<bpnum>",
553+
.help = "Disable Breakpoint",
554+
.flags = KDB_ENABLE_FLOW_CTRL,
555555
},
556-
{ .cmd_name = "ss",
557-
.cmd_func = kdb_ss,
558-
.cmd_usage = "",
559-
.cmd_help = "Single Step",
560-
.cmd_minlen = 1,
561-
.cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
556+
{ .name = "ss",
557+
.func = kdb_ss,
558+
.usage = "",
559+
.help = "Single Step",
560+
.minlen = 1,
561+
.flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
562562
},
563563
};
564564

565565
static kdbtab_t bphcmd = {
566-
.cmd_name = "bph",
567-
.cmd_func = kdb_bp,
568-
.cmd_usage = "[<vaddr>]",
569-
.cmd_help = "[datar [length]|dataw [length]] Set hw brk",
570-
.cmd_flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
566+
.name = "bph",
567+
.func = kdb_bp,
568+
.usage = "[<vaddr>]",
569+
.help = "[datar [length]|dataw [length]] Set hw brk",
570+
.flags = KDB_ENABLE_FLOW_CTRL | KDB_REPEAT_NO_ARGS,
571571
};
572572

573573
/* Initialize the breakpoint table and register breakpoint commands. */

‎kernel/debug/kdb/kdb_debugger.c

-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ int kdb_stub(struct kgdb_state *ks)
140140
*/
141141
kdb_common_deinit_state();
142142
KDB_STATE_CLEAR(PAGER);
143-
kdbnearsym_cleanup();
144143
if (error == KDB_CMD_KGDB) {
145144
if (KDB_STATE(DOING_KGDB))
146145
KDB_STATE_CLEAR(DOING_KGDB);

‎kernel/debug/kdb/kdb_main.c

+286-340
Large diffs are not rendered by default.

‎kernel/debug/kdb/kdb_private.h

-18
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ extern int kdbgetaddrarg(int, const char **, int*, unsigned long *,
109109
long *, char **);
110110
extern int kdbgetsymval(const char *, kdb_symtab_t *);
111111
extern int kdbnearsym(unsigned long, kdb_symtab_t *);
112-
extern void kdbnearsym_cleanup(void);
113112
extern char *kdb_strdup(const char *str, gfp_t type);
114113
extern void kdb_symbol_print(unsigned long, const kdb_symtab_t *, unsigned int);
115114

@@ -165,19 +164,6 @@ typedef struct _kdb_bp {
165164
#ifdef CONFIG_KGDB_KDB
166165
extern kdb_bp_t kdb_breakpoints[/* KDB_MAXBPT */];
167166

168-
/* The KDB shell command table */
169-
typedef struct _kdbtab {
170-
char *cmd_name; /* Command name */
171-
kdb_func_t cmd_func; /* Function to execute command */
172-
char *cmd_usage; /* Usage String for this command */
173-
char *cmd_help; /* Help message for this command */
174-
short cmd_minlen; /* Minimum legal # command
175-
* chars required */
176-
kdb_cmdflags_t cmd_flags; /* Command behaviour flags */
177-
struct list_head list_node; /* Command list */
178-
bool is_dynamic; /* Command table allocation type */
179-
} kdbtab_t;
180-
181167
extern void kdb_register_table(kdbtab_t *kp, size_t len);
182168
extern int kdb_bt(int, const char **); /* KDB display back trace */
183169

@@ -233,10 +219,6 @@ extern struct task_struct *kdb_curr_task(int);
233219

234220
#define GFP_KDB (in_dbg_master() ? GFP_ATOMIC : GFP_KERNEL)
235221

236-
extern void *debug_kmalloc(size_t size, gfp_t flags);
237-
extern void debug_kfree(void *);
238-
extern void debug_kusage(void);
239-
240222
extern struct task_struct *kdb_current_task;
241223
extern struct pt_regs *kdb_current_regs;
242224

‎kernel/debug/kdb/kdb_support.c

+28-301
Original file line numberDiff line numberDiff line change
@@ -51,48 +51,48 @@ int kdbgetsymval(const char *symname, kdb_symtab_t *symtab)
5151
}
5252
EXPORT_SYMBOL(kdbgetsymval);
5353

54-
static char *kdb_name_table[100]; /* arbitrary size */
55-
56-
/*
57-
* kdbnearsym - Return the name of the symbol with the nearest address
58-
* less than 'addr'.
54+
/**
55+
* kdbnearsym() - Return the name of the symbol with the nearest address
56+
* less than @addr.
57+
* @addr: Address to check for near symbol
58+
* @symtab: Structure to receive results
5959
*
60-
* Parameters:
61-
* addr Address to check for symbol near
62-
* symtab Structure to receive results
63-
* Returns:
64-
* 0 No sections contain this address, symtab zero filled
65-
* 1 Address mapped to module/symbol/section, data in symtab
66-
* Remarks:
67-
* 2.6 kallsyms has a "feature" where it unpacks the name into a
68-
* string. If that string is reused before the caller expects it
69-
* then the caller sees its string change without warning. To
70-
* avoid cluttering up the main kdb code with lots of kdb_strdup,
71-
* tests and kfree calls, kdbnearsym maintains an LRU list of the
72-
* last few unique strings. The list is sized large enough to
73-
* hold active strings, no kdb caller of kdbnearsym makes more
74-
* than ~20 later calls before using a saved value.
60+
* WARNING: This function may return a pointer to a single statically
61+
* allocated buffer (namebuf). kdb's unusual calling context (single
62+
* threaded, all other CPUs halted) provides us sufficient locking for
63+
* this to be safe. The only constraint imposed by the static buffer is
64+
* that the caller must consume any previous reply prior to another call
65+
* to lookup a new symbol.
66+
*
67+
* Note that, strictly speaking, some architectures may re-enter the kdb
68+
* trap if the system turns out to be very badly damaged and this breaks
69+
* the single-threaded assumption above. In these circumstances successful
70+
* continuation and exit from the inner trap is unlikely to work and any
71+
* user attempting this receives a prominent warning before being allowed
72+
* to progress. In these circumstances we remain memory safe because
73+
* namebuf[KSYM_NAME_LEN-1] will never change from '\0' although we do
74+
* tolerate the possibility of garbled symbol display from the outer kdb
75+
* trap.
76+
*
77+
* Return:
78+
* * 0 - No sections contain this address, symtab zero filled
79+
* * 1 - Address mapped to module/symbol/section, data in symtab
7580
*/
7681
int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
7782
{
7883
int ret = 0;
7984
unsigned long symbolsize = 0;
8085
unsigned long offset = 0;
81-
#define knt1_size 128 /* must be >= kallsyms table size */
82-
char *knt1 = NULL;
86+
static char namebuf[KSYM_NAME_LEN];
8387

8488
kdb_dbg_printf(AR, "addr=0x%lx, symtab=%px\n", addr, symtab);
8589
memset(symtab, 0, sizeof(*symtab));
8690

8791
if (addr < 4096)
8892
goto out;
89-
knt1 = debug_kmalloc(knt1_size, GFP_ATOMIC);
90-
if (!knt1) {
91-
kdb_func_printf("addr=0x%lx cannot kmalloc knt1\n", addr);
92-
goto out;
93-
}
93+
9494
symtab->sym_name = kallsyms_lookup(addr, &symbolsize , &offset,
95-
(char **)(&symtab->mod_name), knt1);
95+
(char **)(&symtab->mod_name), namebuf);
9696
if (offset > 8*1024*1024) {
9797
symtab->sym_name = NULL;
9898
addr = offset = symbolsize = 0;
@@ -101,63 +101,14 @@ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab)
101101
symtab->sym_end = symtab->sym_start + symbolsize;
102102
ret = symtab->sym_name != NULL && *(symtab->sym_name) != '\0';
103103

104-
if (ret) {
105-
int i;
106-
/* Another 2.6 kallsyms "feature". Sometimes the sym_name is
107-
* set but the buffer passed into kallsyms_lookup is not used,
108-
* so it contains garbage. The caller has to work out which
109-
* buffer needs to be saved.
110-
*
111-
* What was Rusty smoking when he wrote that code?
112-
*/
113-
if (symtab->sym_name != knt1) {
114-
strncpy(knt1, symtab->sym_name, knt1_size);
115-
knt1[knt1_size-1] = '\0';
116-
}
117-
for (i = 0; i < ARRAY_SIZE(kdb_name_table); ++i) {
118-
if (kdb_name_table[i] &&
119-
strcmp(kdb_name_table[i], knt1) == 0)
120-
break;
121-
}
122-
if (i >= ARRAY_SIZE(kdb_name_table)) {
123-
debug_kfree(kdb_name_table[0]);
124-
memmove(kdb_name_table, kdb_name_table+1,
125-
sizeof(kdb_name_table[0]) *
126-
(ARRAY_SIZE(kdb_name_table)-1));
127-
} else {
128-
debug_kfree(knt1);
129-
knt1 = kdb_name_table[i];
130-
memmove(kdb_name_table+i, kdb_name_table+i+1,
131-
sizeof(kdb_name_table[0]) *
132-
(ARRAY_SIZE(kdb_name_table)-i-1));
133-
}
134-
i = ARRAY_SIZE(kdb_name_table) - 1;
135-
kdb_name_table[i] = knt1;
136-
symtab->sym_name = kdb_name_table[i];
137-
knt1 = NULL;
138-
}
139-
140104
if (symtab->mod_name == NULL)
141105
symtab->mod_name = "kernel";
142106
kdb_dbg_printf(AR, "returns %d symtab->sym_start=0x%lx, symtab->mod_name=%px, symtab->sym_name=%px (%s)\n",
143107
ret, symtab->sym_start, symtab->mod_name, symtab->sym_name, symtab->sym_name);
144-
145108
out:
146-
debug_kfree(knt1);
147109
return ret;
148110
}
149111

150-
void kdbnearsym_cleanup(void)
151-
{
152-
int i;
153-
for (i = 0; i < ARRAY_SIZE(kdb_name_table); ++i) {
154-
if (kdb_name_table[i]) {
155-
debug_kfree(kdb_name_table[i]);
156-
kdb_name_table[i] = NULL;
157-
}
158-
}
159-
}
160-
161112
static char ks_namebuf[KSYM_NAME_LEN+1], ks_namebuf_prev[KSYM_NAME_LEN+1];
162113

163114
/*
@@ -655,230 +606,6 @@ unsigned long kdb_task_state(const struct task_struct *p, unsigned long mask)
655606
return (mask & kdb_task_state_string(state)) != 0;
656607
}
657608

658-
/* Last ditch allocator for debugging, so we can still debug even when
659-
* the GFP_ATOMIC pool has been exhausted. The algorithms are tuned
660-
* for space usage, not for speed. One smallish memory pool, the free
661-
* chain is always in ascending address order to allow coalescing,
662-
* allocations are done in brute force best fit.
663-
*/
664-
665-
struct debug_alloc_header {
666-
u32 next; /* offset of next header from start of pool */
667-
u32 size;
668-
void *caller;
669-
};
670-
671-
/* The memory returned by this allocator must be aligned, which means
672-
* so must the header size. Do not assume that sizeof(struct
673-
* debug_alloc_header) is a multiple of the alignment, explicitly
674-
* calculate the overhead of this header, including the alignment.
675-
* The rest of this code must not use sizeof() on any header or
676-
* pointer to a header.
677-
*/
678-
#define dah_align 8
679-
#define dah_overhead ALIGN(sizeof(struct debug_alloc_header), dah_align)
680-
681-
static u64 debug_alloc_pool_aligned[256*1024/dah_align]; /* 256K pool */
682-
static char *debug_alloc_pool = (char *)debug_alloc_pool_aligned;
683-
static u32 dah_first, dah_first_call = 1, dah_used, dah_used_max;
684-
685-
/* Locking is awkward. The debug code is called from all contexts,
686-
* including non maskable interrupts. A normal spinlock is not safe
687-
* in NMI context. Try to get the debug allocator lock, if it cannot
688-
* be obtained after a second then give up. If the lock could not be
689-
* previously obtained on this cpu then only try once.
690-
*
691-
* sparse has no annotation for "this function _sometimes_ acquires a
692-
* lock", so fudge the acquire/release notation.
693-
*/
694-
static DEFINE_SPINLOCK(dap_lock);
695-
static int get_dap_lock(void)
696-
__acquires(dap_lock)
697-
{
698-
static int dap_locked = -1;
699-
int count;
700-
if (dap_locked == smp_processor_id())
701-
count = 1;
702-
else
703-
count = 1000;
704-
while (1) {
705-
if (spin_trylock(&dap_lock)) {
706-
dap_locked = -1;
707-
return 1;
708-
}
709-
if (!count--)
710-
break;
711-
udelay(1000);
712-
}
713-
dap_locked = smp_processor_id();
714-
__acquire(dap_lock);
715-
return 0;
716-
}
717-
718-
void *debug_kmalloc(size_t size, gfp_t flags)
719-
{
720-
unsigned int rem, h_offset;
721-
struct debug_alloc_header *best, *bestprev, *prev, *h;
722-
void *p = NULL;
723-
if (!get_dap_lock()) {
724-
__release(dap_lock); /* we never actually got it */
725-
return NULL;
726-
}
727-
h = (struct debug_alloc_header *)(debug_alloc_pool + dah_first);
728-
if (dah_first_call) {
729-
h->size = sizeof(debug_alloc_pool_aligned) - dah_overhead;
730-
dah_first_call = 0;
731-
}
732-
size = ALIGN(size, dah_align);
733-
prev = best = bestprev = NULL;
734-
while (1) {
735-
if (h->size >= size && (!best || h->size < best->size)) {
736-
best = h;
737-
bestprev = prev;
738-
if (h->size == size)
739-
break;
740-
}
741-
if (!h->next)
742-
break;
743-
prev = h;
744-
h = (struct debug_alloc_header *)(debug_alloc_pool + h->next);
745-
}
746-
if (!best)
747-
goto out;
748-
rem = best->size - size;
749-
/* The pool must always contain at least one header */
750-
if (best->next == 0 && bestprev == NULL && rem < dah_overhead)
751-
goto out;
752-
if (rem >= dah_overhead) {
753-
best->size = size;
754-
h_offset = ((char *)best - debug_alloc_pool) +
755-
dah_overhead + best->size;
756-
h = (struct debug_alloc_header *)(debug_alloc_pool + h_offset);
757-
h->size = rem - dah_overhead;
758-
h->next = best->next;
759-
} else
760-
h_offset = best->next;
761-
best->caller = __builtin_return_address(0);
762-
dah_used += best->size;
763-
dah_used_max = max(dah_used, dah_used_max);
764-
if (bestprev)
765-
bestprev->next = h_offset;
766-
else
767-
dah_first = h_offset;
768-
p = (char *)best + dah_overhead;
769-
memset(p, POISON_INUSE, best->size - 1);
770-
*((char *)p + best->size - 1) = POISON_END;
771-
out:
772-
spin_unlock(&dap_lock);
773-
return p;
774-
}
775-
776-
void debug_kfree(void *p)
777-
{
778-
struct debug_alloc_header *h;
779-
unsigned int h_offset;
780-
if (!p)
781-
return;
782-
if ((char *)p < debug_alloc_pool ||
783-
(char *)p >= debug_alloc_pool + sizeof(debug_alloc_pool_aligned)) {
784-
kfree(p);
785-
return;
786-
}
787-
if (!get_dap_lock()) {
788-
__release(dap_lock); /* we never actually got it */
789-
return; /* memory leak, cannot be helped */
790-
}
791-
h = (struct debug_alloc_header *)((char *)p - dah_overhead);
792-
memset(p, POISON_FREE, h->size - 1);
793-
*((char *)p + h->size - 1) = POISON_END;
794-
h->caller = NULL;
795-
dah_used -= h->size;
796-
h_offset = (char *)h - debug_alloc_pool;
797-
if (h_offset < dah_first) {
798-
h->next = dah_first;
799-
dah_first = h_offset;
800-
} else {
801-
struct debug_alloc_header *prev;
802-
unsigned int prev_offset;
803-
prev = (struct debug_alloc_header *)(debug_alloc_pool +
804-
dah_first);
805-
while (1) {
806-
if (!prev->next || prev->next > h_offset)
807-
break;
808-
prev = (struct debug_alloc_header *)
809-
(debug_alloc_pool + prev->next);
810-
}
811-
prev_offset = (char *)prev - debug_alloc_pool;
812-
if (prev_offset + dah_overhead + prev->size == h_offset) {
813-
prev->size += dah_overhead + h->size;
814-
memset(h, POISON_FREE, dah_overhead - 1);
815-
*((char *)h + dah_overhead - 1) = POISON_END;
816-
h = prev;
817-
h_offset = prev_offset;
818-
} else {
819-
h->next = prev->next;
820-
prev->next = h_offset;
821-
}
822-
}
823-
if (h_offset + dah_overhead + h->size == h->next) {
824-
struct debug_alloc_header *next;
825-
next = (struct debug_alloc_header *)
826-
(debug_alloc_pool + h->next);
827-
h->size += dah_overhead + next->size;
828-
h->next = next->next;
829-
memset(next, POISON_FREE, dah_overhead - 1);
830-
*((char *)next + dah_overhead - 1) = POISON_END;
831-
}
832-
spin_unlock(&dap_lock);
833-
}
834-
835-
void debug_kusage(void)
836-
{
837-
struct debug_alloc_header *h_free, *h_used;
838-
#ifdef CONFIG_IA64
839-
/* FIXME: using dah for ia64 unwind always results in a memory leak.
840-
* Fix that memory leak first, then set debug_kusage_one_time = 1 for
841-
* all architectures.
842-
*/
843-
static int debug_kusage_one_time;
844-
#else
845-
static int debug_kusage_one_time = 1;
846-
#endif
847-
if (!get_dap_lock()) {
848-
__release(dap_lock); /* we never actually got it */
849-
return;
850-
}
851-
h_free = (struct debug_alloc_header *)(debug_alloc_pool + dah_first);
852-
if (dah_first == 0 &&
853-
(h_free->size == sizeof(debug_alloc_pool_aligned) - dah_overhead ||
854-
dah_first_call))
855-
goto out;
856-
if (!debug_kusage_one_time)
857-
goto out;
858-
debug_kusage_one_time = 0;
859-
kdb_func_printf("debug_kmalloc memory leak dah_first %d\n", dah_first);
860-
if (dah_first) {
861-
h_used = (struct debug_alloc_header *)debug_alloc_pool;
862-
kdb_func_printf("h_used %px size %d\n", h_used, h_used->size);
863-
}
864-
do {
865-
h_used = (struct debug_alloc_header *)
866-
((char *)h_free + dah_overhead + h_free->size);
867-
kdb_func_printf("h_used %px size %d caller %px\n",
868-
h_used, h_used->size, h_used->caller);
869-
h_free = (struct debug_alloc_header *)
870-
(debug_alloc_pool + h_free->next);
871-
} while (h_free->next);
872-
h_used = (struct debug_alloc_header *)
873-
((char *)h_free + dah_overhead + h_free->size);
874-
if ((char *)h_used - debug_alloc_pool !=
875-
sizeof(debug_alloc_pool_aligned))
876-
kdb_func_printf("h_used %px size %d caller %px\n",
877-
h_used, h_used->size, h_used->caller);
878-
out:
879-
spin_unlock(&dap_lock);
880-
}
881-
882609
/* Maintain a small stack of kdb_flags to allow recursion without disturbing
883610
* the global kdb state.
884611
*/

‎kernel/trace/trace_kdb.c

+9-3
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,17 @@ static int kdb_ftdump(int argc, const char **argv)
147147
return 0;
148148
}
149149

150+
static kdbtab_t ftdump_cmd = {
151+
.name = "ftdump",
152+
.func = kdb_ftdump,
153+
.usage = "[skip_#entries] [cpu]",
154+
.help = "Dump ftrace log; -skip dumps last #entries",
155+
.flags = KDB_ENABLE_ALWAYS_SAFE,
156+
};
157+
150158
static __init int kdb_ftrace_register(void)
151159
{
152-
kdb_register_flags("ftdump", kdb_ftdump, "[skip_#entries] [cpu]",
153-
"Dump ftrace log; -skip dumps last #entries", 0,
154-
KDB_ENABLE_ALWAYS_SAFE);
160+
kdb_register(&ftdump_cmd);
155161
return 0;
156162
}
157163

‎samples/kdb/kdb_hello.c

+9-11
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,26 @@ static int kdb_hello_cmd(int argc, const char **argv)
2828
return 0;
2929
}
3030

31+
static kdbtab_t hello_cmd = {
32+
.name = "hello",
33+
.func = kdb_hello_cmd,
34+
.usage = "[string]",
35+
.help = "Say Hello World or Hello [string]",
36+
};
3137

3238
static int __init kdb_hello_cmd_init(void)
3339
{
3440
/*
3541
* Registration of a dynamically added kdb command is done with
36-
* kdb_register() with the arguments being:
37-
* 1: The name of the shell command
38-
* 2: The function that processes the command
39-
* 3: Description of the usage of any arguments
40-
* 4: Descriptive text when you run help
41-
* 5: Number of characters to complete the command
42-
* 0 == type the whole command
43-
* 1 == match both "g" and "go" for example
42+
* kdb_register().
4443
*/
45-
kdb_register("hello", kdb_hello_cmd, "[string]",
46-
"Say Hello World or Hello [string]", 0);
44+
kdb_register(&hello_cmd);
4745
return 0;
4846
}
4947

5048
static void __exit kdb_hello_cmd_exit(void)
5149
{
52-
kdb_unregister("hello");
50+
kdb_unregister(&hello_cmd);
5351
}
5452

5553
module_init(kdb_hello_cmd_init);

0 commit comments

Comments
 (0)
Please sign in to comment.