* Re: [PATCH] gianfar: Fix TX ring processing on SMP machines
From: David Miller @ 2010-03-04 8:41 UTC (permalink / raw)
To: avorontsov
Cc: linuxppc-dev, netdev, martyn.welch, paul.gortmaker, Sandeep.Kumar
In-Reply-To: <20100303181858.GA458@oksana.dev.rtsoft.ru>
From: Anton Vorontsov <avorontsov@ru.mvista.com>
Date: Wed, 3 Mar 2010 21:18:58 +0300
> Starting with commit a3bc1f11e9b867a4f49505 ("gianfar: Revive SKB
> recycling") gianfar driver sooner or later stops transmitting any
> packets on SMP machines.
>
> start_xmit() prepares new skb for transmitting, generally it does
> three things:
>
> 1. sets up all BDs (marks them ready to send), except the first one.
> 2. stores skb into tx_queue->tx_skbuff so that clean_tx_ring()
> would cleanup it later.
> 3. sets up the first BD, i.e. marks it ready.
>
> Here is what clean_tx_ring() does:
>
> 1. reads skbs from tx_queue->tx_skbuff
> 2. checks if the *last* BD is ready. If it's still ready [to send]
> then it it isn't transmitted, so clean_tx_ring() returns.
> Otherwise it actually cleanups BDs. All is OK.
>
> Now, if there is just one BD, code flow:
>
> - start_xmit(): stores skb into tx_skbuff. Note that the first BD
> (which is also the last one) isn't marked as ready, yet.
> - clean_tx_ring(): sees that skb is not null, *and* its lstatus
> says that it is NOT ready (like if BD was sent), so it cleans
> it up (bad!)
> - start_xmit(): marks BD as ready [to send], but it's too late.
>
> We can fix this simply by reordering lstatus/tx_skbuff writes.
>
> Reported-by: Martyn Welch <martyn.welch@ge.com>
> Bisected-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
> Tested-by: Paul Gortmaker <paul.gortmaker@windriver.com>
> Tested-by: Martyn Welch <martyn.welch@ge.com>
Applied.
^ permalink raw reply
* Re: [PATCH v2] hvc_console: Fix race between hvc_close and hvc_remove
From: Amit Shah @ 2010-03-04 2:44 UTC (permalink / raw)
To: Alan Cox; +Cc: linuxppc-dev, Rusty Russell, linux-kernel
In-Reply-To: <20100303155522.6d6a4562@lxorguk.ukuu.org.uk>
On (Wed) Mar 03 2010 [15:55:22], Alan Cox wrote:
> On Wed, 3 Mar 2010 20:59:48 +0530
> Amit Shah <amit.shah@redhat.com> wrote:
>
> > Alan pointed out a race in the code where hvc_remove is invoked. The
> > recent virtio_console work is the first user of hvc_remove().
>
> Looks better to me.
Thanks, Alan.
Ben, can you pick this up via your tree if it looks good to you?
Amit
^ permalink raw reply
* Re: [Patch v.2] mpc5200b/uart: improve baud rate calculation (reach high baud rates, better accuracy)
From: Grant Likely @ 2010-03-03 21:07 UTC (permalink / raw)
To: Albrecht Dreß; +Cc: Linux PPC Development
In-Reply-To: <1267640583.4760.0@antares>
Hi Albrecht,
I like this version much better. Comments below...
On Wed, Mar 3, 2010 at 11:23 AM, Albrecht Dre=DF <albrecht.dress@arcor.de> =
wrote:
> On the MPC5200B, make very high baud rates (e.g. 3 MBaud) accessible and
> achieve a higher precision for high baud rates in general. =A0This is don=
e by
> selecting the appropriate prescaler (/4 or /32). =A0As to keep the code c=
lean,
> the getuartclk method has been dropped, and all calculations are done wit=
h a
> "virtual" /4 prescaler for all chips for maximum accuracy. =A0A new set_d=
ivisor
> method scales down the divisor values found by the generic serial code
> appropriately.
>
> Note: only "fsl,mpc5200b-psc-uart" compatible devices benefit from these
> improvements.
>
> Tested on a custom 5200B based board, with up to 3 MBaud, and with both
> "fsl,mpc5200b-psc-uart" and "fsl,mpc5200-psc-uart" devices.
>
> Signed-off-by: Albrecht Dre=DF <albrecht.dress@arcor.de>
>
> ---
>
> Changes vs. v.1: include improvements suggested by Wolfram and Grant (tha=
nks a
> lot for your helpful input!!): drop getuartclk method and use the highest
> possible frequency for calculation, use new psc_ops for the 5200b, let th=
e
> set_divisor method do all the dirty work, emit warnings if bad divisor va=
lues
> have been selected.
>
>
> --- linux-2.6.33-orig/drivers/serial/mpc52xx_uart.c =A0 =A0 2010-02-24 19=
:52:17.000000000 +0100
> +++ linux-2.6.33/drivers/serial/mpc52xx_uart.c =A02010-03-03 10:52:04.000=
000000 +0100
> @@ -388,9 +445,25 @@ static void mpc512x_psc_cw_restore_ints(
> =A0 =A0 =A0 =A0out_be32(&FIFO_512x(port)->rximr, port->read_status_mask &=
0x7f);
> =A0}
>
> -static unsigned long mpc512x_getuartclk(void *p)
> +static void mpc512x_psc_set_divisor(struct uart_port *port,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 uns=
igned int divisor)
> =A0{
> - =A0 =A0 =A0 return mpc5xxx_get_bus_frequency(p);
> + =A0 =A0 =A0 struct mpc52xx_psc __iomem *psc =3D PSC(port);
> +
> + =A0 =A0 =A0 /* adjust divisor for a /16 prescaler; see note in
> + =A0 =A0 =A0 =A0* mpc52xx_uart_of_probe() */
> + =A0 =A0 =A0 divisor =3D (divisor + 2) / 4;
> + =A0 =A0 =A0 if (divisor > 0xffff) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pr_warning("%s: divisor overflow (%x), use =
0xffff\n", __func__,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0divisor);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 divisor =3D 0xffff;
> + =A0 =A0 =A0 } else if (divisor =3D=3D 0) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 pr_warning("%s: divisor 0, use 1\n", __func=
__);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 divisor =3D 1;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 out_8(&psc->ctur, divisor >> 8);
> + =A0 =A0 =A0 out_8(&psc->ctlr, divisor & 0xff);
Save yourself some duplicated code here. The above 14 lines can be
shared between the 512x, 52xx and 5200b versions. Create yourself an
internal __mpc5xxx_psc_set_divisor() function that is passed the *psc,
the divisor, and the clock select register setting (both the 5200 and
the 5121 have the clock select register).
> =A0}
>
> =A0static struct psc_ops mpc512x_psc_ops =3D {
> @@ -409,7 +482,7 @@ static struct psc_ops mpc512x_psc_ops =3D
> =A0 =A0 =A0 =A0.read_char =3D mpc512x_psc_read_char,
> =A0 =A0 =A0 =A0.cw_disable_ints =3D mpc512x_psc_cw_disable_ints,
> =A0 =A0 =A0 =A0.cw_restore_ints =3D mpc512x_psc_cw_restore_ints,
> - =A0 =A0 =A0 .getuartclk =3D mpc512x_getuartclk,
> + =A0 =A0 =A0 .set_divisor =3D mpc512x_psc_set_divisor,
> =A0};
> =A0#endif
>
> @@ -564,7 +637,6 @@ mpc52xx_uart_set_termios(struct uart_por
> =A0 =A0 =A0 =A0struct mpc52xx_psc __iomem *psc =3D PSC(port);
> =A0 =A0 =A0 =A0unsigned long flags;
> =A0 =A0 =A0 =A0unsigned char mr1, mr2;
> - =A0 =A0 =A0 unsigned short ctr;
> =A0 =A0 =A0 =A0unsigned int j, baud, quot;
>
> =A0 =A0 =A0 =A0/* Prepare what we're gonna write */
> @@ -604,7 +676,6 @@ mpc52xx_uart_set_termios(struct uart_por
>
> =A0 =A0 =A0 =A0baud =3D uart_get_baud_rate(port, new, old, 0, port->uartc=
lk/16);
I'm probably nitpicking, because I don't know if the io pin will
handle this speed but uartclk/16 is no longer the maximum baudrate if
a /4 prescaler is used.
> =A0 =A0 =A0 =A0quot =3D uart_get_divisor(port, baud);
> - =A0 =A0 =A0 ctr =3D quot & 0xffff;
>
> =A0 =A0 =A0 =A0/* Get the lock */
> =A0 =A0 =A0 =A0spin_lock_irqsave(&port->lock, flags);
> @@ -635,8 +706,7 @@ mpc52xx_uart_set_termios(struct uart_por
> =A0 =A0 =A0 =A0out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
> =A0 =A0 =A0 =A0out_8(&psc->mode, mr1);
> =A0 =A0 =A0 =A0out_8(&psc->mode, mr2);
> - =A0 =A0 =A0 out_8(&psc->ctur, ctr >> 8);
> - =A0 =A0 =A0 out_8(&psc->ctlr, ctr & 0xff);
> + =A0 =A0 =A0 psc_ops->set_divisor(port, quot);
Hmmm. The divisor calculations have some tricky bits to them. I
would consider changing the set_divisor() function to accept a baud
rate, and modify the set_divisor function to call uart_get_divisor().
That way each set_divisor() can do whatever makes the most sense for
the divisors available to it. The 5121 for example has both a /10 and
a /32 divisor, plus it can use an external clock.
>
> =A0 =A0 =A0 =A0if (UART_ENABLE_MS(port, new->c_cflag))
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0mpc52xx_uart_enable_ms(port);
> @@ -1007,7 +1077,8 @@ mpc52xx_console_setup(struct console *co
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return ret;
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 uartclk =3D psc_ops->getuartclk(np);
> + =A0 =A0 =A0 /* see remarks about the uart clock in mpc52xx_uart_of_prob=
e() */
> + =A0 =A0 =A0 uartclk =3D mpc5xxx_get_bus_frequency(np) * 4;
> =A0 =A0 =A0 =A0if (uartclk =3D=3D 0) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0pr_debug("Could not find uart clock freque=
ncy!\n");
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -EINVAL;
> @@ -1090,6 +1161,7 @@ static struct uart_driver mpc52xx_uart_d
>
> =A0static struct of_device_id mpc52xx_uart_of_match[] =3D {
> =A0#ifdef CONFIG_PPC_MPC52xx
> + =A0 =A0 =A0 { .compatible =3D "fsl,mpc5200b-psc-uart", .data =3D &mpc52=
00b_psc_ops, },
> =A0 =A0 =A0 =A0{ .compatible =3D "fsl,mpc5200-psc-uart", .data =3D &mpc52=
xx_psc_ops, },
> =A0 =A0 =A0 =A0/* binding used by old lite5200 device trees: */
> =A0 =A0 =A0 =A0{ .compatible =3D "mpc5200-psc-uart", .data =3D &mpc52xx_p=
sc_ops, },
> @@ -1122,7 +1194,24 @@ mpc52xx_uart_of_probe(struct of_device *
> =A0 =A0 =A0 =A0pr_debug("Found %s assigned to ttyPSC%x\n",
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 mpc52xx_uart_nodes[idx]->full_name, idx);
>
> - =A0 =A0 =A0 uartclk =3D psc_ops->getuartclk(op->node);
> + =A0 =A0 =A0 /*
> + =A0 =A0 =A0 =A0* Note about the uart clock:
> + =A0 =A0 =A0 =A0* This series of processors use the ipb clock frequency =
for the clock
> + =A0 =A0 =A0 =A0* generation scaled down by prescalers and a 16-bit coun=
ter register:
> + =A0 =A0 =A0 =A0* - the 5200 has a /32 prescaler
> + =A0 =A0 =A0 =A0* - the 5200B has selectable /4 or /32 prescalers (i.e. =
the counter
> + =A0 =A0 =A0 =A0* =A0 reg can be viewed as a 19-bit value, of which we c=
an use either
> + =A0 =A0 =A0 =A0* =A0 the upper or the lower 16 bits - in the latter cas=
e the three
> + =A0 =A0 =A0 =A0* =A0 MSB's must of course be 0)
> + =A0 =A0 =A0 =A0* - the 512x has a /16 prescaler
According to the user manual, the 5121 has both a /32 and /10
prescaler. As such, I'd rather see uartclk get set to the raw value
returned from mpc5xxx_get_bus_frequency() and do all the
transformations in the set_divisor() hook.
Also, I looked at the generic code, and while it does assume a /16
prescaler, that is pretty easy to handle at the point of calling the
uart_get_divisor() function.
> + =A0 =A0 =A0 =A0* The generic serial code assumes a prescaler of /16. =
=A0As we want to
> + =A0 =A0 =A0 =A0* achieve the maximum accuracy possible, we let the gene=
ric serial
> + =A0 =A0 =A0 =A0* code perform all calculations with the /4 prescaler, i=
.e. we have
> + =A0 =A0 =A0 =A0* to set the uart clock to ipb freq * 4 here. =A0The set=
_divisor methods
> + =A0 =A0 =A0 =A0* for the different chips are responsible for scaling do=
wn the divisor
> + =A0 =A0 =A0 =A0* value appropriately.
> + =A0 =A0 =A0 =A0*/
> + =A0 =A0 =A0 uartclk =3D mpc5xxx_get_bus_frequency(op->node) * 4;
> =A0 =A0 =A0 =A0if (uartclk =3D=3D 0) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0dev_dbg(&op->dev, "Could not find uart clo=
ck frequency!\n");
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return -EINVAL;
>
>
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* [Patch v.2] mpc5200b/uart: improve baud rate calculation (reach high baud rates, better accuracy)
From: Albrecht Dreß @ 2010-03-03 18:23 UTC (permalink / raw)
To: Linux PPC Development, Likely, Grant
On the MPC5200B, make very high baud rates (e.g. 3 MBaud) accessible and
achieve a higher precision for high baud rates in general. This is done by
selecting the appropriate prescaler (/4 or /32). As to keep the code clean=
,
the getuartclk method has been dropped, and all calculations are done with =
a
"virtual" /4 prescaler for all chips for maximum accuracy. A new set_divis=
or
method scales down the divisor values found by the generic serial code
appropriately.
Note: only "fsl,mpc5200b-psc-uart" compatible devices benefit from these
improvements.
Tested on a custom 5200B based board, with up to 3 MBaud, and with both
"fsl,mpc5200b-psc-uart" and "fsl,mpc5200-psc-uart" devices.
Signed-off-by: Albrecht Dre=DF <albrecht.dress@arcor.de>
---
Changes vs. v.1: include improvements suggested by Wolfram and Grant (thank=
s a
lot for your helpful input!!): drop getuartclk method and use the highest
possible frequency for calculation, use new psc_ops for the 5200b, let the
set_divisor method do all the dirty work, emit warnings if bad divisor valu=
es
have been selected.
=20
--- linux-2.6.33-orig/drivers/serial/mpc52xx_uart.c 2010-02-24 19:52:17.000=
000000 +0100
+++ linux-2.6.33/drivers/serial/mpc52xx_uart.c 2010-03-03 10:52:04.00000000=
0 +0100
@@ -144,7 +144,8 @@ struct psc_ops {
unsigned char (*read_char)(struct uart_port *port);
void (*cw_disable_ints)(struct uart_port *port);
void (*cw_restore_ints)(struct uart_port *port);
- unsigned long (*getuartclk)(void *p);
+ void (*set_divisor)(struct uart_port *port,
+ unsigned int divisor);
};
=20
#ifdef CONFIG_PPC_MPC52xx
@@ -154,9 +155,6 @@ static void mpc52xx_psc_fifo_init(struct
struct mpc52xx_psc __iomem *psc =3D PSC(port);
struct mpc52xx_psc_fifo __iomem *fifo =3D FIFO_52xx(port);
=20
- /* /32 prescaler */
- out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);
-
out_8(&fifo->rfcntl, 0x00);
out_be16(&fifo->rfalarm, 0x1ff);
out_8(&fifo->tfcntl, 0x07);
@@ -245,15 +243,55 @@ static void mpc52xx_psc_cw_restore_ints(
out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
}
=20
-/* Search for bus-frequency property in this node or a parent */
-static unsigned long mpc52xx_getuartclk(void *p)
+static void mpc52xx_psc_set_divisor(struct uart_port *port,
+ unsigned int divisor)
{
- /*
- * 5200 UARTs have a / 32 prescaler
- * but the generic serial code assumes 16
- * so return ipb freq / 2
- */
- return mpc5xxx_get_bus_frequency(p) / 2;
+ struct mpc52xx_psc __iomem *psc =3D PSC(port);
+
+ /* adjust divisor for a /32 prescaler; see note in
+ * mpc52xx_uart_of_probe() */
+ divisor =3D (divisor + 4) / 8;
+ if (divisor > 0xffff) {
+ pr_warning("%s: divisor overflow (%x), use 0xffff\n", __func__,
+ divisor);
+ divisor =3D 0xffff;
+ } else if (divisor =3D=3D 0) {
+ pr_warning("%s: divisor 0, use 1\n", __func__);
+ divisor =3D 1;
+ }
+
+ /* prescaler */
+ out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */
+
+ /* ctr */
+ out_8(&psc->ctur, divisor >> 8);
+ out_8(&psc->ctlr, divisor & 0xff);
+}
+
+static void mpc5200b_psc_set_divisor(struct uart_port *port,
+ unsigned int divisor)
+{
+ struct mpc52xx_psc __iomem *psc =3D PSC(port);
+
+ /* set prescaler; see note in mpc52xx_uart_of_probe() */
+ if (divisor > 0xffff) {
+ divisor =3D (divisor + 4) / 8;
+ out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /32 */
+ } else
+ out_be16(&psc->mpc52xx_psc_clock_select, 0xff00); /* /4 */
+
+ if (divisor > 0xffff) {
+ pr_warning("%s: divisor overflow (%x), use 0xffff\n", __func__,
+ divisor);
+ divisor =3D 0xffff;
+ } else if (divisor =3D=3D 0) {
+ pr_warning("%s: divisor 0, use 1\n", __func__);
+ divisor =3D 1;
+ }
+
+ /* ctr */
+ out_8(&psc->ctur, divisor >> 8);
+ out_8(&psc->ctlr, divisor & 0xff);
}
=20
static struct psc_ops mpc52xx_psc_ops =3D {
@@ -272,7 +310,26 @@ static struct psc_ops mpc52xx_psc_ops =3D=20
.read_char =3D mpc52xx_psc_read_char,
.cw_disable_ints =3D mpc52xx_psc_cw_disable_ints,
.cw_restore_ints =3D mpc52xx_psc_cw_restore_ints,
- .getuartclk =3D mpc52xx_getuartclk,
+ .set_divisor =3D mpc52xx_psc_set_divisor,
+};
+
+static struct psc_ops mpc5200b_psc_ops =3D {
+ .fifo_init =3D mpc52xx_psc_fifo_init,
+ .raw_rx_rdy =3D mpc52xx_psc_raw_rx_rdy,
+ .raw_tx_rdy =3D mpc52xx_psc_raw_tx_rdy,
+ .rx_rdy =3D mpc52xx_psc_rx_rdy,
+ .tx_rdy =3D mpc52xx_psc_tx_rdy,
+ .tx_empty =3D mpc52xx_psc_tx_empty,
+ .stop_rx =3D mpc52xx_psc_stop_rx,
+ .start_tx =3D mpc52xx_psc_start_tx,
+ .stop_tx =3D mpc52xx_psc_stop_tx,
+ .rx_clr_irq =3D mpc52xx_psc_rx_clr_irq,
+ .tx_clr_irq =3D mpc52xx_psc_tx_clr_irq,
+ .write_char =3D mpc52xx_psc_write_char,
+ .read_char =3D mpc52xx_psc_read_char,
+ .cw_disable_ints =3D mpc52xx_psc_cw_disable_ints,
+ .cw_restore_ints =3D mpc52xx_psc_cw_restore_ints,
+ .set_divisor =3D mpc5200b_psc_set_divisor,
};
=20
#endif /* CONFIG_MPC52xx */
@@ -388,9 +445,25 @@ static void mpc512x_psc_cw_restore_ints(
out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f);
}
=20
-static unsigned long mpc512x_getuartclk(void *p)
+static void mpc512x_psc_set_divisor(struct uart_port *port,
+ unsigned int divisor)
{
- return mpc5xxx_get_bus_frequency(p);
+ struct mpc52xx_psc __iomem *psc =3D PSC(port);
+
+ /* adjust divisor for a /16 prescaler; see note in
+ * mpc52xx_uart_of_probe() */
+ divisor =3D (divisor + 2) / 4;
+ if (divisor > 0xffff) {
+ pr_warning("%s: divisor overflow (%x), use 0xffff\n", __func__,
+ divisor);
+ divisor =3D 0xffff;
+ } else if (divisor =3D=3D 0) {
+ pr_warning("%s: divisor 0, use 1\n", __func__);
+ divisor =3D 1;
+ }
+
+ out_8(&psc->ctur, divisor >> 8);
+ out_8(&psc->ctlr, divisor & 0xff);
}
=20
static struct psc_ops mpc512x_psc_ops =3D {
@@ -409,7 +482,7 @@ static struct psc_ops mpc512x_psc_ops =3D=20
.read_char =3D mpc512x_psc_read_char,
.cw_disable_ints =3D mpc512x_psc_cw_disable_ints,
.cw_restore_ints =3D mpc512x_psc_cw_restore_ints,
- .getuartclk =3D mpc512x_getuartclk,
+ .set_divisor =3D mpc512x_psc_set_divisor,
};
#endif
=20
@@ -564,7 +637,6 @@ mpc52xx_uart_set_termios(struct uart_por
struct mpc52xx_psc __iomem *psc =3D PSC(port);
unsigned long flags;
unsigned char mr1, mr2;
- unsigned short ctr;
unsigned int j, baud, quot;
=20
/* Prepare what we're gonna write */
@@ -604,7 +676,6 @@ mpc52xx_uart_set_termios(struct uart_por
=20
baud =3D uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
quot =3D uart_get_divisor(port, baud);
- ctr =3D quot & 0xffff;
=20
/* Get the lock */
spin_lock_irqsave(&port->lock, flags);
@@ -635,8 +706,7 @@ mpc52xx_uart_set_termios(struct uart_por
out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
out_8(&psc->mode, mr1);
out_8(&psc->mode, mr2);
- out_8(&psc->ctur, ctr >> 8);
- out_8(&psc->ctlr, ctr & 0xff);
+ psc_ops->set_divisor(port, quot);
=20
if (UART_ENABLE_MS(port, new->c_cflag))
mpc52xx_uart_enable_ms(port);
@@ -1007,7 +1077,8 @@ mpc52xx_console_setup(struct console *co
return ret;
}
=20
- uartclk =3D psc_ops->getuartclk(np);
+ /* see remarks about the uart clock in mpc52xx_uart_of_probe() */
+ uartclk =3D mpc5xxx_get_bus_frequency(np) * 4;
if (uartclk =3D=3D 0) {
pr_debug("Could not find uart clock frequency!\n");
return -EINVAL;
@@ -1090,6 +1161,7 @@ static struct uart_driver mpc52xx_uart_d
=20
static struct of_device_id mpc52xx_uart_of_match[] =3D {
#ifdef CONFIG_PPC_MPC52xx
+ { .compatible =3D "fsl,mpc5200b-psc-uart", .data =3D &mpc5200b_psc_ops, }=
,
{ .compatible =3D "fsl,mpc5200-psc-uart", .data =3D &mpc52xx_psc_ops, },
/* binding used by old lite5200 device trees: */
{ .compatible =3D "mpc5200-psc-uart", .data =3D &mpc52xx_psc_ops, },
@@ -1122,7 +1194,24 @@ mpc52xx_uart_of_probe(struct of_device *
pr_debug("Found %s assigned to ttyPSC%x\n",
mpc52xx_uart_nodes[idx]->full_name, idx);
=20
- uartclk =3D psc_ops->getuartclk(op->node);
+ /*
+ * Note about the uart clock:
+ * This series of processors use the ipb clock frequency for the clock
+ * generation scaled down by prescalers and a 16-bit counter register:
+ * - the 5200 has a /32 prescaler
+ * - the 5200B has selectable /4 or /32 prescalers (i.e. the counter
+ * reg can be viewed as a 19-bit value, of which we can use either
+ * the upper or the lower 16 bits - in the latter case the three
+ * MSB's must of course be 0)
+ * - the 512x has a /16 prescaler
+ * The generic serial code assumes a prescaler of /16. As we want to
+ * achieve the maximum accuracy possible, we let the generic serial
+ * code perform all calculations with the /4 prescaler, i.e. we have
+ * to set the uart clock to ipb freq * 4 here. The set_divisor methods
+ * for the different chips are responsible for scaling down the divisor
+ * value appropriately.
+ */
+ uartclk =3D mpc5xxx_get_bus_frequency(op->node) * 4;
if (uartclk =3D=3D 0) {
dev_dbg(&op->dev, "Could not find uart clock frequency!\n");
return -EINVAL;
^ permalink raw reply
* [PATCH] gianfar: Fix TX ring processing on SMP machines
From: Anton Vorontsov @ 2010-03-03 18:18 UTC (permalink / raw)
To: David Miller
Cc: linuxppc-dev, netdev, Martyn Welch, Paul Gortmaker,
Sandeep Gopalpet
Starting with commit a3bc1f11e9b867a4f49505 ("gianfar: Revive SKB
recycling") gianfar driver sooner or later stops transmitting any
packets on SMP machines.
start_xmit() prepares new skb for transmitting, generally it does
three things:
1. sets up all BDs (marks them ready to send), except the first one.
2. stores skb into tx_queue->tx_skbuff so that clean_tx_ring()
would cleanup it later.
3. sets up the first BD, i.e. marks it ready.
Here is what clean_tx_ring() does:
1. reads skbs from tx_queue->tx_skbuff
2. checks if the *last* BD is ready. If it's still ready [to send]
then it it isn't transmitted, so clean_tx_ring() returns.
Otherwise it actually cleanups BDs. All is OK.
Now, if there is just one BD, code flow:
- start_xmit(): stores skb into tx_skbuff. Note that the first BD
(which is also the last one) isn't marked as ready, yet.
- clean_tx_ring(): sees that skb is not null, *and* its lstatus
says that it is NOT ready (like if BD was sent), so it cleans
it up (bad!)
- start_xmit(): marks BD as ready [to send], but it's too late.
We can fix this simply by reordering lstatus/tx_skbuff writes.
Reported-by: Martyn Welch <martyn.welch@ge.com>
Bisected-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Tested-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Tested-by: Martyn Welch <martyn.welch@ge.com>
Cc: Sandeep Gopalpet <Sandeep.Kumar@freescale.com>
Cc: Stable <stable@vger.kernel.org> [2.6.33]
---
drivers/net/gianfar.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 8bd3c9f..cccb409 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -2021,7 +2021,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
/* setup the TxBD length and buffer pointer for the first BD */
- tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE);
@@ -2053,6 +2052,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp_start->lstatus = lstatus;
+ eieio(); /* force lstatus write before tx_skbuff */
+
+ tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
+
/* Update the current skb pointer to the next entry we will use
* (wrapping if necessary) */
tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
--
1.7.0
^ permalink raw reply related
* [RFC] powerpc: add support for new hcall H_BEST_ENERGY
From: Vaidyanathan Srinivasan @ 2010-03-03 18:18 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Anton Blanchard; +Cc: linuxppc-dev
Hi,
A new hypervisor call H_BEST_ENERGY is supported in IBM pseries ppc64
platform in order to exports platform energy management capabilities
to user space administrative tools.
This hypervisor calls provides hints or suggested list of cpus to
activate or deactivate for optimized energy management. The following
patch add a new pseries specific device driver that will export such
platform energy management related information over sysfs interface
for use by user space administrative tools.
The device driver exports the following sysfs files:
/sys/device/system/cpu/pseries_(de)activate_hint_list and
/sys/device/system/cpu/cpuN/pseries_(de)activate_hint.
Typical usage:
# cat /sys/devices/system/cpu/pseries_activate_hint_list
16,20,24
# cat /sys/devices/system/cpu/pseries_deactivate_hint_list
0,4,8,12
Comma separated list of recommended cpu numbers to activate or
deactivate.
cat /sys/device/system/cpu/cpuN/pseries_(de)activate_hint
will provide a single integer value returned by the platform
for that cpu.
Please let me know your comments and suggestions.
Thanks,
Vaidy
---
powerpc: add support for new hcall H_BEST_ENERGY
Create sysfs interface to export data from H_BEST_ENERGY hcall
that can be used by administrative tools on supported pseries
platforms for energy management optimizations.
/sys/device/system/cpu/pseries_(de)activate_hint_list and
/sys/device/system/cpu/cpuN/pseries_(de)activate_hint will provide
hints for activation and deactivation of cpus respectively.
Added new driver module
arch/powerpc/platforms/pseries/pseries_energy.c
under new config option CONFIG_PSERIES_ENERGY
Signed-off-by: Vaidyanathan Srinivasan <svaidy@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/hvcall.h | 3
arch/powerpc/kernel/setup-common.c | 2
arch/powerpc/platforms/pseries/Kconfig | 10 +
arch/powerpc/platforms/pseries/Makefile | 1
arch/powerpc/platforms/pseries/pseries_energy.c | 246 +++++++++++++++++++++++
5 files changed, 261 insertions(+), 1 deletions(-)
create mode 100644 arch/powerpc/platforms/pseries/pseries_energy.c
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index f027581..396599f 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -230,7 +230,8 @@
#define H_ENABLE_CRQ 0x2B0
#define H_SET_MPP 0x2D0
#define H_GET_MPP 0x2D4
-#define MAX_HCALL_OPCODE H_GET_MPP
+#define H_BEST_ENERGY 0x2F4
+#define MAX_HCALL_OPCODE H_BEST_ENERGY
#ifndef __ASSEMBLY__
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 03dd6a2..fbd93e3 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -359,6 +359,8 @@ void __init check_for_initrd(void)
#ifdef CONFIG_SMP
int threads_per_core, threads_shift;
+EXPORT_SYMBOL_GPL(threads_per_core);
+
cpumask_t threads_core_mask;
static void __init cpu_init_thread_core_maps(int tpc)
diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig
index c667f0f..b3dd108 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -33,6 +33,16 @@ config PSERIES_MSI
depends on PCI_MSI && EEH
default y
+config PSERIES_ENERGY
+ tristate "pseries energy management capabilities driver"
+ depends on PPC_PSERIES
+ default y
+ help
+ Provides interface to platform energy management capabilities
+ on supported PSERIES platforms.
+ Provides: /sys/devices/system/cpu/pseries_(de)activation_hint_list
+ and /sys/devices/system/cpu/cpuN/pseries_(de)activation_hint
+
config SCANLOG
tristate "Scanlog dump interface"
depends on RTAS_PROC && PPC_PSERIES
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 0ff5174..3813977 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o
obj-$(CONFIG_KEXEC) += kexec.o
obj-$(CONFIG_PCI) += pci.o pci_dlpar.o
obj-$(CONFIG_PSERIES_MSI) += msi.o
+obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o
obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o
diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c
new file mode 100644
index 0000000..0390188
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/pseries_energy.c
@@ -0,0 +1,246 @@
+/*
+ * POWER platform energy management driver
+ * Copyright (C) 2010 IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This pseries platform device driver provides access to
+ * platform energy management capabilities.
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+#include <linux/of.h>
+#include <asm/cputhreads.h>
+#include <asm/page.h>
+#include <asm/hvcall.h>
+
+
+#define MODULE_VERS "1.0"
+#define MODULE_NAME "pseries_energy"
+
+/* Helper Routines to convert between drc_index to cpu numbers */
+
+static u32 cpu_to_drc_index(int cpu)
+{
+ struct device_node *dn = NULL;
+ const int *indexes;
+ int i;
+ dn = of_find_node_by_name(dn, "cpus");
+ indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
+ /* Convert logical cpu number to core number */
+ i = cpu / threads_per_core;
+ /*
+ * The first element indexes[0] is the number of drc_indexes
+ * returned in the list. Hence i+1 will get the drc_index
+ * corresponding to core number i.
+ */
+ WARN_ON(i > indexes[0]);
+ return indexes[i + 1];
+}
+
+static int drc_index_to_cpu(u32 drc_index)
+{
+ struct device_node *dn = NULL;
+ const int *indexes;
+ int i, cpu;
+ dn = of_find_node_by_name(dn, "cpus");
+ indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
+ /*
+ * First element in the array is the number of drc_indexes
+ * returned. Search through the list to find the matching
+ * drc_index and get the core number
+ */
+ for (i = 0; i < indexes[0]; i++) {
+ if (indexes[i + 1] == drc_index)
+ break;
+ }
+ /* Convert core number to logical cpu number */
+ cpu = i * threads_per_core;
+ return cpu;
+}
+
+/*
+ * pseries hypervisor call H_BEST_ENERGY provides hints to OS on
+ * preferred logical cpus to activate or deactivate for optimized
+ * energy consumption.
+ */
+
+#define FLAGS_MODE1 0x004E200000080E01
+#define FLAGS_MODE2 0x004E200000080401
+#define FLAGS_ACTIVATE 0x100
+
+static ssize_t get_best_energy_list(char *page, int activate)
+{
+ int rc, cnt, i, cpu;
+ unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+ unsigned long flags = 0;
+ u32 *buf_page;
+ char *s = page;
+
+ buf_page = (u32 *) get_zeroed_page(GFP_KERNEL);
+
+ if (!buf_page)
+ return 0;
+
+ flags = FLAGS_MODE1;
+ if (activate)
+ flags |= FLAGS_ACTIVATE;
+
+ rc = plpar_hcall9(H_BEST_ENERGY, retbuf, flags, 0, __pa(buf_page),
+ 0, 0, 0, 0, 0, 0);
+
+ if (rc != H_SUCCESS) {
+ free_page((unsigned long) buf_page);
+ return -EINVAL;
+ }
+
+ cnt = retbuf[0];
+ for (i = 0; i < cnt; i++) {
+ cpu = drc_index_to_cpu(buf_page[2*i+1]);
+ if ((cpu_online(cpu) && !activate) ||
+ (!cpu_online(cpu) && activate))
+ s += sprintf(s, "%d,", cpu);
+ }
+ if (s > page) { /* Something to show */
+ s--; /* Suppress last comma */
+ s += sprintf(s, "\n");
+ }
+
+ free_page((unsigned long) buf_page);
+ return s-page;
+}
+
+static ssize_t get_best_energy_data(struct sys_device *dev,
+ char *page, int activate)
+{
+ int rc;
+ unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+ unsigned long flags = 0;
+
+ flags = FLAGS_MODE2;
+ if (activate)
+ flags |= FLAGS_ACTIVATE;
+
+ rc = plpar_hcall9(H_BEST_ENERGY, retbuf, flags,
+ cpu_to_drc_index(dev->id),
+ 0, 0, 0, 0, 0, 0, 0);
+
+ if (rc != H_SUCCESS)
+ return -EINVAL;
+
+ return sprintf(page, "%lu\n", retbuf[1] >> 32);
+}
+
+/* Wrapper functions */
+
+static ssize_t cpu_activate_hint_list_show(struct sysdev_class *class,
+ char *page)
+{
+ return get_best_energy_list(page, 1);
+}
+
+static ssize_t cpu_deactivate_hint_list_show(struct sysdev_class *class,
+ char *page)
+{
+ return get_best_energy_list(page, 0);
+}
+
+static ssize_t percpu_activate_hint_show(struct sys_device *dev,
+ struct sysdev_attribute *attr, char *page)
+{
+ return get_best_energy_data(dev, page, 1);
+}
+
+static ssize_t percpu_deactivate_hint_show(struct sys_device *dev,
+ struct sysdev_attribute *attr, char *page)
+{
+ return get_best_energy_data(dev, page, 0);
+}
+
+/*
+ * Create sysfs interface:
+ * /sys/devices/system/cpu/pseries_activate_hint_list
+ * /sys/devices/system/cpu/pseries_deactivate_hint_list
+ * Comma separated list of cpus to activate or deactivate
+ * /sys/devices/system/cpu/cpuN/pseries_activate_hint
+ * /sys/devices/system/cpu/cpuN/pseries_deactivate_hint
+ * Per-cpu value of the hint
+ */
+
+struct sysdev_class_attribute attr_cpu_activate_hint_list =
+ _SYSDEV_CLASS_ATTR(pseries_activate_hint_list, 0444,
+ cpu_activate_hint_list_show, NULL);
+
+struct sysdev_class_attribute attr_cpu_deactivate_hint_list =
+ _SYSDEV_CLASS_ATTR(pseries_deactivate_hint_list, 0444,
+ cpu_deactivate_hint_list_show, NULL);
+
+struct sysdev_attribute attr_percpu_activate_hint =
+ _SYSDEV_ATTR(pseries_activate_hint, 0444,
+ percpu_activate_hint_show, NULL);
+
+struct sysdev_attribute attr_percpu_deactivate_hint =
+ _SYSDEV_ATTR(pseries_deactivate_hint, 0444,
+ percpu_deactivate_hint_show, NULL);
+
+static int __init pseries_energy_init(void)
+{
+ int cpu, err;
+ struct sys_device *cpu_sys_dev;
+
+ /* Create the sysfs files */
+ err = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+ &attr_cpu_activate_hint_list.attr);
+ if (!err)
+ err = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+ &attr_cpu_deactivate_hint_list.attr);
+
+ for_each_possible_cpu(cpu) {
+ cpu_sys_dev = get_cpu_sysdev(cpu);
+ err = sysfs_create_file(&cpu_sys_dev->kobj,
+ &attr_percpu_activate_hint.attr);
+ if (err)
+ break;
+ err = sysfs_create_file(&cpu_sys_dev->kobj,
+ &attr_percpu_deactivate_hint.attr);
+ if (err)
+ break;
+ }
+ return err;
+
+}
+
+static void __exit pseries_energy_cleanup(void)
+{
+ int cpu;
+ struct sys_device *cpu_sys_dev;
+
+ /* Remove the sysfs files */
+ sysfs_remove_file(&cpu_sysdev_class.kset.kobj,
+ &attr_cpu_activate_hint_list.attr);
+
+ sysfs_remove_file(&cpu_sysdev_class.kset.kobj,
+ &attr_cpu_deactivate_hint_list.attr);
+
+ for_each_possible_cpu(cpu) {
+ cpu_sys_dev = get_cpu_sysdev(cpu);
+ sysfs_remove_file(&cpu_sys_dev->kobj,
+ &attr_percpu_activate_hint.attr);
+ sysfs_remove_file(&cpu_sys_dev->kobj,
+ &attr_percpu_deactivate_hint.attr);
+ }
+}
+
+module_init(pseries_energy_init);
+module_exit(pseries_energy_cleanup);
+MODULE_DESCRIPTION("Driver for pseries platform energy management");
+MODULE_AUTHOR("Vaidyanathan Srinivasan");
+MODULE_LICENSE("GPL");
^ permalink raw reply related
* Re: [PATCH v2] hvc_console: Fix race between hvc_close and hvc_remove
From: Alan Cox @ 2010-03-03 15:55 UTC (permalink / raw)
To: Amit Shah; +Cc: linuxppc-dev, Rusty Russell, linux-kernel
In-Reply-To: <1267630188-30824-1-git-send-email-amit.shah@redhat.com>
On Wed, 3 Mar 2010 20:59:48 +0530
Amit Shah <amit.shah@redhat.com> wrote:
> Alan pointed out a race in the code where hvc_remove is invoked. The
> recent virtio_console work is the first user of hvc_remove().
Looks better to me.
Alan
^ permalink raw reply
* [PATCH v2] hvc_console: Fix race between hvc_close and hvc_remove
From: Amit Shah @ 2010-03-03 15:29 UTC (permalink / raw)
To: linux-kernel; +Cc: Amit Shah, linuxppc-dev, Rusty Russell, Alan Cox
Alan pointed out a race in the code where hvc_remove is invoked. The
recent virtio_console work is the first user of hvc_remove().
Alan describes it thus:
The hvc_console assumes that a close and remove call can't occur at the
same time.
In addition tty_hangup(tty) is problematic as tty_hangup is asynchronous
itself....
So this can happen
hvc_close hvc_remove
hung up ? - no
lock
tty = hp->tty
unlock
lock
hp->tty = NULL
unlock
notify del
kref_put the hvc struct
close completes
tty is destroyed
tty_hangup dead tty
tty->ops will be NULL
NULL->...
This patch adds some tty krefs and also converts to using tty_vhangup().
Reported-by: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
CC: Alan Cox <alan@lxorguk.ukuu.org.uk>
CC: linuxppc-dev@ozlabs.org
CC: Rusty Russell <rusty@rustcorp.com.au>
---
Alan, how does this version look?
I've tested with multiple virtio_console ports.
There's some other bug in the hvc_remove code that's unrelated:
hot-removal of one console port results in all other hvc consoles to
stop working. I'll look at that once this is finalised.
drivers/char/hvc_console.c | 31 +++++++++++++++++++++----------
1 files changed, 21 insertions(+), 10 deletions(-)
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 4c3b59b..7e94b3c 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -312,6 +312,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
spin_lock_irqsave(&hp->lock, flags);
/* Check and then increment for fast path open. */
if (hp->count++ > 0) {
+ tty_kref_get(tty);
spin_unlock_irqrestore(&hp->lock, flags);
hvc_kick();
return 0;
@@ -319,7 +320,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
tty->driver_data = hp;
- hp->tty = tty;
+ hp->tty = tty_kref_get(tty);
spin_unlock_irqrestore(&hp->lock, flags);
@@ -336,6 +337,7 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
spin_lock_irqsave(&hp->lock, flags);
hp->tty = NULL;
spin_unlock_irqrestore(&hp->lock, flags);
+ tty_kref_put(tty);
tty->driver_data = NULL;
kref_put(&hp->kref, destroy_hvc_struct);
printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
@@ -363,13 +365,18 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
return;
hp = tty->driver_data;
+
spin_lock_irqsave(&hp->lock, flags);
+ tty_kref_get(tty);
if (--hp->count == 0) {
/* We are done with the tty pointer now. */
hp->tty = NULL;
spin_unlock_irqrestore(&hp->lock, flags);
+ /* Put the ref obtained in hvc_open() */
+ tty_kref_put(tty);
+
if (hp->ops->notifier_del)
hp->ops->notifier_del(hp, hp->data);
@@ -389,6 +396,7 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
spin_unlock_irqrestore(&hp->lock, flags);
}
+ tty_kref_put(tty);
kref_put(&hp->kref, destroy_hvc_struct);
}
@@ -424,10 +432,11 @@ static void hvc_hangup(struct tty_struct *tty)
spin_unlock_irqrestore(&hp->lock, flags);
if (hp->ops->notifier_hangup)
- hp->ops->notifier_hangup(hp, hp->data);
+ hp->ops->notifier_hangup(hp, hp->data);
while(temp_open_count) {
--temp_open_count;
+ tty_kref_put(tty);
kref_put(&hp->kref, destroy_hvc_struct);
}
}
@@ -592,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp)
}
/* No tty attached, just skip */
- tty = hp->tty;
+ tty = tty_kref_get(hp->tty);
if (tty == NULL)
goto bail;
@@ -672,6 +681,8 @@ int hvc_poll(struct hvc_struct *hp)
tty_flip_buffer_push(tty);
}
+ if (tty)
+ tty_kref_put(tty);
return poll_mask;
}
@@ -807,7 +818,7 @@ int hvc_remove(struct hvc_struct *hp)
struct tty_struct *tty;
spin_lock_irqsave(&hp->lock, flags);
- tty = hp->tty;
+ tty = tty_kref_get(hp->tty);
if (hp->index < MAX_NR_HVC_CONSOLES)
vtermnos[hp->index] = -1;
@@ -819,18 +830,18 @@ int hvc_remove(struct hvc_struct *hp)
/*
* We 'put' the instance that was grabbed when the kref instance
* was initialized using kref_init(). Let the last holder of this
- * kref cause it to be removed, which will probably be the tty_hangup
+ * kref cause it to be removed, which will probably be the tty_vhangup
* below.
*/
kref_put(&hp->kref, destroy_hvc_struct);
/*
- * This function call will auto chain call hvc_hangup. The tty should
- * always be valid at this time unless a simultaneous tty close already
- * cleaned up the hvc_struct.
+ * This function call will auto chain call hvc_hangup.
*/
- if (tty)
- tty_hangup(tty);
+ if (tty) {
+ tty_vhangup(tty);
+ tty_kref_put(tty);
+ }
return 0;
}
EXPORT_SYMBOL_GPL(hvc_remove);
--
1.6.2.5
^ permalink raw reply related
* Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
From: Joakim Tjernlund @ 2010-03-03 10:38 UTC (permalink / raw)
To: hs; +Cc: Scott Wood, linuxppc-dev, Wolfgang Denk
In-Reply-To: <4B8E3582.8060003@denx.de>
Heiko Schocher <hs@denx.de> wrote on 2010/03/03 11:10:10:
>
> Hello Joakim,
>
> Joakim Tjernlund wrote:
> > Heiko Schocher <hs@denx.de> wrote on 2010/03/03 09:02:47:
> [...]
> >> Here the results:
> >> (The first 4 rows are the results for the kernel without your patches,
> >> the next 4 rows are the results for the kernel with your patches)
> >>
> >> make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results'
> >
> > I see both ups and downs in this test, don't quite understand why.
> > What is your config w.r.t SWAP, MODULES, CPU6 and CPU15?
>
> Sorry, forgot to say, where to find the sources. You can find them
> here:
>
> http://git.denx.de/?p=linux-2.6-denx.git;a=shortlog;h=refs/heads/tqm8xx
OK, so you got SWAP=no, MODULES=yes, CPU6=no, CPU15=no
PIN_TLB isn't listed in you def config so I assume
it is no?
MODULES=yes nullifies one optimization.
I don't understand the bad numbers for Prot Fault:
File & VM system latencies in microseconds - smaller is better
-------------------------------------------------------------------------------
Host OS 0K File 10K File Mmap Prot Page 100fd
Create Delete Create Delete Latency Fault Fault selct
--------- ------------- ------ ------ ------ ------ ------- ----- ------- -----
tqm8xx Linux 2.6.33- 5917.2 3968.3 31.2K 4329.0 4147.0 18.8 34.1 135.2
tqm8xx Linux 2.6.33- 5714.3 3937.0 32.3K 6060.6 4210.0 14.2 34.5 131.4
tqm8xx Linux 2.6.33- 5747.1 4000.0 31.2K 4329.0 4114.0 7.692 34.0 133.1
tqm8xx Linux 2.6.33- 5747.1 4081.6 30.3K 4273.5 4100.0 18.2 34.2 135.0
tqm8xx Linux 2.6.33- 5714.3 3952.6 31.2K 4273.5 4130.0 33.5 35.1 136.1
tqm8xx Linux 2.6.33- 5714.3 3906.2 31.2K 6060.6 4105.0 25.7 35.5 135.9
tqm8xx Linux 2.6.33- 5681.8 3921.6 32.3K 4255.3 4144.0 23.5 35.0 134.9
tqm8xx Linux 2.6.33- 5649.7 3937.0 30.3K 4237.3 4116.0 21.6 35.3 135.3
Could you try reverting patch:
8xx: Don't touch ACCESSED when no SWAP.
and see if that makes a difference?
Turning on pinned TLBs(you must turn on ADVANCED_OPTIONS first) could be an improvement,
regardless of my patches.
Jocke
^ permalink raw reply
* Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
From: Heiko Schocher @ 2010-03-03 10:10 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: Scott Wood, linuxppc-dev, Wolfgang Denk
In-Reply-To: <OF5AEF2DED.4E6AA5A2-ONC12576DB.002FD2D9-C12576DB.00305B81@transmode.se>
Hello Joakim,
Joakim Tjernlund wrote:
> Heiko Schocher <hs@denx.de> wrote on 2010/03/03 09:02:47:
[...]
>> Here the results:
>> (The first 4 rows are the results for the kernel without your patches,
>> the next 4 rows are the results for the kernel with your patches)
>>
>> make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results'
>
> I see both ups and downs in this test, don't quite understand why.
> What is your config w.r.t SWAP, MODULES, CPU6 and CPU15?
Sorry, forgot to say, where to find the sources. You can find them
here:
http://git.denx.de/?p=linux-2.6-denx.git;a=shortlog;h=refs/heads/tqm8xx
bye
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply
* Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
From: Joakim Tjernlund @ 2010-03-03 8:59 UTC (permalink / raw)
Cc: Scott Wood, linuxppc-dev, hs, Wolfgang Denk
In-Reply-To: <OF5AEF2DED.4E6AA5A2-ONC12576DB.002FD2D9-C12576DB.00305B81@transmode.se>
>
> Heiko Schocher <hs@denx.de> wrote on 2010/03/03 09:02:47:
> >
> > Hello Joakim,
> >
> > I tried your 4 patches on a MPC855M based system:
>
> Thanks a lot for testing this for me!
>
> >
> > -bash-3.2# cat /proc/cpuinfo
> > processor : 0
> > cpu : 8xx
> > clock : 66.000000MHz
> > revision : 0.0 (pvr 0050 0000)
> > bogomips : 8.25
> > timebase : 4125000
> > platform : TQM8xx
> > model : TQM8xx
> > Memory : 32 MB
> > -bash-3.2# cat /proc/version
> > Linux version 2.6.33-rc6-01500-gbddcb41-dirty (hs@xpert.denx.de) (gcc version
> > 4.2.2) #9 Tue Mar 2 18:08:49 CET 2010
> > -bash-3.2#
> >
> > First I looked for the Boottime:
> >
> > Booting Linux:
> >
> > 2.6.33 2.6.33tunned
> > ... until "Freeing unused kernel memory" message (= enter user space) ~4s ~4s
> > ... until "login:" message (= full multi-user mode) 56s 56s
> >
> > and I did a Performance test with lmbench, see:
> > http://sourceforge.net/projects/lmbench
> >
> > Here the results:
> > (The first 4 rows are the results for the kernel without your patches,
> > the next 4 rows are the results for the kernel with your patches)
> >
> > make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results'
>
> I see both ups and downs in this test, don't quite understand why.
> What is your config w.r.t SWAP, MODULES, CPU6 and CPU15?
Forgot to ask for PIN_TLB too
^ permalink raw reply
* Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
From: Joakim Tjernlund @ 2010-03-03 8:48 UTC (permalink / raw)
To: hs; +Cc: Scott Wood, linuxppc-dev, Wolfgang Denk
In-Reply-To: <4B8E17A7.10509@denx.de>
Heiko Schocher <hs@denx.de> wrote on 2010/03/03 09:02:47:
>
> Hello Joakim,
>
> I tried your 4 patches on a MPC855M based system:
Thanks a lot for testing this for me!
>
> -bash-3.2# cat /proc/cpuinfo
> processor : 0
> cpu : 8xx
> clock : 66.000000MHz
> revision : 0.0 (pvr 0050 0000)
> bogomips : 8.25
> timebase : 4125000
> platform : TQM8xx
> model : TQM8xx
> Memory : 32 MB
> -bash-3.2# cat /proc/version
> Linux version 2.6.33-rc6-01500-gbddcb41-dirty (hs@xpert.denx.de) (gcc version
> 4.2.2) #9 Tue Mar 2 18:08:49 CET 2010
> -bash-3.2#
>
> First I looked for the Boottime:
>
> Booting Linux:
>
> 2.6.33 2.6.33tunned
> ... until "Freeing unused kernel memory" message (= enter user space) ~4s ~4s
> ... until "login:" message (= full multi-user mode) 56s 56s
>
> and I did a Performance test with lmbench, see:
> http://sourceforge.net/projects/lmbench
>
> Here the results:
> (The first 4 rows are the results for the kernel without your patches,
> the next 4 rows are the results for the kernel with your patches)
>
> make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results'
I see both ups and downs in this test, don't quite understand why.
What is your config w.r.t SWAP, MODULES, CPU6 and CPU15?
>
> L M B E N C H 3 . 0 S U M M A R Y
> ------------------------------------
> (Alpha software, do not distribute)
>
> Basic system parameters
> ------------------------------------------------------------------------------
> Host OS Description Mhz tlb cache mem scal
> pages line par load
> bytes
> --------- ------------- ----------------------- ---- ----- ----- ------ ----
> tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 32 16 1.0400 1
> tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 7 16 1.0400 1
> tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 7 16 1.0400 1
> tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 32 16 1.0400 1
> tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 32 16 1.0400 1
> tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 7 16 1.0400 1
> tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 7 16 1.0400 1
> tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 32 16 1.0400 1
>
> Processor, Processes - times in microseconds - smaller is better
> ------------------------------------------------------------------------------
> Host OS Mhz null null open slct sig sig fork exec sh
> call I/O stat clos TCP inst hndl proc proc proc
> --------- ------------- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
> tqm8xx Linux 2.6.33- 66 2.97 10.3 129. 1377 272. 21.8 91.3 6949 29.K 89.K
> tqm8xx Linux 2.6.33- 66 3.06 10.5 124. 1375 273. 21.8 91.3 7136 30.K 89.K
> tqm8xx Linux 2.6.33- 66 3.06 10.6 129. 1365 272. 21.2 96.6 6889 29.K 89.K
> tqm8xx Linux 2.6.33- 66 3.06 10.5 124. 1309 272. 21.8 101. 6896 29.K 89.K
> tqm8xx Linux 2.6.33- 66 2.97 8.86 126. 1336 273. 21.7 84.2 6785 29.K 88.K
> tqm8xx Linux 2.6.33- 66 3.06 8.90 130. 1343 263. 21.3 84.7 7080 29.K 88.K
> tqm8xx Linux 2.6.33- 66 3.52 8.97 129. 1339 270. 22.4 84.4 6823 29.K 88.K
> tqm8xx Linux 2.6.33- 66 2.97 8.99 127. 1333 261. 22.4 87.0 7037 29.K 87.K
>
[SNIP integer/float test, these are not relevant]
>
> Context switching - times in microseconds - smaller is better
> -------------------------------------------------------------------------
> Host OS 2p/0K 2p/16K 2p/64K 8p/16K 8p/64K 16p/16K 16p/64K
> ctxsw ctxsw ctxsw ctxsw ctxsw ctxsw ctxsw
> --------- ------------- ------ ------ ------ ------ ------ ------- -------
> tqm8xx Linux 2.6.33- 92.6 109.6 110.9 137.5 173.8 151.8 199.3
> tqm8xx Linux 2.6.33- 95.8 108.5 104.7 137.1 172.7 150.9 194.7
> tqm8xx Linux 2.6.33- 95.8 118.8 97.5 146.4 162.0 160.8 190.1
> tqm8xx Linux 2.6.33- 92.9 111.9 101.0 138.1 166.6 152.3 192.0
> tqm8xx Linux 2.6.33- 90.8 108.5 116.2 134.3 171.8 147.1 210.0
> tqm8xx Linux 2.6.33- 100.1 111.4 105.0 136.4 173.1 148.3 200.8
> tqm8xx Linux 2.6.33- 98.7 111.3 111.8 135.7 172.5 147.9 200.9
> tqm8xx Linux 2.6.33- 92.0 117.9 109.9 141.6 170.4 154.9 196.4
>
> *Local* Communication latencies in microseconds - smaller is better
> ---------------------------------------------------------------------
> Host OS 2p/0K Pipe AF UDP RPC/ TCP RPC/ TCP
> ctxsw UNIX UDP TCP conn
> --------- ------------- ----- ----- ---- ----- ----- ----- ----- ----
> tqm8xx Linux 2.6.33- 92.6 338.4 581. 720.1 1047. 2749
> tqm8xx Linux 2.6.33- 95.8 334.0 595. 725.0 1051. 2754
> tqm8xx Linux 2.6.33- 95.8 330.9 574. 720.1 1047. 2772
> tqm8xx Linux 2.6.33- 92.9 338.8 574. 714.3 1046. 2742
> tqm8xx Linux 2.6.33- 90.8 322.1 576. 734.9 1012. 2706
> tqm8xx Linux 2.6.33- 100.1 326.0 565. 719.5 1027. 2702
> tqm8xx Linux 2.6.33- 98.7 322.8 571. 713.8 1028. 2711
> tqm8xx Linux 2.6.33- 92.0 328.1 549. 714.1 1022. 2696
>
> *Remote* Communication latencies in microseconds - smaller is better
> ---------------------------------------------------------------------
> Host OS UDP RPC/ TCP RPC/ TCP
> UDP TCP conn
> --------- ------------- ----- ----- ----- ----- ----
> tqm8xx Linux 2.6.33-
> tqm8xx Linux 2.6.33-
> tqm8xx Linux 2.6.33-
> tqm8xx Linux 2.6.33-
> tqm8xx Linux 2.6.33-
> tqm8xx Linux 2.6.33-
> tqm8xx Linux 2.6.33-
> tqm8xx Linux 2.6.33-
>
> File & VM system latencies in microseconds - smaller is better
> -------------------------------------------------------------------------------
> Host OS 0K File 10K File Mmap Prot Page 100fd
> Create Delete Create Delete Latency Fault Fault selct
> --------- ------------- ------ ------ ------ ------ ------- ----- ------- -----
> tqm8xx Linux 2.6.33- 5917.2 3968.3 31.2K 4329.0 4147.0 18.8 34.1 135.2
> tqm8xx Linux 2.6.33- 5714.3 3937.0 32.3K 6060.6 4210.0 14.2 34.5 131.4
> tqm8xx Linux 2.6.33- 5747.1 4000.0 31.2K 4329.0 4114.0 7.692 34.0 133.1
> tqm8xx Linux 2.6.33- 5747.1 4081.6 30.3K 4273.5 4100.0 18.2 34.2 135.0
> tqm8xx Linux 2.6.33- 5714.3 3952.6 31.2K 4273.5 4130.0 33.5 35.1 136.1
> tqm8xx Linux 2.6.33- 5714.3 3906.2 31.2K 6060.6 4105.0 25.7 35.5 135.9
> tqm8xx Linux 2.6.33- 5681.8 3921.6 32.3K 4255.3 4144.0 23.5 35.0 134.9
> tqm8xx Linux 2.6.33- 5649.7 3937.0 30.3K 4237.3 4116.0 21.6 35.3 135.3
>
> *Local* Communication bandwidths in MB/s - bigger is better
> -----------------------------------------------------------------------------
> Host OS Pipe AF TCP File Mmap Bcopy Bcopy Mem Mem
> UNIX reread reread (libc) (hand) read write
> --------- ------------- ---- ---- ---- ------ ------ ------ ------ ---- -----
> tqm8xx Linux 2.6.33- 14.8 15.6 10.1 21.0 55.5 32.3 34.5 55.6 53.0
> tqm8xx Linux 2.6.33- 14.8 15.6 10.7 21.0 55.5 32.3 34.5 55.6 53.0
> tqm8xx Linux 2.6.33- 14.8 15.7 12.7 21.0 55.5 32.3 34.5 55.6 53.0
> tqm8xx Linux 2.6.33- 14.8 15.6 13.9 21.0 55.5 32.3 34.5 55.6 53.0
> tqm8xx Linux 2.6.33- 14.8 15.8 12.9 21.0 55.7 32.5 34.6 55.8 53.1
> tqm8xx Linux 2.6.33- 14.8 15.7 14.0 21.0 55.7 32.4 34.6 55.8 53.1
> tqm8xx Linux 2.6.33- 14.8 15.8 12.9 21.0 55.7 32.5 34.6 55.8 53.1
> tqm8xx Linux 2.6.33- 14.8 15.8 13.0 21.0 55.7 32.5 34.6 55.8 53.1
>
> Memory latencies in nanoseconds - smaller is better
> (WARNING - may not be correct, check graphs)
> ------------------------------------------------------------------------------
> Host OS Mhz L1 $ L2 $ Main mem Rand mem Guesses
> --------- ------------- --- ---- ---- -------- -------- -------
> tqm8xx Linux 2.6.33- 66 31.8 141.0 184.0 1165.7
> tqm8xx Linux 2.6.33- 66 31.8 141.2 184.2 1165.3
> tqm8xx Linux 2.6.33- 66 31.8 141.3 184.3 1165.6
> tqm8xx Linux 2.6.33- 66 31.8 141.3 184.2 1166.2
> tqm8xx Linux 2.6.33- 66 31.8 141.0 171.8 1100.5 No L2 cache?
> tqm8xx Linux 2.6.33- 66 31.8 141.0 171.8 1102.5 No L2 cache?
> tqm8xx Linux 2.6.33- 66 31.8 141.0 171.8 1101.7 No L2 cache?
> tqm8xx Linux 2.6.33- 66 31.8 141.0 171.8 1101.6 No L2 cache?
> make[1]: Leaving directory `/home/hs/lmbench-3.0-a9/results'
>
> bye
> Heiko
>
> --
> DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
>
^ permalink raw reply
* Re: [PATCH 0/4] 8xx: Optimize TLB Miss code.
From: Heiko Schocher @ 2010-03-03 8:02 UTC (permalink / raw)
To: Joakim Tjernlund; +Cc: Scott Wood, linuxppc-dev, Wolfgang Denk
Hello Joakim,
I tried your 4 patches on a MPC855M based system:
-bash-3.2# cat /proc/cpuinfo
processor : 0
cpu : 8xx
clock : 66.000000MHz
revision : 0.0 (pvr 0050 0000)
bogomips : 8.25
timebase : 4125000
platform : TQM8xx
model : TQM8xx
Memory : 32 MB
-bash-3.2# cat /proc/version
Linux version 2.6.33-rc6-01500-gbddcb41-dirty (hs@xpert.denx.de) (gcc version 4.2.2) #9 Tue Mar 2 18:08:49 CET 2010
-bash-3.2#
First I looked for the Boottime:
Booting Linux:
2.6.33 2.6.33tunned
... until "Freeing unused kernel memory" message (= enter user space) ~4s ~4s
... until "login:" message (= full multi-user mode) 56s 56s
and I did a Performance test with lmbench, see:
http://sourceforge.net/projects/lmbench
Here the results:
(The first 4 rows are the results for the kernel without your patches,
the next 4 rows are the results for the kernel with your patches)
make[1]: Entering directory `/home/hs/lmbench-3.0-a9/results'
L M B E N C H 3 . 0 S U M M A R Y
------------------------------------
(Alpha software, do not distribute)
Basic system parameters
------------------------------------------------------------------------------
Host OS Description Mhz tlb cache mem scal
pages line par load
bytes
--------- ------------- ----------------------- ---- ----- ----- ------ ----
tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 32 16 1.0400 1
tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 7 16 1.0400 1
tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 7 16 1.0400 1
tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 32 16 1.0400 1
tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 32 16 1.0400 1
tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 7 16 1.0400 1
tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 7 16 1.0400 1
tqm8xx Linux 2.6.33- powerpc-linux-gnu 66 32 16 1.0400 1
Processor, Processes - times in microseconds - smaller is better
------------------------------------------------------------------------------
Host OS Mhz null null open slct sig sig fork exec sh
call I/O stat clos TCP inst hndl proc proc proc
--------- ------------- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
tqm8xx Linux 2.6.33- 66 2.97 10.3 129. 1377 272. 21.8 91.3 6949 29.K 89.K
tqm8xx Linux 2.6.33- 66 3.06 10.5 124. 1375 273. 21.8 91.3 7136 30.K 89.K
tqm8xx Linux 2.6.33- 66 3.06 10.6 129. 1365 272. 21.2 96.6 6889 29.K 89.K
tqm8xx Linux 2.6.33- 66 3.06 10.5 124. 1309 272. 21.8 101. 6896 29.K 89.K
tqm8xx Linux 2.6.33- 66 2.97 8.86 126. 1336 273. 21.7 84.2 6785 29.K 88.K
tqm8xx Linux 2.6.33- 66 3.06 8.90 130. 1343 263. 21.3 84.7 7080 29.K 88.K
tqm8xx Linux 2.6.33- 66 3.52 8.97 129. 1339 270. 22.4 84.4 6823 29.K 88.K
tqm8xx Linux 2.6.33- 66 2.97 8.99 127. 1333 261. 22.4 87.0 7037 29.K 87.K
Basic integer operations - times in nanoseconds - smaller is better
-------------------------------------------------------------------
Host OS intgr intgr intgr intgr intgr
bit add mul div mod
--------- ------------- ------ ------ ------ ------ ------
tqm8xx Linux 2.6.33- 15.7 18.0 1.5600 124.2 203.1
tqm8xx Linux 2.6.33- 15.7 17.4 1.5800 121.1 202.8
tqm8xx Linux 2.6.33- 15.2 17.9 1.6200 124.2 202.7
tqm8xx Linux 2.6.33- 15.2 17.9 1.6000 125.0 204.0
tqm8xx Linux 2.6.33- 15.7 18.1 1.5600 124.7 204.4
tqm8xx Linux 2.6.33- 15.7 18.1 1.5800 124.2 202.8
tqm8xx Linux 2.6.33- 15.7 17.9 1.5500 124.2 203.2
tqm8xx Linux 2.6.33- 15.7 18.1 1.5500 124.5 202.0
Basic uint64 operations - times in nanoseconds - smaller is better
------------------------------------------------------------------
Host OS int64 int64 int64 int64 int64
bit add mul div mod
--------- ------------- ------ ------ ------ ------ ------
tqm8xx Linux 2.6.33- 15. 13.3 1952.2 1838.2
tqm8xx Linux 2.6.33- 15. 13.2 1951.5 1837.8
tqm8xx Linux 2.6.33- 15. 13.2 1886.7 1907.8
tqm8xx Linux 2.6.33- 15. 13.2 1951.5 1838.2
tqm8xx Linux 2.6.33- 15. 13.3 1887.0 1902.2
tqm8xx Linux 2.6.33- 15. 13.3 1887.4 1901.5
tqm8xx Linux 2.6.33- 15. 13.3 1886.7 1893.0
tqm8xx Linux 2.6.33- 15. 13.3 1950.0 1900.4
Basic float operations - times in nanoseconds - smaller is better
-----------------------------------------------------------------
Host OS float float float float
add mul div bogo
--------- ------------- ------ ------ ------ ------
tqm8xx Linux 2.6.33- 1008.9 1629.2 5527.0 9895.0
tqm8xx Linux 2.6.33- 1008.9 1628.9 5495.0 9892.0
tqm8xx Linux 2.6.33- 1007.8 1622.0 5499.0 9886.0
tqm8xx Linux 2.6.33- 1016.5 1628.6 5319.0 9940.0
tqm8xx Linux 2.6.33- 1008.0 1628.3 5497.0 9879.0
tqm8xx Linux 2.6.33- 1007.6 1577.4 5495.0 9881.0
tqm8xx Linux 2.6.33- 1014.8 1627.1 5493.0 9889.0
tqm8xx Linux 2.6.33- 1004.6 1627.7 5487.0 9881.0
Basic double operations - times in nanoseconds - smaller is better
------------------------------------------------------------------
Host OS double double double double
add mul div bogo
--------- ------------- ------ ------ ------ ------
tqm8xx Linux 2.6.33- 1562.4 2782.8 3730.7 12.6K
tqm8xx Linux 2.6.33- 1556.1 2781.5 3724.3 12.6K
tqm8xx Linux 2.6.33- 1513.9 2801.0 3726.4 12.8K
tqm8xx Linux 2.6.33- 1556.1 2780.9 3611.4 12.6K
tqm8xx Linux 2.6.33- 1570.5 2772.6 3742.1 12.6K
tqm8xx Linux 2.6.33- 1560.1 2703.0 3611.4 12.7K
tqm8xx Linux 2.6.33- 1560.4 2779.5 3760.7 12.7K
tqm8xx Linux 2.6.33- 1559.8 2773.0 3742.1 12.6K
Context switching - times in microseconds - smaller is better
-------------------------------------------------------------------------
Host OS 2p/0K 2p/16K 2p/64K 8p/16K 8p/64K 16p/16K 16p/64K
ctxsw ctxsw ctxsw ctxsw ctxsw ctxsw ctxsw
--------- ------------- ------ ------ ------ ------ ------ ------- -------
tqm8xx Linux 2.6.33- 92.6 109.6 110.9 137.5 173.8 151.8 199.3
tqm8xx Linux 2.6.33- 95.8 108.5 104.7 137.1 172.7 150.9 194.7
tqm8xx Linux 2.6.33- 95.8 118.8 97.5 146.4 162.0 160.8 190.1
tqm8xx Linux 2.6.33- 92.9 111.9 101.0 138.1 166.6 152.3 192.0
tqm8xx Linux 2.6.33- 90.8 108.5 116.2 134.3 171.8 147.1 210.0
tqm8xx Linux 2.6.33- 100.1 111.4 105.0 136.4 173.1 148.3 200.8
tqm8xx Linux 2.6.33- 98.7 111.3 111.8 135.7 172.5 147.9 200.9
tqm8xx Linux 2.6.33- 92.0 117.9 109.9 141.6 170.4 154.9 196.4
*Local* Communication latencies in microseconds - smaller is better
---------------------------------------------------------------------
Host OS 2p/0K Pipe AF UDP RPC/ TCP RPC/ TCP
ctxsw UNIX UDP TCP conn
--------- ------------- ----- ----- ---- ----- ----- ----- ----- ----
tqm8xx Linux 2.6.33- 92.6 338.4 581. 720.1 1047. 2749
tqm8xx Linux 2.6.33- 95.8 334.0 595. 725.0 1051. 2754
tqm8xx Linux 2.6.33- 95.8 330.9 574. 720.1 1047. 2772
tqm8xx Linux 2.6.33- 92.9 338.8 574. 714.3 1046. 2742
tqm8xx Linux 2.6.33- 90.8 322.1 576. 734.9 1012. 2706
tqm8xx Linux 2.6.33- 100.1 326.0 565. 719.5 1027. 2702
tqm8xx Linux 2.6.33- 98.7 322.8 571. 713.8 1028. 2711
tqm8xx Linux 2.6.33- 92.0 328.1 549. 714.1 1022. 2696
*Remote* Communication latencies in microseconds - smaller is better
---------------------------------------------------------------------
Host OS UDP RPC/ TCP RPC/ TCP
UDP TCP conn
--------- ------------- ----- ----- ----- ----- ----
tqm8xx Linux 2.6.33-
tqm8xx Linux 2.6.33-
tqm8xx Linux 2.6.33-
tqm8xx Linux 2.6.33-
tqm8xx Linux 2.6.33-
tqm8xx Linux 2.6.33-
tqm8xx Linux 2.6.33-
tqm8xx Linux 2.6.33-
File & VM system latencies in microseconds - smaller is better
-------------------------------------------------------------------------------
Host OS 0K File 10K File Mmap Prot Page 100fd
Create Delete Create Delete Latency Fault Fault selct
--------- ------------- ------ ------ ------ ------ ------- ----- ------- -----
tqm8xx Linux 2.6.33- 5917.2 3968.3 31.2K 4329.0 4147.0 18.8 34.1 135.2
tqm8xx Linux 2.6.33- 5714.3 3937.0 32.3K 6060.6 4210.0 14.2 34.5 131.4
tqm8xx Linux 2.6.33- 5747.1 4000.0 31.2K 4329.0 4114.0 7.692 34.0 133.1
tqm8xx Linux 2.6.33- 5747.1 4081.6 30.3K 4273.5 4100.0 18.2 34.2 135.0
tqm8xx Linux 2.6.33- 5714.3 3952.6 31.2K 4273.5 4130.0 33.5 35.1 136.1
tqm8xx Linux 2.6.33- 5714.3 3906.2 31.2K 6060.6 4105.0 25.7 35.5 135.9
tqm8xx Linux 2.6.33- 5681.8 3921.6 32.3K 4255.3 4144.0 23.5 35.0 134.9
tqm8xx Linux 2.6.33- 5649.7 3937.0 30.3K 4237.3 4116.0 21.6 35.3 135.3
*Local* Communication bandwidths in MB/s - bigger is better
-----------------------------------------------------------------------------
Host OS Pipe AF TCP File Mmap Bcopy Bcopy Mem Mem
UNIX reread reread (libc) (hand) read write
--------- ------------- ---- ---- ---- ------ ------ ------ ------ ---- -----
tqm8xx Linux 2.6.33- 14.8 15.6 10.1 21.0 55.5 32.3 34.5 55.6 53.0
tqm8xx Linux 2.6.33- 14.8 15.6 10.7 21.0 55.5 32.3 34.5 55.6 53.0
tqm8xx Linux 2.6.33- 14.8 15.7 12.7 21.0 55.5 32.3 34.5 55.6 53.0
tqm8xx Linux 2.6.33- 14.8 15.6 13.9 21.0 55.5 32.3 34.5 55.6 53.0
tqm8xx Linux 2.6.33- 14.8 15.8 12.9 21.0 55.7 32.5 34.6 55.8 53.1
tqm8xx Linux 2.6.33- 14.8 15.7 14.0 21.0 55.7 32.4 34.6 55.8 53.1
tqm8xx Linux 2.6.33- 14.8 15.8 12.9 21.0 55.7 32.5 34.6 55.8 53.1
tqm8xx Linux 2.6.33- 14.8 15.8 13.0 21.0 55.7 32.5 34.6 55.8 53.1
Memory latencies in nanoseconds - smaller is better
(WARNING - may not be correct, check graphs)
------------------------------------------------------------------------------
Host OS Mhz L1 $ L2 $ Main mem Rand mem Guesses
--------- ------------- --- ---- ---- -------- -------- -------
tqm8xx Linux 2.6.33- 66 31.8 141.0 184.0 1165.7
tqm8xx Linux 2.6.33- 66 31.8 141.2 184.2 1165.3
tqm8xx Linux 2.6.33- 66 31.8 141.3 184.3 1165.6
tqm8xx Linux 2.6.33- 66 31.8 141.3 184.2 1166.2
tqm8xx Linux 2.6.33- 66 31.8 141.0 171.8 1100.5 No L2 cache?
tqm8xx Linux 2.6.33- 66 31.8 141.0 171.8 1102.5 No L2 cache?
tqm8xx Linux 2.6.33- 66 31.8 141.0 171.8 1101.7 No L2 cache?
tqm8xx Linux 2.6.33- 66 31.8 141.0 171.8 1101.6 No L2 cache?
make[1]: Leaving directory `/home/hs/lmbench-3.0-a9/results'
bye
Heiko
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
^ permalink raw reply
* Re: [PATCH] powerpc: remove IOMMU_VMERGE config option
From: FUJITA Tomonori @ 2010-03-03 0:25 UTC (permalink / raw)
To: michael; +Cc: arnd, linux-kernel, fujita.tomonori, linuxppc-dev, davem
In-Reply-To: <1267575232.7814.21.camel@concordia>
On Wed, 03 Mar 2010 11:13:52 +1100
Michael Ellerman <michael@ellerman.id.au> wrote:
> On Wed, 2010-03-03 at 08:54 +0900, FUJITA Tomonori wrote:
> > Seems that IOMMU_VMERGE option description gives the false
> > information:
> >
> > http://marc.info/?l=linux-sparc&m=126753808727669&w=2
> > http://marc.info/?l=linux-sparc&m=126753880528825&w=2
> >
> > IOMMU_VMERGE is unnecessary nowadays so how about removing it?
>
> Except you didn't remove it, you just made it uneditable? Why not get
> rid of it entirely.
Oops, yeah, I should have. Here's the second version.
Thanks,
=
From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Subject: [PATCH] powerpc: remove IOMMU_VMERGE config option
The description says:
Cause IO segments sent to a device for DMA to be merged virtually
by the IOMMU when they happen to have been allocated contiguously.
This doesn't add pressure to the IOMMU allocator. However, some
drivers don't support getting large merged segments coming back
from *_map_sg().
Most drivers don't have this problem; it is safe to say Y here.
It's out of date. Long ago, drivers didn't have a way to tell IOMMUs
about their segment length limit (that is, the maximum segment length
that they can handle). So IOMMUs merged as many segments as possible
and gave too large segments to drivers.
dma_get_max_seg_size() was introduced to solve the above
problem. Device drives can use the API to tell IOMMU about the maximum
segment length that they can handle. In addition, the default limit
(64K) should be safe for everyone.
So this config option seems to be unnecessary.
Note that this config option just enables users to disable the virtual
merging by default. Users can still disable the virtual merging by the
boot parameter.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
---
arch/powerpc/Kconfig | 13 -------------
arch/powerpc/kernel/iommu.c | 7 +------
2 files changed, 1 insertions(+), 19 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 155d571..c984bc5 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -313,19 +313,6 @@ config 8XX_MINIMAL_FPEMU
It is recommended that you build a soft-float userspace instead.
-config IOMMU_VMERGE
- bool "Enable IOMMU virtual merging"
- depends on PPC64
- default y
- help
- Cause IO segments sent to a device for DMA to be merged virtually
- by the IOMMU when they happen to have been allocated contiguously.
- This doesn't add pressure to the IOMMU allocator. However, some
- drivers don't support getting large merged segments coming back
- from *_map_sg().
-
- Most drivers don't have this problem; it is safe to say Y here.
-
config IOMMU_HELPER
def_bool PPC64
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 5547ae6..ec94f90 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -42,12 +42,7 @@
#define DBG(...)
-#ifdef CONFIG_IOMMU_VMERGE
-static int novmerge = 0;
-#else
-static int novmerge = 1;
-#endif
-
+static int novmerge;
static int protect4gb = 1;
static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int);
--
1.6.5
^ permalink raw reply related
* Re: [PATCH] powerpc: remove IOMMU_VMERGE config option
From: Michael Ellerman @ 2010-03-03 0:13 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: linuxppc-dev, davem, linux-kernel, arnd, benh
In-Reply-To: <20100303085404R.fujita.tomonori@lab.ntt.co.jp>
[-- Attachment #1: Type: text/plain, Size: 1280 bytes --]
On Wed, 2010-03-03 at 08:54 +0900, FUJITA Tomonori wrote:
> Seems that IOMMU_VMERGE option description gives the false
> information:
>
> http://marc.info/?l=linux-sparc&m=126753808727669&w=2
> http://marc.info/?l=linux-sparc&m=126753880528825&w=2
>
> IOMMU_VMERGE is unnecessary nowadays so how about removing it?
Except you didn't remove it, you just made it uneditable? Why not get
rid of it entirely.
cheers
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index 155d571..2dfa83b 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -314,17 +314,8 @@ config 8XX_MINIMAL_FPEMU
> It is recommended that you build a soft-float userspace instead.
>
> config IOMMU_VMERGE
> - bool "Enable IOMMU virtual merging"
> + def_bool y
> depends on PPC64
> - default y
> - help
> - Cause IO segments sent to a device for DMA to be merged virtually
> - by the IOMMU when they happen to have been allocated contiguously.
> - This doesn't add pressure to the IOMMU allocator. However, some
> - drivers don't support getting large merged segments coming back
> - from *_map_sg().
> -
> - Most drivers don't have this problem; it is safe to say Y here.
>
> config IOMMU_HELPER
> def_bool PPC64
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* linux-next: possible recursive locking detected
From: Stephen Rothwell @ 2010-03-03 0:10 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: ppc-dev
[-- Attachment #1: Type: text/plain, Size: 1894 bytes --]
Hi all,
next-20100302 (and next-20100301) produce this log during boot on a
Power5 lpar.
calling .hvc_vio_init+0x0/0x34 @ 1
=============================================
[ INFO: possible recursive locking detected ]
2.6.33-autokern1 #1
---------------------------------------------
swapper/1 is trying to acquire lock:
(&dev->mutex){+.+...}, at: [<c000000000345490>] .__driver_attach+0x80/0xe0
but task is already holding lock:
(&dev->mutex){+.+...}, at: [<c000000000345480>] .__driver_attach+0x70/0xe0
other info that might help us debug this:
1 lock held by swapper/1:
#0: (&dev->mutex){+.+...}, at: [<c000000000345480>] .__driver_attach+0x70/0xe0
stack backtrace:
Call Trace:
[c0000000400cf590] [c000000000010780] .show_stack+0x70/0x184 (unreliable)
[c0000000400cf640] [c000000000096c24] .validate_chain+0x6e4/0xf2c
[c0000000400cf750] [c000000000097d8c] .__lock_acquire+0x920/0x9e4
[c0000000400cf850] [c000000000097ef8] .lock_acquire+0xa8/0xec
[c0000000400cf920] [c000000000567fc4] .mutex_lock_nested+0x5c/0x468
[c0000000400cfa00] [c000000000345490] .__driver_attach+0x80/0xe0
[c0000000400cfa90] [c000000000343f0c] .bus_for_each_dev+0x84/0xdc
[c0000000400cfb40] [c000000000344e6c] .driver_attach+0x28/0x40
[c0000000400cfbc0] [c0000000003448ec] .bus_add_driver+0xd8/0x2b0
[c0000000400cfc70] [c000000000345830] .driver_register+0xd4/0x1a8
[c0000000400cfd20] [c00000000002225c] .vio_register_driver+0x40/0x5c
[c0000000400cfdb0] [c0000000007ff4d4] .hvc_vio_init+0x1c/0x34
[c0000000400cfe30] [c0000000000094c0] .do_one_initcall+0x9c/0x1cc
[c0000000400cfee0] [c0000000007d6d2c] .kernel_init+0x218/0x294
[c0000000400cff90] [c000000000026c00] .kernel_thread+0x54/0x70
initcall .hvc_vio_init+0x0/0x34 returned 0 after 1904 usecs
Any ideas?
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* [PATCH] powerpc: remove IOMMU_VMERGE config option
From: FUJITA Tomonori @ 2010-03-02 23:54 UTC (permalink / raw)
To: linuxppc-dev; +Cc: linux-kernel, benh, arnd, davem
Seems that IOMMU_VMERGE option description gives the false
information:
http://marc.info/?l=linux-sparc&m=126753808727669&w=2
http://marc.info/?l=linux-sparc&m=126753880528825&w=2
IOMMU_VMERGE is unnecessary nowadays so how about removing it?
=
From: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Subject: [PATCH] powerpc: remove IOMMU_VMERGE config option
The description says:
Cause IO segments sent to a device for DMA to be merged virtually
by the IOMMU when they happen to have been allocated contiguously.
This doesn't add pressure to the IOMMU allocator. However, some
drivers don't support getting large merged segments coming back
from *_map_sg().
Most drivers don't have this problem; it is safe to say Y here.
It's out of date. Long ago, drivers didn't have a way to tell IOMMUs
about their segment length limit (that is, the maximum segment length
that they can handle). So IOMMUs merged as many segments as possible
and gave too large segments to drivers.
dma_get_max_seg_size() was introduced to solve the above
problem. Device drives can use the API to tell IOMMU about the maximum
segment length that they can handle. The powerpc IOMMU supports
dma_get_max_seg_size() properly. In addition, the default limit (64K)
should be safe for everyone.
So this config option seems to be unnecessary.
Note that this config option just enables users to disable the virtual
merging by default (powerpc enables it by default). Users can still
disable the virtual merging by the boot parameter.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
---
arch/powerpc/Kconfig | 11 +----------
1 files changed, 1 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 155d571..2dfa83b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -314,17 +314,8 @@ config 8XX_MINIMAL_FPEMU
It is recommended that you build a soft-float userspace instead.
config IOMMU_VMERGE
- bool "Enable IOMMU virtual merging"
+ def_bool y
depends on PPC64
- default y
- help
- Cause IO segments sent to a device for DMA to be merged virtually
- by the IOMMU when they happen to have been allocated contiguously.
- This doesn't add pressure to the IOMMU allocator. However, some
- drivers don't support getting large merged segments coming back
- from *_map_sg().
-
- Most drivers don't have this problem; it is safe to say Y here.
config IOMMU_HELPER
def_bool PPC64
--
1.6.5
^ permalink raw reply related
* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
From: vb @ 2010-03-02 21:21 UTC (permalink / raw)
To: Paul Gortmaker; +Cc: linuxppc-dev, linux-serial
In-Reply-To: <4B8D3C59.4080504@windriver.com>
On Tue, Mar 2, 2010 at 8:27 AM, Paul Gortmaker
<paul.gortmaker@windriver.com> wrote:
> On 10-03-01 06:03 PM, vb@vsbe.com wrote:
>> sounds very much like this issue:
>>
>> http://linux.derkeiler.com/Mailing-Lists/Kernel/2010-02/msg09470.html
>
> Thanks for the link.
>
>>
>> (interrupt storm on the second port which is hit with breaks).
>>
>> It's not the uart driver problem per se, the below fixes it:
>
> Actually, it is a uart *hardware* problem -- see in this same
> thread where Scott Wood described an errata, and when I
> implemented his interpretation of what the fix should look
> like, things just worked. =A0You might want to try out that patch
> and see if it helps you, since from the link above, I see you
> are also on a powerpc board.
>
> Paul.
>
yeah, I was not aware of the hardware bug you are describing, it's
just the scenario I encountered is very similar: the serial interface
is flooded with breaks, after a while the prot generates an IRQ storm.
But the storm happens only after the port gets shut down (by getty in
my case).
In my case this behavior is due to a SW bug, you might be hitting the
HW problem, I have not seen it yet,
cheers,
/vb
>>
>> *** linux/drivers/serial/serial_core.c#1 =A0 =A0 =A0 =A0Wed Feb 24 17:46=
:22 2010
>> --- =A0linux/drivers/serial/serial_core.c#2 =A0 =A0 =A0 =A0Mon Mar =A01 =
15:00:29 2010
>> ***************
>> *** 622,632 ****
>> =A0 =A0 =A0 =A0 =A0struct uart_port *port =3D state->port;
>>
>> =A0 =A0 =A0 =A0 =A0if (I_IXOFF(tty)) {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (port->x_char)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0port->x_char =3D 0;
>> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 else
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uart_send_xchar(tty, =
START_CHAR(tty));
>> =A0 =A0 =A0 =A0 =A0}
>>
>> =A0 =A0 =A0 =A0 =A0if (tty->termios->c_cflag& =A0CRTSCTS)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uart_set_mctrl(port, TIOCM_RTS);
>> --- 622,632 ----
>> =A0 =A0 =A0 =A0 =A0struct uart_port *port =3D state->port;
>>
>> =A0 =A0 =A0 =A0 =A0if (I_IXOFF(tty)) {
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0if (port->x_char)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0port->x_char =3D 0;
>> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 else if (!(tty->flags& =A0(1<< =A0TTY_IO_E=
RROR)))
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uart_send_xchar(tty, =
START_CHAR(tty));
>> =A0 =A0 =A0 =A0 =A0}
>>
>> =A0 =A0 =A0 =A0 =A0if (tty->termios->c_cflag& =A0CRTSCTS)
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0uart_set_mctrl(port, TIOCM_RTS);
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^=
^^^^^^^^^^^^^^^^^^^^^^
>>
>> I did not get to trying to submit it, but it sure gets rid o the storm.
>>
>> cheers,
>> /vb
>>
>> On Fri, Feb 26, 2010 at 11:25 AM, Paul Gortmaker
>> <paul.gortmaker@windriver.com> =A0wrote:
>>> Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
>>> chips seems to cause a short lived IRQ storm (/proc/interrupts
>>> typically shows somewhere between 300 and 1500 events). =A0Unfortunatel=
y
>>> this renders SysRQ over the serial console completely inoperable.
>>> Testing with obvious things like ACKing the event doesn't seem to
>>> change anything vs. a completely dumb approach of just ignoring
>>> it and waiting for it to stop, so that is what is implemented here.
>>>
>>> Signed-off-by: Paul Gortmaker<paul.gortmaker@windriver.com>
>>> ---
>>>
>>> This is a refresh of a patch I'd done earlier -- I've tried to make
>>> the bug support as generic as possible to minimize having board
>>> specific ifdef crap in 8250.c -- any suggestions on how to further
>>> improve it are welcome.
>>>
>>> =A0 drivers/serial/8250.c =A0 =A0 =A0| =A0 =A06 ++++++
>>> =A0 drivers/serial/8250.h =A0 =A0 =A0| =A0 20 ++++++++++++++++++++
>>> =A0 drivers/serial/Kconfig =A0 =A0 | =A0 14 ++++++++++++++
>>> =A0 include/linux/serial_reg.h | =A0 =A02 ++
>>> =A0 4 files changed, 42 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
>>> index e9b15c3..850b0e9 100644
>>> --- a/drivers/serial/8250.c
>>> +++ b/drivers/serial/8250.c
>>> @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct uart_8=
250_port *up)
>>>
>>> =A0 =A0 =A0 =A0 status =3D serial_inp(up, UART_LSR);
>>>
>>> + =A0 =A0 =A0 if ((up->bugs& =A0UART_BUG_PPC)&& =A0(status =3D=3D UART_=
LSR_RFE_ERROR_BITS)) {
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 spin_unlock_irqrestore(&up->port.lock, fl=
ags);
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return;
>>> + =A0 =A0 =A0 }
>>> +
>>> =A0 =A0 =A0 =A0 DEBUG_INTR("status =3D %x...", status);
>>>
>>> =A0 =A0 =A0 =A0 if (status& =A0(UART_LSR_DR | UART_LSR_BI))
>>> @@ -1948,6 +1953,7 @@ static int serial8250_startup(struct uart_port *p=
ort)
>>>
>>> =A0 =A0 =A0 =A0 up->capabilities =3D uart_config[up->port.type].flags;
>>> =A0 =A0 =A0 =A0 up->mcr =3D 0;
>>> + =A0 =A0 =A0 up->bugs |=3D UART_KNOWN_BUGS;
>>>
>>> =A0 =A0 =A0 =A0 if (up->port.iotype !=3D up->cur_iotype)
>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 set_io_from_upio(port);
>>> diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
>>> index 6e19ea3..2074ce1 100644
>>> --- a/drivers/serial/8250.h
>>> +++ b/drivers/serial/8250.h
>>> @@ -49,6 +49,7 @@ struct serial8250_config {
>>> =A0 #define UART_BUG_TXEN =A0(1<< =A01) =A0 =A0 =A0 =A0/* UART has bugg=
y TX IIR status */
>>> =A0 #define UART_BUG_NOMSR (1<< =A02) =A0 =A0 =A0 =A0/* UART has buggy =
MSR status bits (Au1x00) */
>>> =A0 #define UART_BUG_THRE =A0(1<< =A03) =A0 =A0 =A0 =A0/* UART has bugg=
y THRE reassertion */
>>> +#define UART_BUG_PPC =A0 (1<< =A04) =A0 =A0 =A0 =A0/* UART has buggy P=
PC break IRQ storm */
>>>
>>> =A0 #define PROBE_RSA =A0 =A0 =A0(1<< =A00)
>>> =A0 #define PROBE_ANY =A0 =A0 =A0(~0)
>>> @@ -78,3 +79,22 @@ struct serial8250_config {
>>> =A0 #else
>>> =A0 #define ALPHA_KLUDGE_MCR 0
>>> =A0 #endif
>>> +
>>> +/*
>>> + * The following UART bugs are currently dynamically detected and not
>>> + * required to be contingent on any particular compile time options.
>>> + */
>>> +#define HAS_BUG_QUOT =A0 0 =A0 =A0 =A0 /* assign UART_BUG_QUOT to enab=
le */
>>> +#define HAS_BUG_TXEN =A0 0 =A0 =A0 =A0 /* assign UART_BUG_TXEN to enab=
le */
>>> +#define HAS_BUG_NOMSR =A00 =A0 =A0 =A0 /* assign UART_BUG_NOMSR to ena=
ble */
>>> +#define HAS_BUG_THRE =A0 0 =A0 =A0 =A0 /* assign UART_BUG_THRE to enab=
le */
>>> +
>>> +#ifdef CONFIG_SERIAL_8250_PPC_BUG
>>> +#define HAS_BUG_PPC =A0 =A0UART_BUG_PPC
>>> +#else
>>> +#define HAS_BUG_PPC =A0 =A00
>>> +#endif
>>> +
>>> +#define UART_KNOWN_BUGS (HAS_BUG_QUOT | HAS_BUG_TXEN | HAS_BUG_NOMSR |=
\
>>> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 HAS_BUG_THRE | HAS_BUG_PP=
C)
>>> +
>>> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
>>> index 9ff47db..e01a411 100644
>>> --- a/drivers/serial/Kconfig
>>> +++ b/drivers/serial/Kconfig
>>> @@ -70,6 +70,20 @@ config SERIAL_8250_CONSOLE
>>>
>>> =A0 =A0 =A0 =A0 =A0 If unsure, say N.
>>>
>>> +config SERIAL_8250_PPC_BUG
>>> + =A0 =A0 =A0 bool "Fix 8250/16550 to handle IRQ storm after receipt of=
a break"
>>> + =A0 =A0 =A0 depends on SERIAL_8250&& =A0PPC32
>>> + =A0 =A0 =A0 ---help---
>>> + =A0 =A0 =A0 =A0 If you say Y here, addional checks will be added in t=
he handling of
>>> + =A0 =A0 =A0 =A0 interrupts on the serial ports which will prevent ill=
effects of
>>> + =A0 =A0 =A0 =A0 an interrupt storm triggered by a break on the serial=
line. Without
>>> + =A0 =A0 =A0 =A0 this enabled, a Sysrq via the serial console can be u=
nusable on
>>> + =A0 =A0 =A0 =A0 some systems.
>>> +
>>> + =A0 =A0 =A0 =A0 This is commonly observed on PPC32 MPC83xx/85xx/86xx =
based boards.
>>> +
>>> + =A0 =A0 =A0 =A0 If unsure, say N.
>>> +
>>> =A0 config FIX_EARLYCON_MEM
>>> =A0 =A0 =A0 =A0 bool
>>> =A0 =A0 =A0 =A0 depends on X86
>>> diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
>>> index cf9327c..010174f 100644
>>> --- a/include/linux/serial_reg.h
>>> +++ b/include/linux/serial_reg.h
>>> @@ -111,6 +111,7 @@
>>> =A0 #define UART_MCR_DTR =A0 =A0 =A0 =A0 =A0 0x01 /* DTR complement */
>>>
>>> =A0 #define UART_LSR =A0 =A0 =A0 5 =A0 =A0 =A0 /* In: =A0Line Status Re=
gister */
>>> +#define UART_LSR_RFE =A0 =A0 =A0 =A0 =A0 0x80 /* Rx FIFO Error (BE, FE=
, or PE) */
>>> =A0 #define UART_LSR_TEMT =A0 =A0 =A0 =A0 =A00x40 /* Transmitter empty =
*/
>>> =A0 #define UART_LSR_THRE =A0 =A0 =A0 =A0 =A00x20 /* Transmit-hold-regi=
ster empty */
>>> =A0 #define UART_LSR_BI =A0 =A0 =A0 =A0 =A0 =A00x10 /* Break interrupt =
indicator */
>>> @@ -119,6 +120,7 @@
>>> =A0 #define UART_LSR_OE =A0 =A0 =A0 =A0 =A0 =A00x02 /* Overrun error in=
dicator */
>>> =A0 #define UART_LSR_DR =A0 =A0 =A0 =A0 =A0 =A00x01 /* Receiver data re=
ady */
>>> =A0 #define UART_LSR_BRK_ERROR_BITS =A0 =A0 =A0 =A00x1E /* BI, FE, PE, =
OE bits */
>>> +#define UART_LSR_RFE_ERROR_BITS =A0 =A0 =A0 =A00xF1 /* RFE, TEMT, THRE=
, BI, DR bits */
>>>
>>> =A0 #define UART_MSR =A0 =A0 =A0 6 =A0 =A0 =A0 /* In: =A0Modem Status R=
egister */
>>> =A0 #define UART_MSR_DCD =A0 =A0 =A0 =A0 =A0 0x80 /* Data Carrier Detec=
t */
>>> --
>>> 1.6.5.2
>>>
>>> _______________________________________________
>>> Linuxppc-dev mailing list
>>> Linuxppc-dev@lists.ozlabs.org
>>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>>
>
>
^ permalink raw reply
* OProfile on the MPC8313 / e300 core
From: Jeff Hansen @ 2010-03-02 20:13 UTC (permalink / raw)
To: linuxppc-dev
Hello,
I am running 2.6.31.4 on an MPC8313 (e300/PPC6xx core) platform running
OpenWRT. I am getting non-recoverable exceptions in random functions
shortly after I start profiling using OProfile (within a few minutes).
The exception usually happens in cpu_idle, but not always. The oops
usually shows that exception 0xf00 (performance counter) precedes the
non-recoverable condition. Even if it doesn't show the 0xf00 exception
in the stack trace, the following entry_32.S's _switch function always
detects the non-recoverable condition (when this happens):
andi. r10,r9,MSR_RI /* check for recoverable interrupt */
The MSR's RI bit is not set, and so the kernel assumes the worst. I've
tried disabling the above check as well, but other strange oopses still
occur, so something is definitely wrong with the CPU. If I leave things
alone I *always* get a non-recoverable exception within a few minutes.
This only occurs under heavy interrupt load (I do a short packet ping
flood from three hosts on the Ethernet). I don't think trying 2.6.33
will help because I haven't seen any bug-fixes related to
oprofile/ppc/e300 since 2.6.31. But of course if somebody thinks 2.6.33
will help, I can try it out. I've also tried powersave=off and
idle=poll on the kernel command line, with the same results.
Does anyone have any ideas as to why this is happening? Is it a bug in
the PowerPC oprofile implementation? Or a bug in the performance
counter core in the MPC8313? It's making it very hard to profile things
under heavy load since it oopses so soon.
Here is one of the oopses with a GPL-only kernel with heavy load on the
gianfar driver:
Non-recoverable exception at PC=c0186704 MSR=1000
Oops: nonrecoverable exception, sig: 9 [#1]
MPC831x RDB
Modules linked in: oprofile nf_nat_tftp nf_conntrack_tftp nf_nat_irc
nf_conntrack_irc nf_nat_ftp nf_conntrack_ftp ipt_MASQUERADE iptable_nat
nf_nat xt_NOTRACK iptable_raw xt_state nf_conntrack_ipv4 nf_defrag_ipv4
nf_conntrack ipt_REJECT xt_TCPMSS ipt_LOG xt_multiport xt_mac xt_limit
iptable_mangle iptable_filter ip_tables xt_tcpudp x_tables nfs ppp_async
ppp_generic slhc auth_rpcgss lockd sunrpc crc_ccitt netconsole ipv6
NIP: c0186704 LR: c01866f4 CTR: 00000000
REGS: c036dc80 TRAP: 0f00 Not tainted (2.6.31.4)
MSR: 00001000 <ME> CR: 84004022 XER: 00000000
TASK = c03433e8[0] 'swapper' THREAD: c036c000
GPR00: 00000089 c036dd30 c03433e8 c7844190 00000000 00000000 c72d2f9c
c03716dc
GPR08: 00000000 c7844180 c720e880 c720e840 44004022 ffff8000 000000ff
00000000
GPR16: c02ef210 0000000a c02ef1fc c02ef1e8 00000001 00000000 c783eb64
c1661800
GPR24: c036c000 00000000 0000003f c72d2f00 c1661c48 c783e800 c783eae0
c783eae0
NIP [c0186704] gfar_clean_rx_ring+0xe0/0x4ec
LR [c01866f4] gfar_clean_rx_ring+0xd0/0x4ec
Call Trace:
[c036dd30] [c01866f4] gfar_clean_rx_ring+0xd0/0x4ec (unreliable)
[c036dd80] [c0186dc8] gfar_poll+0x2b8/0x3b4
[c036ddd0] [c01dbf64] net_rx_action+0x11c/0x2d8
[c036de30] [c00332f0] __do_softirq+0x130/0x23c
[c036de90] [c000661c] do_softirq+0x40/0x58
[c036dea0] [c0032d74] irq_exit+0x38/0x48
[c036deb0] [c00066c0] do_IRQ+0x8c/0xac
[c036ded0] [c00120f0] ret_from_except+0x0/0x14
--- Exception: 501 at cpu_idle+0xc8/0xe0
LR = cpu_idle+0xdc/0xe0
[c036dfb0] [c0003fc8] rest_init+0x5c/0x74
[c036dfc0] [c03187f8] start_kernel+0x2b0/0x2d0
[c036dff0] [00003440] 0x3440
Instruction dump:
XXXXXXXX XXXXXXXX XXXXXXXX 3aa00000 XXXXXXXX XXXXXXXX XXXXXXXX 4bfffe95
XXXXXXXX XXXXXXXX XXXXXXXX 34690010 XXXXXXXX XXXXXXXX XXXXXXXX 7fcb002e
And another oops with the proprietary modules I am working with:
Non-recoverable exception at PC=c0009724 MSR=1000
Oops: nonrecoverable exception, sig: 9 [#1]
MPC831x RDB
Modules linked in: oprofile ... nf_nat_tftp nf_conntrack_tftp nf_nat_irc
nf_conntrack_irc nf_nat_ftp nf_conntrack_ftp ipt_MASQUERADE iptable_nat
nf_nat xt_NOTRACK iptable_raw xt_state nf_conntrack_ipv4 nf_defrag_ipv4
nf_conntrack ipt_REJECT xt_TCPMSS ipt_LOG xt_multiport xt_mac xt_limit
iptable_mangle iptable_filter ip_tables xt_tcpudp x_tables nfs ppp_async
ppp_generic slhc auth_rpcgss lockd sunrpc floader crc_ccitt netconsole ipv6
NIP: c0009724 LR: c0009724 CTR: c000cd20
REGS: c036dee0 TRAP: 0f00 Tainted: P ... (2.6.31.4)
MSR: 00001000 <ME> CR: 24002028 XER: 20000000
TASK = c03433e8[0] 'swapper' THREAD: c036c000
GPR00: 00000000 c036df90 c03433e8 00800000 8090c000 00e00000 8a23c64a
00049032
GPR08: 00000001 c036c000 24002022 c1796000 ae8b6fd7 ffff8000 07ffb000
09fbc000
GPR16: 00000000 00000000 00000000 00000000 00000000 00000002 00000002
00000001
GPR24: 00000000 003ab000 40100000 00000020 c037465c c037465c 00000008
c036c03c
NIP [c0009724] cpu_idle+0xa0/0xe0
LR [c0009724] cpu_idle+0xa0/0xe0
Call Trace:
[c036df90] [c0009760] cpu_idle+0xdc/0xe0 (unreliable)
[c036dfb0] [c0003fc8] rest_init+0x5c/0x74
[c036dfc0] [c03187f8] start_kernel+0x2b0/0x2d0
[c036dff0] [00003440] 0x3440
Instruction dump:
XXXXXXXX XXXXXXXX XXXXXXXX 7c0000a6 XXXXXXXX XXXXXXXX XXXXXXXX 70090004
XXXXXXXX XXXXXXXX XXXXXXXX 4e800421 XXXXXXXX XXXXXXXX XXXXXXXX 7c00f828
Kernel panic - not syncing: Fatal exception
Call Trace:
[c036de30] [c0008764] show_stack+0x78/0x1a4 (unreliable)
[c036de60] [c0258adc] panic+0x98/0x174
[c036deb0] [c000f748] die+0x15c/0x168
[c036ded0] [c0012330] nonrecoverable+0xa4/0xa8
--- Exception: f00 at cpu_idle+0xa0/0xe0
LR = cpu_idle+0xa0/0xe0
[c036df90] [c0009760] cpu_idle+0xdc/0xe0 (unreliable)
[c036dfb0] [c0003fc8] rest_init+0x5c/0x74
[c036dfc0] [c03187f8] start_kernel+0x2b0/0x2d0
[c036dff0] [00003440] 0x3440
Rebooting in 3 seconds..
-Jeff
^ permalink raw reply
* Re: [Patch] mpc5200b: improve baud rate calculation (reach high baud rates, better accuracy)
From: Grant Likely @ 2010-03-02 20:22 UTC (permalink / raw)
To: Albrecht Dreß; +Cc: Linux PPC Development
In-Reply-To: <1267467114.2218.0@antares>
Hi Albrecht,
Thanks for this work, comment below...
On Mon, Mar 1, 2010 at 11:11 AM, Albrecht Dre=DF <albrecht.dress@arcor.de> =
wrote:
> On the MPC5200B, select the baud rate prescaler as /4 by default to make =
very
> high baud rates (e.g. 3 MBaud) accessible and to achieve a higher precisi=
on
> for high baud rates in general. For baud rates below ~500 Baud, the code =
will
> automatically fall back to the /32 prescaler. =A0The original MPC5200 doe=
s only
> have a /32 prescaler which is detected only once and stored in a global. =
=A0A
> new chip-dependent method is used to set the divisor.
>
> Tested on a custom 5200B based board, with up to 3 MBaud.
>
> Signed-off-by: Albrecht Dre=DF <albrecht.dress@arcor.de>
>
> ---
>
> --- linux-2.6.33/drivers/serial/mpc52xx_uart.c.orig =A0 =A0 2010-02-24 19=
:52:17.000000000 +0100
> +++ linux-2.6.33/drivers/serial/mpc52xx_uart.c =A02010-02-26 21:12:51.000=
000000 +0100
> =A0/* Search for bus-frequency property in this node or a parent */
> =A0static unsigned long mpc52xx_getuartclk(void *p)
> =A0{
> =A0 =A0 =A0 =A0/*
> - =A0 =A0 =A0 =A0* 5200 UARTs have a / 32 prescaler
> - =A0 =A0 =A0 =A0* but the generic serial code assumes 16
> - =A0 =A0 =A0 =A0* so return ipb freq / 2
> + =A0 =A0 =A0 =A0* The 5200 has only /32 prescalers.
> + =A0 =A0 =A0 =A0* 5200B UARTs have a /4 or a /32 prescaler. =A0For highe=
r accuracy, we
> + =A0 =A0 =A0 =A0* do all calculations using the /4 prescaler for this ch=
ip.
> + =A0 =A0 =A0 =A0* The generic serial code assumes /16 so return ipb freq=
/ 2 (5200)
> + =A0 =A0 =A0 =A0* or ipb freq * 4 (5200B).
> =A0 =A0 =A0 =A0 */
> - =A0 =A0 =A0 return mpc5xxx_get_bus_frequency(p) / 2;
> + =A0 =A0 =A0 if (is_mpc5200b =3D=3D 1)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return mpc5xxx_get_bus_frequency(p) * 4;
> + =A0 =A0 =A0 else
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return mpc5xxx_get_bus_frequency(p) / 2;
> =A0}
Remove this function entirely and the associated .getuartclk() hook
from the psc_ops structure. Callers can just call
mpc5xxx_get_bus_frequency() directly. mpc5121 already just passes
back the return value unmodified, and current mpc52xx code uses a /2,
but that would be eliminated if the new set_divisor hook took that
into account. That way all the chip-specific clock setup calculation
is consolidated into a single function. I like patches that make
things simpler.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [Patch] mpc5200b: improve baud rate calculation (reach high baud rates, better accuracy)
From: Grant Likely @ 2010-03-02 20:12 UTC (permalink / raw)
To: Albrecht Dreß; +Cc: linuxppc-dev, devicetree-discuss
In-Reply-To: <22132814.1267520208614.JavaMail.ngmail@webmail14.arcor-online.net>
On Tue, Mar 2, 2010 at 1:56 AM, Albrecht Dre=DF <albrecht.dress@arcor.de> w=
rote:
> Hi Wolfram:
>
> [snip]
>> > Yes, but I do all /calculations/ with the /4 prescaler for higher
>> accuracy.
>> > If the divisor exceeds the available 16 bits of the counter reg, I rou=
nd
>> > (divisor / 8) to use the /32 prescaler. =A0Think of a 19-bit counter v=
alue,
>> > where I can choose to use either the lower or the higher 16 bits for t=
he
>> > counter reg.
>>
>> Okay, now I got it. (Maybe this is an indication for another comment abo=
ve
>> the
>> set divisor function?)
>
> O.k., I will add that comment...
>
Yes, please document your calculation approach thoroughly.
>> > > This should be handled using a new compatible-entry
>> > > "fsl,mpc5200b-psc-uart".
>> >
>>
>> > I agree that this would be a lot cleaner, but it's also a lot more
>> intrusive.
>> > CC'ing the device tree discussion list here... comments, please!!
>>
>> Why intrusive? Maybe I miss something?
>
> Not for the source file, but for all the dts files, if they want to benef=
it from the detection of the '5200B. =A0Basically, *all* files have to be c=
hecked and touched if necessary. =A0Again, I agree that this would be the c=
lean approach, but I wanted to avoid that effort. =A0Grant???
Already there on mainlined .dts files, and it won't break boards that
don't have it.
> [snip]
>> Leave those two function pointers empty and fill them during probe (prob=
e
>> has
>> access to the compatible-property it was matched against, see its
>> arguments).
>> So it should be a matter of:
>>
>> if (matched_property =3D=3D 5200b)
>> =A0 =A0 =A0 ops->func =3D this_one;
>> else
>> =A0 =A0 =A0 ops->func =3D that_one;
>
> Umm, yes, that's true of course. =A0Will pick it up.
When it comes to code clarity, I'd prefer you had separate mpc5200 and
mpc5200b ops structures. I'm not worried about an extra 64 bytes
added to the kernel size for this (minus the # of bytes needed to test
and set the new op).
g.
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [Patch] mpc5200b: improve baud rate calculation (reach high baud rates, better accuracy)
From: Grant Likely @ 2010-03-02 20:06 UTC (permalink / raw)
To: Albrecht Dreß; +Cc: linuxppc-dev, devicetree-discuss
In-Reply-To: <14429243.1267517383754.JavaMail.ngmail@webmail14.arcor-online.net>
On Tue, Mar 2, 2010 at 1:09 AM, Albrecht Dre=DF <albrecht.dress@arcor.de> w=
rote:
>> > + =A0 /* Check only once if we are running on a mpc5200b or not */
>> > + =A0 if (is_mpc5200b =3D=3D -1) {
>> > + =A0 =A0 =A0 =A0 =A0 struct device_node *np;
>> > +
>> > + =A0 =A0 =A0 =A0 =A0 np =3D of_find_compatible_node(NULL, NULL, "fsl,=
mpc5200b-immr");
>>
>> This should be handled using a new compatible-entry
>> "fsl,mpc5200b-psc-uart".
>
> I agree that this would be a lot cleaner, but it's also a lot more intrus=
ive. =A0CC'ing the device tree discussion list here... comments, please!!
fsl,mpc5200b-psc-uart is already in the compatible list for all
MPC500b boards currently in the kernel tree.
>> > + =A0 =A0 =A0 =A0 =A0 if (np) {
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 is_mpc5200b =3D 1;
>> > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_dbg(&op->dev, "mpc5200b: usi=
ng /4 prescaler\n");
>>
>> Does this message respect the fallback case?
>
> See comment above...
>
>> You could also have a set_divisor-function for 5200 and 5200B and set it
>> here
>> in the function struct (one reason less for the static ;))
>
> Hmmm, but then I would need a 'static struct psc_ops mpc5200b_psc_ops', w=
here only two functions differ from the generic 52xx struct as it is implem=
ented now. =A0Using the static int needs less space. =A0However, in combina=
tion with the new compatible entry, it would of course make sense.
>
> Again, any insight from the device tree gurus would be appreciated!
Wolfram is correct, you should set the correct divisor function in the
ops structure. Much clearer code that way.
g.
^ permalink raw reply
* Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
From: Alan Stern @ 2010-03-02 17:43 UTC (permalink / raw)
To: Albert Herranz; +Cc: linux-usb, linuxppc-dev, linux-arm-kernel
In-Reply-To: <4B8D44A7.7030302@yahoo.es>
On Tue, 2 Mar 2010, Albert Herranz wrote:
> > Currently "this URB doesn't require PIO" is always true, but in the
> > future it won't be.
> >
>
> Can this be currently tested?
Not yet, but soon. You can follow the gory details in this email
thread:
http://marc.info/?l=linux-usb&m=126477569707174&w=2
See especially this email:
http://marc.info/?l=linux-usb&m=126630714002200&w=2
> Should I make provisions for this check now too?
Don't worry about it. If you structure the code as I described, it
will be easy to insert the check later on.
Alan Stern
^ permalink raw reply
* Re: [RFC PATCH v2 8/9] USB: add HCD_NO_COHERENT_MEM host controller driver flag
From: Albert Herranz @ 2010-03-02 17:02 UTC (permalink / raw)
To: Alan Stern; +Cc: linux-usb, linuxppc-dev, linux-arm-kernel
In-Reply-To: <Pine.LNX.4.44L0.1003021034190.1730-100000@iolanthe.rowland.org>
Alan Stern wrote:
> On Mon, 1 Mar 2010, Albert Herranz wrote:
>
>>> If transfer_buffer_length is 0 then do nothing.
>>> Otherwise if num_sgs > 0 then do nothing.
>>> Otherwise if URB_NO_TRANSFER_DMA_MAP and transfer_dma
>>> are both set (this avoids your HCD_NO_COHERENT_MEM
>>> case) then do nothing.
>>>
>> I see. This case would include the PIO case too (for which dma_handle
>> is set to all 1s).
>
> The test above should be transfer_dma != ~0, not transfer_dma != 0,
> since ~0 means the DMA address isn't set. In fact I forgot to
> include the PIO case; it should be handled by changing the remaining
> tests as follows:
>
> Otherwise if hcd->self.uses_dma is set then
> If this URB doesn't require PIO then call dma_map_single
> Otherwise if HCD_LOCAL_MEM is set then call hcd_alloc_coherent
> Otherwise do nothing (PIO case).
>
> Currently "this URB doesn't require PIO" is always true, but in the
> future it won't be.
>
Can this be currently tested?
Should I make provisions for this check now too?
>> So this assumes that transfer_dma should be set initially to 0 when
>> allocating USB buffers for HCD_NO_COHERENT_MEM.
>
> No, it should be set to ~0, the same as when buffers are allocated for
> a PIO-based controller.
>
This logic now resembles more the one in my v2 proposal although with different formal checks.
I think I'll code and post another iteration of the 8/9 patch with your proposed checks and then we can continue further discussion on it.
I'll try to add explanatory comments for each check.
> Alan Stern
>
Thanks a lot for your input,
Albert
^ permalink raw reply
* Re: [PATCH] 8250: add workaround for MPC8[356]xx UART break IRQ storm
From: Paul Gortmaker @ 2010-03-02 16:27 UTC (permalink / raw)
To: vb; +Cc: linuxppc-dev, linux-serial
In-Reply-To: <f608b67d1003011503h57b88742md889ba8d6da652bc@mail.gmail.com>
On 10-03-01 06:03 PM, vb@vsbe.com wrote:
> sounds very much like this issue:
>
> http://linux.derkeiler.com/Mailing-Lists/Kernel/2010-02/msg09470.html
Thanks for the link.
>
> (interrupt storm on the second port which is hit with breaks).
>
> It's not the uart driver problem per se, the below fixes it:
Actually, it is a uart *hardware* problem -- see in this same
thread where Scott Wood described an errata, and when I
implemented his interpretation of what the fix should look
like, things just worked. You might want to try out that patch
and see if it helps you, since from the link above, I see you
are also on a powerpc board.
Paul.
>
> *** linux/drivers/serial/serial_core.c#1 Wed Feb 24 17:46:22 2010
> --- linux/drivers/serial/serial_core.c#2 Mon Mar 1 15:00:29 2010
> ***************
> *** 622,632 ****
> struct uart_port *port = state->port;
>
> if (I_IXOFF(tty)) {
> if (port->x_char)
> port->x_char = 0;
> ! else
> uart_send_xchar(tty, START_CHAR(tty));
> }
>
> if (tty->termios->c_cflag& CRTSCTS)
> uart_set_mctrl(port, TIOCM_RTS);
> --- 622,632 ----
> struct uart_port *port = state->port;
>
> if (I_IXOFF(tty)) {
> if (port->x_char)
> port->x_char = 0;
> ! else if (!(tty->flags& (1<< TTY_IO_ERROR)))
> uart_send_xchar(tty, START_CHAR(tty));
> }
>
> if (tty->termios->c_cflag& CRTSCTS)
> uart_set_mctrl(port, TIOCM_RTS);
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> I did not get to trying to submit it, but it sure gets rid o the storm.
>
> cheers,
> /vb
>
> On Fri, Feb 26, 2010 at 11:25 AM, Paul Gortmaker
> <paul.gortmaker@windriver.com> wrote:
>> Sending a break on the SOC UARTs found in some MPC83xx/85xx/86xx
>> chips seems to cause a short lived IRQ storm (/proc/interrupts
>> typically shows somewhere between 300 and 1500 events). Unfortunately
>> this renders SysRQ over the serial console completely inoperable.
>> Testing with obvious things like ACKing the event doesn't seem to
>> change anything vs. a completely dumb approach of just ignoring
>> it and waiting for it to stop, so that is what is implemented here.
>>
>> Signed-off-by: Paul Gortmaker<paul.gortmaker@windriver.com>
>> ---
>>
>> This is a refresh of a patch I'd done earlier -- I've tried to make
>> the bug support as generic as possible to minimize having board
>> specific ifdef crap in 8250.c -- any suggestions on how to further
>> improve it are welcome.
>>
>> drivers/serial/8250.c | 6 ++++++
>> drivers/serial/8250.h | 20 ++++++++++++++++++++
>> drivers/serial/Kconfig | 14 ++++++++++++++
>> include/linux/serial_reg.h | 2 ++
>> 4 files changed, 42 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
>> index e9b15c3..850b0e9 100644
>> --- a/drivers/serial/8250.c
>> +++ b/drivers/serial/8250.c
>> @@ -1531,6 +1531,11 @@ static void serial8250_handle_port(struct uart_8250_port *up)
>>
>> status = serial_inp(up, UART_LSR);
>>
>> + if ((up->bugs& UART_BUG_PPC)&& (status == UART_LSR_RFE_ERROR_BITS)) {
>> + spin_unlock_irqrestore(&up->port.lock, flags);
>> + return;
>> + }
>> +
>> DEBUG_INTR("status = %x...", status);
>>
>> if (status& (UART_LSR_DR | UART_LSR_BI))
>> @@ -1948,6 +1953,7 @@ static int serial8250_startup(struct uart_port *port)
>>
>> up->capabilities = uart_config[up->port.type].flags;
>> up->mcr = 0;
>> + up->bugs |= UART_KNOWN_BUGS;
>>
>> if (up->port.iotype != up->cur_iotype)
>> set_io_from_upio(port);
>> diff --git a/drivers/serial/8250.h b/drivers/serial/8250.h
>> index 6e19ea3..2074ce1 100644
>> --- a/drivers/serial/8250.h
>> +++ b/drivers/serial/8250.h
>> @@ -49,6 +49,7 @@ struct serial8250_config {
>> #define UART_BUG_TXEN (1<< 1) /* UART has buggy TX IIR status */
>> #define UART_BUG_NOMSR (1<< 2) /* UART has buggy MSR status bits (Au1x00) */
>> #define UART_BUG_THRE (1<< 3) /* UART has buggy THRE reassertion */
>> +#define UART_BUG_PPC (1<< 4) /* UART has buggy PPC break IRQ storm */
>>
>> #define PROBE_RSA (1<< 0)
>> #define PROBE_ANY (~0)
>> @@ -78,3 +79,22 @@ struct serial8250_config {
>> #else
>> #define ALPHA_KLUDGE_MCR 0
>> #endif
>> +
>> +/*
>> + * The following UART bugs are currently dynamically detected and not
>> + * required to be contingent on any particular compile time options.
>> + */
>> +#define HAS_BUG_QUOT 0 /* assign UART_BUG_QUOT to enable */
>> +#define HAS_BUG_TXEN 0 /* assign UART_BUG_TXEN to enable */
>> +#define HAS_BUG_NOMSR 0 /* assign UART_BUG_NOMSR to enable */
>> +#define HAS_BUG_THRE 0 /* assign UART_BUG_THRE to enable */
>> +
>> +#ifdef CONFIG_SERIAL_8250_PPC_BUG
>> +#define HAS_BUG_PPC UART_BUG_PPC
>> +#else
>> +#define HAS_BUG_PPC 0
>> +#endif
>> +
>> +#define UART_KNOWN_BUGS (HAS_BUG_QUOT | HAS_BUG_TXEN | HAS_BUG_NOMSR | \
>> + HAS_BUG_THRE | HAS_BUG_PPC)
>> +
>> diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
>> index 9ff47db..e01a411 100644
>> --- a/drivers/serial/Kconfig
>> +++ b/drivers/serial/Kconfig
>> @@ -70,6 +70,20 @@ config SERIAL_8250_CONSOLE
>>
>> If unsure, say N.
>>
>> +config SERIAL_8250_PPC_BUG
>> + bool "Fix 8250/16550 to handle IRQ storm after receipt of a break"
>> + depends on SERIAL_8250&& PPC32
>> + ---help---
>> + If you say Y here, addional checks will be added in the handling of
>> + interrupts on the serial ports which will prevent ill effects of
>> + an interrupt storm triggered by a break on the serial line. Without
>> + this enabled, a Sysrq via the serial console can be unusable on
>> + some systems.
>> +
>> + This is commonly observed on PPC32 MPC83xx/85xx/86xx based boards.
>> +
>> + If unsure, say N.
>> +
>> config FIX_EARLYCON_MEM
>> bool
>> depends on X86
>> diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
>> index cf9327c..010174f 100644
>> --- a/include/linux/serial_reg.h
>> +++ b/include/linux/serial_reg.h
>> @@ -111,6 +111,7 @@
>> #define UART_MCR_DTR 0x01 /* DTR complement */
>>
>> #define UART_LSR 5 /* In: Line Status Register */
>> +#define UART_LSR_RFE 0x80 /* Rx FIFO Error (BE, FE, or PE) */
>> #define UART_LSR_TEMT 0x40 /* Transmitter empty */
>> #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
>> #define UART_LSR_BI 0x10 /* Break interrupt indicator */
>> @@ -119,6 +120,7 @@
>> #define UART_LSR_OE 0x02 /* Overrun error indicator */
>> #define UART_LSR_DR 0x01 /* Receiver data ready */
>> #define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */
>> +#define UART_LSR_RFE_ERROR_BITS 0xF1 /* RFE, TEMT, THRE, BI, DR bits */
>>
>> #define UART_MSR 6 /* In: Modem Status Register */
>> #define UART_MSR_DCD 0x80 /* Data Carrier Detect */
>> --
>> 1.6.5.2
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox