linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Steffen Rumler <Steffen.Rumler@siemens.com>
To: linuxppc <linuxppc-embedded@lists.linuxppc.org>
Subject: Re: Problem of concurrency in arch/ppc/8260_io/uart.c
Date: Mon, 15 Sep 2003 12:18:10 +0200	[thread overview]
Message-ID: <3F6591E2.5070205@siemens.com> (raw)

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

Hi,

I have seen a similar problem for the 2.4.20.

When I force a lot of console output via the following command:

   while true; do cd /; ls -R; done

and type-in some letters in parallel, the console
becomes crazy.

I have added some instrumentation in order to dump the
TX Buffer Descriptor Table. I have found that the
hardware pointer (TBPTR) and the software pointer (tx_cur)
are not more synchronized together:

 >> make new rlogin session <<
/root# cd /proc/driver

/root# cat uart-bdtables; cat mpc82xx/smc1_pram | grep SMC1_PRAM_TBPTR

TX BD table
   (000 at 0xfff005f0) status: 0x1000 len: 0001 addr: 0x001bb084
   (001 at 0xfff005f8) status: 0x1000 len: 0001 addr: 0x001bb0a4
* (002 at 0xfff00600) status: 0x1000 len: 0001 addr: 0x001bb0c4
   (003 at 0xfff00608) status: 0x3000 len: 0004 addr: 0x001bb0e4
    SMC1_PRAM_TBPTR            0x20         2     0600

    --> hardware and software pointer still synchronized

    >> force console to become crazy (see above) <<

/root# cat uart-bdtables; cat mpc82xx/smc1_pram | grep SMC1_PRAM_TBPTR

TX BD table (tbptr: 0x00000088)
   (000 at 0xfff005f0) status: 0x1000 len: 0003 addr: 0x001bb084
* (001 at 0xfff005f8) status: 0x1000 len: 0021 addr: 0x001bb0a4
   (002 at 0xfff00600) status: 0x1000 len: 0001 addr: 0x001bb0c4
   (003 at 0xfff00608) status: 0x3000 len: 0001 addr: 0x001bb0e4
    SMC1_PRAM_TBPTR            0x20         2     0600

    --> hardware and software pointer NOT more synchronized

    >> make additional console output: echo foo >/dev/console <<

/root# cat uart-bdtables; cat mpc82xx/smc1_pram | grep SMC1_PRAM_TBPTR

* (000 at 0xfff005f0) status: 0x1000 len: 0003 addr: 0x001bb084
   (001 at 0xfff005f8) status: 0x9000 len: 0004 addr: 0x001bb0a4
   (002 at 0xfff00600) status: 0x1000 len: 0001 addr: 0x001bb0c4
   (003 at 0xfff00608) status: 0x3000 len: 0001 addr: 0x001bb0e4
    SMC1_PRAM_TBPTR            0x20         2     05f0

    --> hardware pointer hangs at 0x5f0 because R-Bit not set, but
        at 0x5f8

Inside uart.c, there are the following output routines:

   rs_8xx_put_char()
   rs_8xx_write()
   rs_8xx_send_xchar()
   my_console_write()

I think there must be a synchronization accessing the
TX BD table. I suggest the patch attached.


Best Regards
Steffen
--


--------------------------------------------------------------

Steffen Rumler
ICN CP D NT SW 7
Siemens AG
Hofmannstr. 51                 Email: Steffen.Rumler@siemens.com
D-81359 Munich                 Phone: +49 89 722-44061
Germany                        Fax  : +49 89 722-36703

--------------------------------------------------------------



[-- Attachment #2: uart.c.patch --]
[-- Type: text/plain, Size: 3270 bytes --]

diff -Naur old/uart.c new/uart.c
--- old/uart.c	Mon Sep 15 11:52:02 2003
+++ new/uart.c	Mon Sep 15 11:51:32 2003
@@ -44,6 +44,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <asm/immap_8260.h>
 #include <asm/mpc8260.h>
@@ -253,6 +254,11 @@
 	cbd_t			*rx_cur;
 	cbd_t			*tx_bd_base;
 	cbd_t			*tx_cur;
+
+        /*  for output synchronization
+         */
+        spinlock_t output_lock;
+        
 } ser_info_t;
 
 static void change_speed(ser_info_t *info);
@@ -1010,6 +1016,7 @@
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 	volatile cbd_t	*bdp;
+        unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
 		return;
@@ -1017,6 +1024,8 @@
 	if (!tty)
 		return;
 
+        spin_lock_irqsave(&(info->output_lock), flags);
+
 	bdp = info->tx_cur;
 	while (bdp->cbd_sc & BD_SC_READY);
 
@@ -1033,6 +1042,8 @@
 
 	info->tx_cur = (cbd_t *)bdp;
 
+        spin_unlock_irqrestore(&(info->output_lock), flags);
+
 }
 
 static int rs_8xx_write(struct tty_struct * tty, int from_user,
@@ -1041,6 +1052,7 @@
 	int	c, ret = 0;
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 	volatile cbd_t *bdp;
+        unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->device, "rs_write"))
 		return 0;
@@ -1048,6 +1060,8 @@
 	if (!tty) 
 		return 0;
 
