All of lore.kernel.org
 help / color / mirror / Atom feed
* Problem when disabled interrupt in system call (ppc8270)
@ 2009-10-16  1:12 wilbur.chan
  2009-10-16  4:43 ` Benjamin Herrenschmidt
  2009-10-16  7:25 ` Gabriel Paubert
  0 siblings, 2 replies; 4+ messages in thread
From: wilbur.chan @ 2009-10-16  1:12 UTC (permalink / raw)
  To: linuxppc-dev

ppc 8270, kernel 2.6.21.7

I took the following steps:


In a system call function , say , sys_reboot, interrupt was disabled
by local_irq_disable.

Then ,  value at the address of 0xc000050  was set to a value , say ,
0x1234.  Code was like this :

sys_reboot()
{
local_irq_disable();
*(volatile unsigned long * )0xc1000050 = 0x1234;
 while(1)
   {
    ;
   }
}

Finally, I reset the board (with power still on)  into uboot,using
'md 0x1000050' to display the content at physical address 0x1000050,
and found that , it was not 0x1234.


However, if I delete the local_irq_disable() in sys_reboot, everything
went well---After I reset the board, 'md 0x1000050' return the value
0x1234.


So, this really puzzled me , could someone explain why this happed?  Thank you.



PS:

static inline unsigned long local_irq_disable(void)
{
	unsigned long flags, zero;

	__asm__ __volatile__("li %1,0; lbz %0,%2(13); stb %1,%2(13)"
	: "=r" (flags), "=&r" (zero)
	: "i" (offsetof(struct paca_struct, soft_enabled))
	: "memory");

	return flags;
}

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

* Re: Problem when disabled interrupt in system call (ppc8270)
  2009-10-16  1:12 Problem when disabled interrupt in system call (ppc8270) wilbur.chan
@ 2009-10-16  4:43 ` Benjamin Herrenschmidt
  2009-10-16  5:14   ` wilbur.chan
  2009-10-16  7:25 ` Gabriel Paubert
  1 sibling, 1 reply; 4+ messages in thread
From: Benjamin Herrenschmidt @ 2009-10-16  4:43 UTC (permalink / raw)
  To: wilbur.chan; +Cc: linuxppc-dev

On Fri, 2009-10-16 at 09:12 +0800, wilbur.chan wrote:

> static inline unsigned long local_irq_disable(void)
> {
> 	unsigned long flags, zero;
> 
> 	__asm__ __volatile__("li %1,0; lbz %0,%2(13); stb %1,%2(13)"
> 	: "=r" (flags), "=&r" (zero)
> 	: "i" (offsetof(struct paca_struct, soft_enabled))
> 	: "memory");
> 
> 	return flags;
> }

This is not the variant of local_irq_disable() used on that machine :-)

The above is the 64-bit version.

Ben.

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

* Re: Problem when disabled interrupt in system call (ppc8270)
  2009-10-16  4:43 ` Benjamin Herrenschmidt
@ 2009-10-16  5:14   ` wilbur.chan
  0 siblings, 0 replies; 4+ messages in thread
From: wilbur.chan @ 2009-10-16  5:14 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev

2009/10/16, Benjamin Herrenschmidt <benh@kernel.crashing.org>:
> On Fri, 2009-10-16 at 09:12 +0800, wilbur.chan wrote:
>
>> static inline unsigned long local_irq_disable(void)
>> {
>> 	unsigned long flags, zero;
>>
>> 	__asm__ __volatile__("li %1,0; lbz %0,%2(13); stb %1,%2(13)"
>> 	: "=r" (flags), "=&r" (zero)
>> 	: "i" (offsetof(struct paca_struct, soft_enabled))
>> 	: "memory");
>>
>> 	return flags;
>> }
>
> This is not the variant of local_irq_disable() used on that machine :-)
>
> The above is the 64-bit version.
>
> Ben.
Hmmm...

I just called  local_irq_disable in sys_reboot, but actually, I don't
know which

local_irq_disable  function it really called , So I just paste one of
them here ...

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

* Re: Problem when disabled interrupt in system call (ppc8270)
  2009-10-16  1:12 Problem when disabled interrupt in system call (ppc8270) wilbur.chan
  2009-10-16  4:43 ` Benjamin Herrenschmidt
@ 2009-10-16  7:25 ` Gabriel Paubert
  1 sibling, 0 replies; 4+ messages in thread
From: Gabriel Paubert @ 2009-10-16  7:25 UTC (permalink / raw)
  To: wilbur.chan; +Cc: linuxppc-dev

On Fri, Oct 16, 2009 at 09:12:34AM +0800, wilbur.chan wrote:
> ppc 8270, kernel 2.6.21.7
> 
> I took the following steps:
> 
> 
> In a system call function , say , sys_reboot, interrupt was disabled
> by local_irq_disable.
> 
> Then ,  value at the address of 0xc000050  was set to a value , say ,
> 0x1234.  Code was like this :
> 
> sys_reboot()
> {
> local_irq_disable();
> *(volatile unsigned long * )0xc1000050 = 0x1234;
>  while(1)
>    {
>     ;
>    }
> }
> 
> Finally, I reset the board (with power still on)  into uboot,using
> 'md 0x1000050' to display the content at physical address 0x1000050,
> and found that , it was not 0x1234.
> 
> 
> However, if I delete the local_irq_disable() in sys_reboot, everything
> went well---After I reset the board, 'md 0x1000050' return the value
> 0x1234.
> 
> 
> So, this really puzzled me , could someone explain why this happed?  Thank you.

The 0x1234 stays in the data cache and is not written to memory. The hard reset
invalidates the caches and you read the previous value from memory.

If you don't disable interrupts, the cache line is ultimately written
back to memory and you see it after reset.

Just try inserting a dcbst (or dcbf) instruction for the address
of the 0x1234 value just after.

Something like asm volatile("dcbst 0,%0": : "r" (address) : "memory");

(Not even tried to compile it, but you get the idea).

	Gabriel

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

end of thread, other threads:[~2009-10-16  7:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-16  1:12 Problem when disabled interrupt in system call (ppc8270) wilbur.chan
2009-10-16  4:43 ` Benjamin Herrenschmidt
2009-10-16  5:14   ` wilbur.chan
2009-10-16  7:25 ` Gabriel Paubert

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.