On Wed, May 05, 2004 at 01:20:42PM -0500, [EMAIL PROTECTED] wrote:
> 
> On Wed, May 05, 2004 at 07:16:47PM +0500, Ananth N Mavinakayanahalli wrote:
> > @@ -200,25 +196,49 @@ kdba_bt_stack_ppc(struct pt_regs *regs,
> > +           if (!flag && (task_curr(p))) {
> > +
> > +                   lr = regs->link;
> 
> Its not obvious that regs might not be a null pointer.  Code
> higher up tries to make sure that regs is set to something,
> but its not clear that every branch is correctly handled.
> 

Right.. Here is a reworked patch that handles NULL regs.


Anton,

Please consider this patch for inclusion to Ameslab.


Thanks,
Ananth
-- 
Ananth Narayan
Linux Technology Center,
IBM Software Lab, INDIA


diff -Naurp temp/ameslab/arch/ppc64/kdb/kdba_bt.c ameslab/arch/ppc64/kdb/kdba_bt.c
--- temp/ameslab/arch/ppc64/kdb/kdba_bt.c       2004-04-22 21:52:09.000000000 -0700
+++ ameslab/arch/ppc64/kdb/kdba_bt.c    2004-05-05 22:06:39.401239784 -0700
@@ -101,17 +101,15 @@ kdba_bt_stack_ppc(struct pt_regs *regs, 
                   struct task_struct *p, int regs_esp)
 {
 
-       kdb_machreg_t   esp,eip,ebp,old_esp;
-/*     kdb_symtab_t    symtab, *sym; */
-       kdbtbtable_t    tbtab;
+       kdb_machreg_t   esp, eip, ebp, old_esp;
        /* declare these as raw ptrs so we don't get func descriptors */
        extern void *ret_from_except, *ret_from_syscall_1;
-/*     int do_bottom_half_ret=0; */
 
        const char *name;
-       char namebuf[128];
-       unsigned long symsize,symoffset;
+       unsigned long symsize, symoffset;
        char *symmodname;
+       int flag = 0;
+       char namebuf[128];
 
        /*
         * The caller may have supplied an address at which the
@@ -155,7 +153,8 @@ kdba_bt_stack_ppc(struct pt_regs *regs, 
 
        kdb_printf("          SP(esp)            PC(eip)      Function(args)\n");
 
-       /* (Ref: 64-bit PowerPC ELF ABI Spplement; Ian Lance Taylor, Zembu Labs).
+       /* (Ref: 64-bit PowerPC ELF ABI Supplement: 
+                               Ian Lance Taylor, Zembu Labs).
         A PPC stack frame looks like this:
 
         High Address
@@ -180,18 +179,15 @@ kdba_bt_stack_ppc(struct pt_regs *regs, 
         */
        while (1) {
                kdb_printf("0x%016lx  0x%016lx  ", esp, eip);
-               /*              kdbnearsym(eip, &symtab); */
-               kdba_find_tb_table(eip, &tbtab); 
-
-               /* sym = symtab.sym_name ? &symtab : &tbtab.symtab; */
-               /* use fake symtab if necessary */
                name = NULL;
                if (esp >= PAGE_OFFSET) { 
-                       /*if ((sym) )*/ 
-                       /* if this fails, eip is outside of kernel space, dont trust 
it. */
+                       /* 
+                        * if this fails, eip is outside of kernel space, 
+                        * dont trust it. 
+                        */
                        if (eip > PAGE_OFFSET) {
-                               name = kallsyms_lookup(eip, &symsize, &symoffset, 
&symmodname,
-                                                      namebuf);
+                               name = kallsyms_lookup(eip, &symsize, 
+                                       &symoffset, &symmodname, namebuf);
                        }
                        if (name) { 
                                kdb_printf("%s", name);
@@ -200,25 +196,50 @@ kdba_bt_stack_ppc(struct pt_regs *regs, 
                        }
                }
 
-               /* if this fails, eip is outside of kernel space, dont trust data. */
+               /* 
+                * if this fails, eip is outside of kernel space, 
+                * dont trust data. 
+                */
                if (eip > PAGE_OFFSET) { 
                        if (eip - symoffset > 0) {
                                kdb_printf(" +0x%lx", /*eip -*/ symoffset);
                        }
                }
                kdb_printf("\n");
+               if (!flag && (task_curr(p))) {
+                       kdb_machreg_t lr;
+                       unsigned long start = 0, end = 0;
+
+                       flag++;
+                       if ((!regs) || (regs->link < PAGE_OFFSET) || 
+                                       (regs->link == eip))
+                               goto next_frame;
+
+                       lr = regs->link;
+                       start = eip - symoffset;
+                       end = eip - symoffset + symsize;
+                       if (lr >= start && lr < end)
+                               goto next_frame;
+
+                       name = NULL;
+                       name = kallsyms_lookup(lr, &symsize, 
+                               &symoffset, &symmodname, namebuf);
+                       if (name)
+                               kdb_printf("0x%016lx  0x%016lx (lr) %s +0x%lx\n", 
+                                       esp, lr, name, symoffset);
+               }
 
-               /* ret_from_except=0xa5e0 ret_from_syscall_1=a378 
do_bottom_half_ret=a5e0 */
+next_frame:
                if (esp < PAGE_OFFSET) { /* below kernelspace..   */
                        kdb_printf("<Stack contents outside of kernel space.  
%.16lx>\n", esp );
                        break;
                } else {
                        if (eip == (kdb_machreg_t)ret_from_except ||
-                           eip == (kdb_machreg_t)ret_from_syscall_1 /* ||
-                                                                     eip == 
(kdb_machreg_t)do_bottom_half_ret */) {
+                           eip == (kdb_machreg_t)ret_from_syscall_1) {
                                /* pull exception regs from the stack */
                                struct pt_regs eregs;
-                               kdba_getmem(esp+STACK_FRAME_OVERHEAD, &eregs, 
sizeof(eregs));
+                               kdba_getmem(esp+STACK_FRAME_OVERHEAD, 
+                                                       &eregs, sizeof(eregs));
                                kdb_printf("  [exception: %lx:%s regs 0x%lx] "
                                           "nip:[0x%lx] gpr[1]:[0x%lx]\n", 
                                           eregs.trap,getvecname(eregs.trap), 
@@ -236,7 +257,10 @@ kdba_bt_stack_ppc(struct pt_regs *regs, 
                                                break;
                                        }
                                }
-                               /* we want to follow exception registers, not into 
user stack.  ...   */
+                               /* 
+                                * we want to follow exception registers, 
+                                * not into user stack.  ...   
+                                */
                                esp = eregs.gpr[1];
                                eip = eregs.nip;
                        } else {
diff -Naurp temp/ameslab/kdb/ChangeLog ameslab/kdb/ChangeLog
--- temp/ameslab/kdb/ChangeLog  2004-05-04 02:07:51.000000000 -0700
+++ ameslab/kdb/ChangeLog       2004-05-05 02:51:18.168228408 -0700
@@ -1,3 +1,8 @@
+2004-04-30 Keith Owens  <[EMAIL PROTECTED]>
+
+       * Rewrite inode_pages command for new radix code in struct page.
+       * kdb v4.3-2.6.6-rc1-common-1.
+
 2004-04-11 Keith Owens  <[EMAIL PROTECTED]>
 
        * Unlock sn_sal_lock before entering kdb from sn_serial.
diff -Naurp temp/ameslab/kdb/gen-kdb_cmds.c ameslab/kdb/gen-kdb_cmds.c
--- temp/ameslab/kdb/gen-kdb_cmds.c     2004-04-22 21:54:41.000000000 -0700
+++ ameslab/kdb/gen-kdb_cmds.c  1969-12-31 16:00:00.000000000 -0800
@@ -1,4 +0,0 @@
-#include <linux/init.h>
-char __initdata *kdb_cmds[] = {
-  0
-};
diff -Naurp temp/ameslab/kdb/modules/kdbm_pg.c ameslab/kdb/modules/kdbm_pg.c
--- temp/ameslab/kdb/modules/kdbm_pg.c  2004-05-04 02:07:51.000000000 -0700
+++ ameslab/kdb/modules/kdbm_pg.c       2004-05-05 03:07:16.033237072 -0700
@@ -151,42 +151,25 @@ kdbm_page(int argc, const char **argv, c
        long    offset=0;
        int nextarg;
        int diag;
-       int lookup_page = 0;
        
-       if (argc == 2) {
-               if (strcmp(argv[1], "-s") != 0) {
-                       return KDB_ARGCOUNT;
-               }
-               lookup_page = 1;
-       } else if (argc != 1) {
+       if (argc != 1)
                return KDB_ARGCOUNT;
-       }
 
-       nextarg = argc;
+       nextarg = 1;
        diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
        if (diag)
                return diag;
 
-       /* Assume argument is a page number, not address */
        if (addr < PAGE_OFFSET)
                addr = (unsigned long) &mem_map[addr];
 
-       /* Get the struct page * that corresponds to this addr */
-       if (lookup_page)
-       {
-               addr = (unsigned long) virt_to_page(addr);
-       }
-       
        if ((diag = kdb_getarea(page, addr)))
                return(diag);
 
        kdb_printf("struct page at 0x%lx\n", addr);
-/*     kdb_printf("  next 0x%p prev 0x%p addr space 0x%p index %lu (offset 0x%x)\n",
-                  page.list.next, page.list.prev, page.mapping, page.index,
-                  (int)(page.index << PAGE_CACHE_SHIFT)); */
-       kdb_printf("  addr space 0x%p index %lu (offset 0x%x)\n",
+       kdb_printf("  addr space 0x%p index %lu (offset 0x%llx)\n",
                   page.mapping, page.index,
-                  (int)(page.index << PAGE_CACHE_SHIFT)); 
+                  (unsigned long long)page.index << PAGE_CACHE_SHIFT);
        kdb_printf("  count %d flags %s\n",
                   page.count.counter, page_flags(page.flags));
        kdb_printf("  virtual 0x%p\n", page_address((struct page *)addr));
@@ -276,7 +259,7 @@ kdbm_rqueue(int argc, const char **argv,
        return 0;
 }
 
-/* routine not used currently.. sync with upstream later
+
 static void
 do_buffer(unsigned long addr)
 {
@@ -285,13 +268,54 @@ do_buffer(unsigned long addr)
        if (kdb_getarea(bh, addr))
                return;
 
-       kdb_printf("bh 0x%lx bno %8llu [%s]\n", addr,
+       kdb_printf(" bh 0x%lx bno %8llu [%s]", addr,
                 (unsigned long long)bh.b_blocknr,
                 map_flags(bh.b_state, bh_state_vals));
 }
-*/
 
-/* inode_struct changed in 2.6.6-rc series.. sync with upstream later
+static void
+kdbm_show_page(struct page *page, int first)
+{
+       if (first)
+               kdb_printf("page_struct       index   cnt zone nid flags\n");
+       kdb_printf("%p%s %6lu %5d %3ld %3ld 0x%lx",
+               page_address(page), sizeof(void *) == 4 ? "        " : "",
+               page->index, atomic_read(&(page->count)),
+               page_zonenum(page), page_to_nid(page),
+               page->flags & (~0UL >> ZONES_SHIFT));
+#define kdb_page_flags(page, type) if (Page ## type(page)) kdb_printf(" " #type);
+       kdb_page_flags(page, Locked);
+       kdb_page_flags(page, Error);
+       kdb_page_flags(page, Referenced);
+       kdb_page_flags(page, Uptodate);
+       kdb_page_flags(page, Dirty);
+       kdb_page_flags(page, LRU);
+       kdb_page_flags(page, Active);
+       kdb_page_flags(page, Slab);
+       kdb_page_flags(page, HighMem);
+       kdb_page_flags(page, Checked);
+       if (page->flags & (1UL << PG_arch_1))
+               kdb_printf(" arch_1");
+       kdb_page_flags(page, Reserved);
+       kdb_page_flags(page, Private);
+       kdb_page_flags(page, Writeback);
+       kdb_page_flags(page, Nosave);
+       if (page->flags & (1UL << PG_maplock))
+               kdb_printf(" maplock");
+       kdb_page_flags(page, Direct);
+       kdb_page_flags(page, MappedToDisk);
+       kdb_page_flags(page, Reclaim);
+       kdb_page_flags(page, Compound);
+       kdb_page_flags(page, Anon);
+       kdb_page_flags(page, SwapCache);
+       if (page_has_buffers(page))
+               do_buffer((unsigned long) page_buffers(page));
+       else if (page->private)
+               kdb_printf(" private=0x%lx", page->private);
+       kdb_printf("\n");
+#undef kdb_page_flags
+}
+
 static int
 kdbm_inode_pages(int argc, const char **argv, const char **envp,
        struct pt_regs *regs)
@@ -302,12 +326,9 @@ kdbm_inode_pages(int argc, const char **
        long offset=0;
        int nextarg;
        int diag;
-       int which=0;
-
-       struct list_head *head, *curr;
-       
-       if (argc < 1)
-               return KDB_ARGCOUNT;
+       pgoff_t next = 0;
+       struct page *page;
+       int first;
 
        nextarg = 1;
        diag = kdbgetaddrarg(argc, argv, &nextarg, &addr, &offset, NULL, regs);
@@ -321,6 +342,7 @@ kdbm_inode_pages(int argc, const char **
                if (diag)
                        goto out;
                kdb_printf("Looking for page index 0x%lx ... \n", addr1);
+               next = addr1;
        }
 
        if (!(inode = kmalloc(sizeof(*inode), GFP_ATOMIC))) {
@@ -340,58 +362,23 @@ kdbm_inode_pages(int argc, const char **
        if ((diag = kdb_getarea(*ap, (unsigned long) inode->i_mapping)))
                goto out;
        
- again:
-       if (which == 0){
-         which=1;
-         head = &inode->i_mapping->clean_pages;
-         kdb_printf("CLEAN  page_struct   index  cnt  flags\n");
-       } else if (which == 1) {
-         which=2;
-         head = &inode->i_mapping->dirty_pages;
-         kdb_printf("DIRTY  page_struct   index  cnt  flags\n");
-       } else if (which == 2) {
-         which=3;
-         head = &inode->i_mapping->locked_pages;
-         kdb_printf("LOCKED page_struct   index  cnt  flags\n");
-       } else {
-         goto out;
+       /* Run the pages in the radix tree, printing the state of each page */
+       first = 1;
+       while (radix_tree_gang_lookup(&ap->page_tree, (void **)&page, next, 1)) {
+               kdbm_show_page(page, first);
+               if (addr1)
+                       break;
+               first = 0;
+               next = page->index + 1;
        }
-       
-       curr = head->next;
-       while (curr != head) {
-               struct page      page;
-               struct list_head curr_struct;
-
-               addr = (unsigned long) list_entry(curr, struct page, list);
-               if ((diag = kdb_getarea(page, addr)))
-                       goto out;
-
-               if (!addr1 || page.index == addr1 ||
-                       (addr1 == -1 && (page.flags & ( 1 << PG_locked))))
-               {
-                       kdb_printf("    0x%lx    %6lu    %5d    0x%lx ",
-                               addr, page.index, page.count.counter,
-                               page.flags);
-                       if (page_has_buffers(&page))
-                               do_buffer((unsigned long) page_buffers(&page));
-                       else
-                               kdb_printf("bh [NULL]\n");
-               }
-
-               if ((diag = kdb_getarea(curr_struct, (unsigned long) curr)))
-                       goto out;
-
-               curr = curr_struct.next;
-       }
-       goto again;
- out:
+ 
+out:
        if (inode)
                kfree(inode);
        if (ap)
                kfree(ap);
        return diag;
 }
-*/
 
 static int
 kdbm_inode(int argc, const char **argv, const char **envp,
@@ -567,13 +554,12 @@ kdbm_memmap(int argc, const char **argv,
 static int __init kdbm_pg_init(void)
 {
 #ifndef CONFIG_DISCONTIGMEM
-       kdb_register("page", kdbm_page, "[-s] <vaddr>", "Display page [or page of 
addr]", 0);
+       kdb_register("page", kdbm_page, "<vaddr>", "Display page", 0);
 #endif
        kdb_register("inode", kdbm_inode, "<vaddr>", "Display inode", 0);
        kdb_register("sb", kdbm_sb, "<vaddr>", "Display super_block", 0);
        kdb_register("bh", kdbm_buffers, "<buffer head address>", "Display buffer", 0);
-/* inode struct changed in 2.6.6-rc series.. sync with upstream later
-       kdb_register("inode_pages", kdbm_inode_pages, "<inode *>", "Display pages in 
an inode", 0); */
+       kdb_register("inode_pages", kdbm_inode_pages, "<inode *>", "Display pages in 
an inode", 0);
        kdb_register("req", kdbm_request, "<vaddr>", "dump request struct", 0);
        kdb_register("rqueue", kdbm_rqueue, "<vaddr>", "dump request queue", 0);
 #if    defined(CONFIG_X86) | defined(CONFIG_PPC64)
---------------------------
Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.

Reply via email to