public inbox for linux-m68k@lists.linux-m68k.org
 help / color / mirror / Atom feed
From: Lanttor <lanttor.guo@freescale.com>
To: linux-m68k@vger.kernel.org
Cc: uClinux development list <uclinux-dev@uclinux.org>
Subject: Interrupt issue on m68k platform and some fix
Date: Thu, 02 Jul 2009 12:07:03 +0800	[thread overview]
Message-ID: <4A4C3267.2040705@freescale.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 5894 bytes --]

Hi,

I find one interrupt issue on my coldfire platform on linux-2.6.29
version (mcf54451evb board, mmu, NFS as rootfs).

After system boot up, I do following test:
on target board, run command: nc -l -p 3333 > /dev/null &
on host PC, run command: dd if=/dev/zero | nc 10.192.208.230 (target ip)
3333

and then I run top command on target board to check, which is shown as
follows:
CPU:  0.5% usr  0.0% sys  0.0% nice  0.0% idle  0.0% io 99.4% irq  0.0%
softirq
Load average: 0.39 0.10 0.03
  PID  PPID USER     STAT   VSZ %MEM %CPU COMMAND
  502   498 root     R     2560  2.0 97.8 nc -l -p 3333
    3     2 root     SW<      0  0.0  1.3 [ksoftirqd/0]
  503   498 root     R     2832  2.2  0.4 top
  492     1 root     S     3952  3.1  0.2 nmbd -s /etc/samba/smb.conf
  495     1 root     S     6144  4.8  0.0 smbd -s /etc/samba/smb.conf
  499   495 root     S     6144  4.8  0.0 smbd -s /etc/samba/smb.conf
  498     1 root     S     3056  2.4  0.0 -/bin/sh
  485     1 root     S     2864  2.2  0.0 /usr/sbin/inetd
    1     0 root     S     2824  2.2  0.0 init      
  468     1 root     S     2824  2.2  0.0 /sbin/syslogd
  470     1 root     S     2824  2.2  0.0 /sbin/klogd
  488     1 nobody   S     2672  2.1  0.0 /usr/sbin/boa -c /etc
  297     1 root     S <   2472  1.9  0.0 udevd --daemon
  282     2 root     SW<      0  0.0  0.0 [rpciod/0]
  143     2 root     SW<      0  0.0  0.0 [nfsiod]
    6     2 root     SW<      0  0.0  0.0 [khelper]
    2     0 root     SW<      0  0.0  0.0 [kthreadd]
    4     2 root     SW<      0  0.0  0.0 [watchdog/0]
    5     2 root     SW<      0  0.0  0.0 [events/0]
   53     2 root     SW<      0  0.0  0.0 [kblockd/0]

The irq time takes up most cpu time, but "softirq" and "sys" time is 0%.

I run /proc/stat to check, which is shown as follows:

[root@freescale /]# cat /proc/stat
cpu  316 0 0 53838 409 14467 0 0 0
cpu0 316 0 0 53838 409 14467 0 0 0
intr 636215 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00
ctxt 281405
btime 0
processes 499
procs_running 2
procs_blocked 0

It's indeed that the statistic time number of "sys" and "softirq" is zero.


I tracked the source codes, and find the root cause is in following
codes (the Entry function for interrupt) in the entry.S:

ENTRY(inthandler)
        SAVE_ALL_INT
        GET_CURRENT(%d0)
       * addql   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)*
        /* put exception # in d0 */
        movel   %sp@(PT_VECTOR),%d0
        swap    %d0                     /* extract bits 25:18 */
        lsrl    #2,%d0
        andl    #0x0ff,%d0

        movel   %sp,%sp@-
        movel   %d0,%sp@-               /* put vector # on stack */
auto_irqhandler_fixup = . + 2
        jbsr    process_int             /* process the IRQ */
        addql   #8,%sp                  /* pop parameters off stack */
        *subql   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)*
        jeq     ret_from_last_interrupt
2:      RESTORE_ALL

        ALIGN
ret_from_last_interrupt:
        moveb   %sp@(PT_SR),%d0
        andl    #(~ALLOWINT>>8)&0xff,%d0
        jne     2b

        /* check if we need to do software interrupts */
        tstl    irq_stat+CPUSTAT_SOFTIRQ_PENDING
        jeq     .Lret_from_exception
        pea     ret_from_exception
        jra     do_softirq

My understanding of "*addql   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)*"
is that its meaning is equal to
"current_thread_info()->preempt_count += HARDIRQ_OFFSET", which shows
now it's interrupt context. And the
meaning of "*subql   #1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)*" should be
opposite.

However, it seems these two line codes doesn't take their responsibility
from above test result (I don't know why).
I comment these two lines and add "irq_enter() / irq_exit()" function
pairs into the process_int function (process_int() is the interrupt
handler).

My understanding the function of irq_enter()/irq_exit() is the same as
those two line assembly codes).  Attached is my patch.

Following is my test result with my patch:

on target board, run command: nc -l -p 3333 > /dev/null &
on host PC, run command: dd if=/dev/zero | nc 10.192.208.230 (target ip)
3333
run top command on target:
CPU:  0.9% usr 24.1% sys  0.0% nice  0.0% idle  0.0% io 18.2% irq 56.6%
softirq
Load average: 0.28 0.12 0.06
  PID  PPID USER     STAT   VSZ %MEM %CPU COMMAND
  498   495 root     R     2560  2.0 99.2 nc -l -p 3333
  499   495 root     R     2832  2.2  0.4 top
  489     1 root     S     3952  3.1  0.2 nmbd -s /etc/samba/smb.conf
  492     1 root     S     6144  4.8  0.0 smbd -s /etc/samba/smb.conf
  496   492 root     S     6144  4.8  0.0 smbd -s /etc/samba/smb.conf
  495     1 root     S     3056  2.4  0.0 -/bin/sh
  482     1 root     S     2864  2.2  0.0 /usr/sbin/inetd
    1     0 root     S     2824  2.2  0.0 init      
  465     1 root     S     2824  2.2  0.0 /sbin/syslogd
  467     1 root     S     2824  2.2  0.0 /sbin/klogd
  485     1 nobody   S     2672  2.1  0.0 /usr/sbin/boa -c /etc
  297     1 root     S <   2472  1.9  0.0 udevd --daemon
  282     2 root     SW<      0  0.0  0.0 [rpciod/0]
  143     2 root     SW<      0  0.0  0.0 [nfsiod]
    6     2 root     SW<      0  0.0  0.0 [khelper]
    2     0 root     SW<      0  0.0  0.0 [kthreadd]
    3     2 root     SW<      0  0.0  0.0 [ksoftirqd/0]
    4     2 root     SW<      0  0.0  0.0 [watchdog/0]
    5     2 root     SW<      0  0.0  0.0 [events/0]
   53     2 root     SW<      0  0.0  0.0 [kblockd/0]

run cat /proc/stat on target:
[root@freescale /]# cat /proc/stat
cpu  281 0 3565 34268 475 2597 7452 0 0
cpu0 281 0 3565 34268 475 2597 7452 0 0
intr 522453 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00
ctxt 18910
btime 0
processes 497
procs_running 2
procs_blocked 0


Any idea for this issue?

Regards,
Lanttor



[-- Attachment #2: Fix-interrupt-contexting-bug-on-mcf5445x.patch --]
[-- Type: text/x-diff, Size: 1214 bytes --]

diff --git a/arch/m68k/coldfire/entry.S b/arch/m68k/coldfire/entry.S
index 3fc1df8..cfd9349 100644
--- a/arch/m68k/coldfire/entry.S
+++ b/arch/m68k/coldfire/entry.S
@@ -232,7 +232,6 @@ do_delayed_trace:
 ENTRY(inthandler)
 	SAVE_ALL_INT
 	GET_CURRENT(%d0)
-	addql	#1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
 	/* put exception # in d0 */
 	movel	%sp@(PT_VECTOR),%d0
 	swap	%d0			/* extract bits 25:18 */
@@ -244,7 +243,6 @@ ENTRY(inthandler)
 auto_irqhandler_fixup = . + 2
 	jbsr	process_int		/* process the IRQ */
 	addql	#8,%sp			/* pop parameters off stack */
-	subql	#1,%curptr@(TASK_INFO+TINFO_PREEMPT+1)
 	jeq	ret_from_last_interrupt
 2:	RESTORE_ALL
 
diff --git a/arch/m68k/coldfire/ints.c b/arch/m68k/coldfire/ints.c
index 3316463..85ce27e 100644
--- a/arch/m68k/coldfire/ints.c
+++ b/arch/m68k/coldfire/ints.c
@@ -100,6 +100,7 @@ asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
 	old_regs = set_irq_regs(fp);
 	kstat_cpu(0).irqs[vec]++;
 
+	irq_enter();
 	node = irq_list[vec];
 	if (!node)
 		handle_badint(fp);
@@ -109,6 +110,7 @@ asmlinkage void process_int(unsigned long vec, struct pt_regs *fp)
 			node = node->next;
 		} while (node);
 	}
+	irq_exit();
 
 	set_irq_regs(old_regs);
 }

             reply	other threads:[~2009-07-02  4:06 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-02  4:07 Lanttor [this message]
2009-07-02  8:24 ` Interrupt issue on m68k platform and some fix Andreas Schwab
2009-07-02  8:58   ` Lanttor
2009-07-02  9:05     ` Andreas Schwab
2009-07-02 10:06       ` Lanttor
2009-07-02 20:25       ` Roman Hodek
2009-07-03  3:18         ` Lanttor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4A4C3267.2040705@freescale.com \
    --to=lanttor.guo@freescale.com \
    --cc=linux-m68k@vger.kernel.org \
    --cc=uclinux-dev@uclinux.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox