Linux PARISC architecture development
 help / color / mirror / Atom feed
* [parisc-linux] traps, unwind new patch proposal.
@ 2005-05-01 14:25 Joel Soete
  2005-05-03  9:30 ` [parisc-linux] " Randolph Chung
  0 siblings, 1 reply; 3+ messages in thread
From: Joel Soete @ 2005-05-01 14:25 UTC (permalink / raw)
  To: parisc-linux; +Cc: Randolph Chung

Hi Randolph and *,

Here is my new proposal to attempt to fix the show_stack() bug in the early boot stage:
--- include/asm-parisc/unwind.h.Orig    2005-05-01 15:55:25.000000000 +0200
+++ include/asm-parisc/unwind.h 2005-05-01 15:23:56.000000000 +0200
@@ -61,6 +61,14 @@
         unsigned long prev_sp, prev_ip;
  };

+struct unwind_frame_regs {
+       unsigned long sp, ip, rp, r31;
+};
+
+#define UFI_REGS_BUF_MAX       128     /* about 4k for LP64 */
+extern struct unwind_frame_regs ufi_regs_buf[UFI_REGS_BUF_MAX];
+extern unsigned int ufi_regs_buf_i;
+
  struct unwind_table *
  unwind_table_add(const char *name, unsigned long base_addr,
                  unsigned long gp, void *start, void *end);
@@ -68,9 +76,11 @@
  unwind_table_remove(struct unwind_table *table);

  void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
-                      struct pt_regs *regs);
+                       struct unwind_frame_regs *regs);
  void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t);
+#if 0   /* FIXME: not used */
  void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs);
+#endif
  int unwind_once(struct unwind_frame_info *info);
  int unwind_to_user(struct unwind_frame_info *info);

--- arch/parisc/kernel/unwind.c.Orig    2005-05-01 15:50:50.000000000 +0200
+++ arch/parisc/kernel/unwind.c 2005-05-01 15:40:39.000000000 +0200
@@ -326,14 +326,18 @@
  }

  void unwind_frame_init(struct unwind_frame_info *info, struct task_struct *t,
-                      struct pt_regs *regs)
+                       struct unwind_frame_regs *regs)
  {
-       memset(info, 0, sizeof(struct unwind_frame_info));
+       if (unlikely(!info)) {
+               printk(KERN_ERR "%s: info == NULL\n", __FUNCTION__);
+               return;
+       }
+       memset(info, 0, sizeof(*info));
         info->t = t;
-       info->sp = regs->gr[30];
-       info->ip = regs->iaoq[0];
-       info->rp = regs->gr[2];
-       info->r31 = regs->gr[31];
+       info->sp = regs->sp;
+       info->ip = regs->ip;
+       info->rp = regs->rp;
+       info->r31 = regs->r31;

         dbg("(%d) Start unwind from sp=%08lx ip=%08lx\n",
             t ? (int)t->pid : -1, info->sp, info->ip);
@@ -342,22 +346,21 @@
  void unwind_frame_init_from_blocked_task(struct unwind_frame_info *info, struct task_struct *t)
  {
         struct pt_regs *r = &t->thread.regs;
-       struct pt_regs *r2;
+       struct unwind_frame_regs r2;

-       r2 = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
-       if (!r2)
-               return;
-       *r2 = *r;
-       r2->gr[30] = r->ksp;
-       r2->iaoq[0] = r->kpc;
-       unwind_frame_init(info, t, r2);
-       kfree(r2);
+       r2.sp  = r->ksp;
+       r2.ip  = r->kpc;
+       r2.rp  = r->gr[2];
+       r2.r31 = r->gr[31];
+       unwind_frame_init(info, t, &r2);
  }

+#if 0  /* FIXME: not used */
  void unwind_frame_init_running(struct unwind_frame_info *info, struct pt_regs *regs)
  {
         unwind_frame_init(info, current, regs);
  }
+#endif

  int unwind_once(struct unwind_frame_info *next_frame)
  {
--- arch/parisc/kernel/traps.c.Orig     2005-05-01 15:50:32.000000000 +0200
+++ arch/parisc/kernel/traps.c  2005-05-01 15:38:08.000000000 +0200
@@ -158,25 +158,35 @@
         printk("\n");
  }

+struct unwind_frame_regs ufi_regs_buf[UFI_REGS_BUF_MAX];
+unsigned int ufi_regs_buf_i = 0;
+
  void show_stack(struct task_struct *task, unsigned long *s)
  {
         struct unwind_frame_info info;
+       struct unwind_frame_regs *r;

         if (!task) {
+               if (ufi_regs_buf_i >= UFI_REGS_BUF_MAX) {
+                       printk(KERN_ERR "Can't %s().\n", __FUNCTION__);
+                       return;
+               }
+
                 unsigned long sp;
-               struct pt_regs *r;

  HERE:
                 asm volatile ("copy %%r30, %0" : "=r"(sp));
-               r = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL);
-               if (!r)
-                       return;
-               memset(r, 0, sizeof(struct pt_regs));
-               r->iaoq[0] = (unsigned long)&&HERE;
-               r->gr[2] = (unsigned long)__builtin_return_address(0);
-               r->gr[30] = sp;
+               r = &ufi_regs_buf[ufi_regs_buf_i++];
+               memset(r, 0, sizeof(*r));
+               r->ip = (unsigned long)&&HERE;
+               r->rp = (unsigned long)__builtin_return_address(0);
+               r->sp = sp;
                 unwind_frame_init(&info, current, r);
-               kfree(r);
+               ufi_regs_buf_i--;
+               if (ufi_regs_buf_i < 0) {
+                       printk(KERN_ERR "Wouldn't have reach here???\n");
+                       return;
+               }
         } else {
                 unwind_frame_init_from_blocked_task(&info, task);
         }
@@ -423,7 +433,10 @@
         {
                 /* show_stack(NULL, (unsigned long *)regs->gr[30]); */
                 struct unwind_frame_info info;
-               unwind_frame_init(&info, current, regs);
+               struct unwind_frame_regs r2;
+               r2.sp = regs->gr[30]; r2.ip = regs->iaoq[0];
+               r2.rp = regs->gr[2]; r2.r31 = regs->gr[31];
+               unwind_frame_init(&info, current, &r2);
                 do_show_stack(&info);
         }

====<>====

compile and boot fine on c110.

Thanks for additional advise,
	Joel
_______________________________________________
parisc-linux mailing list
parisc-linux@lists.parisc-linux.org
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [parisc-linux] Re: traps, unwind new patch proposal.
  2005-05-01 14:25 [parisc-linux] traps, unwind new patch proposal Joel Soete
@ 2005-05-03  9:30 ` Randolph Chung
  0 siblings, 0 replies; 3+ messages in thread
From: Randolph Chung @ 2005-05-03  9:30 UTC (permalink / raw)
  To: Joel Soete; +Cc: parisc-linux

Joel,

> Here is my new proposal to attempt to fix the show_stack() bug in the early 
> boot stage:

Can you explain again what is the problem you are seeing? Is it because
of stack overflow? calls to kmalloc()?

> +struct unwind_frame_regs {
> +       unsigned long sp, ip, rp, r31;
> +};

this is better, although i am still not very clear why we can't just use
pt_regs.

> +#define UFI_REGS_BUF_MAX       128     /* about 4k for LP64 */
> +extern struct unwind_frame_regs ufi_regs_buf[UFI_REGS_BUF_MAX];
> +extern unsigned int ufi_regs_buf_i;

this seems to be used to handle recursive calls to show_stack(), is that
right? why do we want to call show_stack() recursively?

i'm not sure why you want to put this array as a global variable. what's
wrong with putting it on the stack of show_stack()?

> +#if 0   /* FIXME: not used */
>  void unwind_frame_init_running(struct unwind_frame_info *info, struct 
>  pt_regs *regs);
> +#endif

please fix this. this function is useful e.g. for kdb.

randolph
-- 
Randolph Chung
Debian GNU/Linux Developer, hppa/ia64 ports
http://www.tausq.org/
_______________________________________________
parisc-linux mailing list
parisc-linux@lists.parisc-linux.org
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [parisc-linux] Re: traps, unwind new patch proposal.
@ 2005-05-03 15:50 Joel Soete
  0 siblings, 0 replies; 3+ messages in thread
From: Joel Soete @ 2005-05-03 15:50 UTC (permalink / raw)
  To: Randolph Chung; +Cc: parisc-linux