+        spin_lock_irqsave(&(info->output_lock), flags);
+
 	bdp = info->tx_cur;
 
 	while (1) {
@@ -1086,6 +1100,9 @@
 			bdp++;
 		info->tx_cur = (cbd_t *)bdp;
 	}
+
+        spin_unlock_irqrestore(&(info->output_lock), flags);
+
 	return ret;
 }
 
@@ -1143,12 +1160,15 @@
 static void rs_8xx_send_xchar(struct tty_struct *tty, char ch)
 {
 	volatile cbd_t	*bdp;
+        unsigned long flags;
 
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 
 	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
 		return;
 
+        spin_lock_irqsave(&(info->output_lock), flags);
+
 	bdp = info->tx_cur;
 	while (bdp->cbd_sc & BD_SC_READY);
 
@@ -1164,6 +1184,8 @@
 		bdp++;
 
 	info->tx_cur = (cbd_t *)bdp;
+
+        spin_unlock_irqrestore(&(info->output_lock), flags);
 }
 
 /*
@@ -2227,9 +2249,11 @@
 	volatile	cbd_t		*bdp, *bdbase;
 	volatile	smc_uart_t	*up;
 	volatile	u_char		*cp;
+        unsigned long   flags;
 
 	ser = rs_table + idx;
 
+
 	/* If the port has been initialized for general use, we have
 	 * to use the buffer descriptors allocated there.  Otherwise,
 	 * we simply use the single buffer allocated.
@@ -2237,6 +2261,7 @@
 	if ((info = (ser_info_t *)ser->info) != NULL) {
 		bdp = info->tx_cur;
 		bdbase = info->tx_bd_base;
+                spin_lock_irqsave(&(info->output_lock), flags);
 	}
 	else {
 		/* Pointer to UART in parameter ram.
@@ -2309,6 +2334,9 @@
 
 	if (info)
 		info->tx_cur = (cbd_t *)bdp;
+
+        if (info)
+            spin_unlock_irqrestore(&(info->output_lock), flags);
 }
 
 static void serial_console_write(struct console *c, const char *s,
@@ -2764,6 +2792,7 @@
 			info->tqueue_hangup.data = info;
 			info->line = i;
 			info->state = state;
+                        spin_lock_init(&(info->output_lock));
 			state->info = (struct async_struct *)info;
 
 			/* We need to allocate a transmit and receive buffer

             reply	other threads:[~2003-09-15 10:18 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-09-15 10:18 Steffen Rumler [this message]
2003-09-15 13:30 ` Problem of concurrency in arch/ppc/8260_io/uart.c Joakim Tjernlund
     [not found] <3F8E8817.5ACD7ACB@siemens.com>
2003-10-16 14:11 ` Joakim Tjernlund
  -- strict thread matches above, loose matches on Subject: below --
2003-09-15 16:26 Jean-Denis Boyer
2003-09-15 18:37 ` Joakim Tjernlund
2003-09-15 18:53 ` Dan Malek
2003-09-15 20:02   ` Joakim Tjernlund
2003-09-16 12:25     ` Joakim Tjernlund
2003-09-17  9:33       ` Joakim Tjernlund
2003-09-17 13:38         ` Joakim Tjernlund
2003-09-17 14:58         ` Dan Malek
2003-09-17 15:22           ` Joakim Tjernlund
2003-09-17 16:33             ` Joakim Tjernlund
2003-09-23  8:28               ` Joakim Tjernlund
2003-09-26 16:31               ` Tom Rini
2003-09-26 18:34                 ` Joakim Tjernlund
2003-09-26 18:38                   ` Tom Rini
2003-09-26 21:24               ` Tom Rini
2003-09-26 22:20                 ` Dan Malek
2003-09-26 22:39                   ` Joakim Tjernlund
2003-09-26 23:12                     ` Dan Malek
2003-09-27  8:07                       ` Joakim Tjernlund
2003-09-27 13:43                         ` Joakim Tjernlund
2003-09-29 15:33                           ` Tom Rini
2003-09-30 15:28                             ` Dan Malek
2003-10-01 14:26                               ` Kumar Gala
2003-10-01 14:32                                 ` Tom Rini
2003-10-01 14:48                                   ` Gary Thomas
2003-10-01 21:20                                     ` Joakim Tjernlund
2003-10-01 21:32                                       ` Tom Rini
2003-10-01 21:51                                         ` Joakim Tjernlund
2003-10-01 22:00                                           ` Tom Rini
2003-10-01 22:17                                             ` Joakim Tjernlund
2003-10-01 22:31                                               ` Tom Rini
2003-10-01 23:23                                                 ` Robin Gilks
2003-10-01 23:51                                                   ` Tom Rini
2003-10-02  0:47                                                     ` Wolfgang Denk
2003-10-02  6:03                                         ` Dan Kegel
2003-10-02 19:15                                           ` Tom Rini
2003-03-07 15:18 Jean-Denis Boyer
2003-03-07 12:52 Dayton, Dean
2003-03-06 21:39 Jean-Denis Boyer

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=3F6591E2.5070205@siemens.com \
    --to=steffen.rumler@siemens.com \
    --cc=linuxppc-embedded@lists.linuxppc.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;
as well as URLs for NNTP newsgroup(s).