Hello Randolph,

>
> > Here is my new proposal to attempt to fix the show_stack() bug in the=

early
>
> > boot stage:
>
> Can you explain again what is the problem you are seeing?
Well all came from the fact that my b2k was runing fine a 2.6 64bit (quie=
t
more stable then 32bit twin kernel) and a day I read I mail (iirc from tb=
one)
speaking about DEBUG_SLAB.
I would so try it to attempt to reproduce its pb.

Effectively, under heavy stress condition this same 64bit kernel +  DEBUG=
_SLAB
made panicing the system.
What was anoying: there was no Backtrace?

The analyse of piminfo learned me that the system did a hpmc so why no Ba=
cktrace?

Another case was when I attempted to study the irq (enable/disable) statu=
s
(if I well undestand the PSW I bit) along the boot of our parisc-linux (s=
till
on going :-) ).
I also remember of the willy's patch: "Remove spurious BUG_ON()."
<http://cvs.parisc-linux.org/linux-2.6/kernel/posix-cpu-timers.c?r1=3D1.2=
&r2=3D1.3>

I thought so that it could be interesting to replace the BUG_ON() by a WA=
RN_ON()
to start.

Even thought that was just a warning the system panicing also whithout an=
y
Backtrace?

Then I have a look and found a possible way which could explain this pb:
BUG_ON (for parisc) as well as WARN_ON() -> dump_stack() -> show_stack()
-> kmalloc() (as *task =3D=3D NULL)
OTH (for some run path) kmalloc() -> __kmalloc() -> kmem_find_genral_cach=
ep()->
BUG_ON() (when DEBUG_SLAB is selected)

> Is it because
> of stack overflow? calls to kmalloc()?
>
so imho there are at least a possibility of calls of kmalloc() in loop?

> > +struct unwind_frame_regs {
> > +       unsigned long sp, ip, rp, r31;
> > +};
>
> this is better, although i am still not very clear why we can't just us=
e
> pt_regs.
>
Just because pt_regs struct would use many place (around 0.7k) for just u=
sefull
32bytes (64bit kernel).
(mmm may be oldfashion but at school I learned basis of asm on a 8088 tes=
ting
board with a lot of 4k of ram ;-) ...)

> > +#define UFI_REGS_BUF_MAX       128     /* about 4k for LP64 */
> > +extern struct unwind_frame_regs ufi_regs_buf[UFI_REGS_BUF_MAX];
> > +extern unsigned int ufi_regs_buf_i;
>
> this seems to be used to handle recursive calls to show_stack(), is tha=
t
> right? why do we want to call show_stack() recursively?
>
I thought more to insure some kind of re-intrance (may be not the right w=
ay?).

> i'm not sure why you want to put this array as a global variable. what'=
s
> wrong with putting it on the stack of show_stack()?
>
Willy seems to dis-like this solution:
<http://lists.parisc-linux.org/pipermail/parisc-linux/2005-April/026315.h=
tml>
(imho make sense?)

> > +#if 0   /* FIXME: not used */
> >  void unwind_frame_init_running(struct unwind_frame_info *info, struc=
t
>
> >  pt_regs *regs);
> > +#endif
>
> please fix this. this function is useful e.g. for kdb.
>
Oops I missed sorry (I will check that as soon as we agreed a common solu=
tion).

Thanks,
    Joel

PS: I still need to check the DEBUG_SLAB case; but already help to get mo=
re
backtrace in the second example (eventhought it dramaticaly slow down the=

boot).
It also also help me about that 'ext3' pb encountered with 32bit kernel o=
n
b180 and b2k by showing me now the same Backtrace :-) (previously on b180=
,
it was showing apparently a truncated backtrace, making thought to a diff=
erent
pb)  


_______________________________________________
parisc-linux mailing list
parisc-linux@lists.parisc-linux.org
http://lists.parisc-linux.org/mailman/listinfo/parisc-linux

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2005-05-03 15:50 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-01 14:25 [parisc-linux] traps, unwind new patch proposal Joel Soete
2005-05-03  9:30 ` [parisc-linux] " Randolph Chung
  -- strict thread matches above, loose matches on Subject: below --
2005-05-03 15:50 Joel Soete

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox