From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Wolfgang Grandegger <wg@grandegger.com>,
Marc Kleine-Budde <mkl@pengutronix.de>,
Markus Pargmann <mpa@pengutronix.de>,
Benedikt Spranger <b.spranger@linutronix.de>,
linux-can@vger.kernel.org, netdev@vger.kernel.org
Subject: [patch 03/12] can: c_can: Make it SMP safe
Date: Tue, 18 Mar 2014 17:19:09 -0000 [thread overview]
Message-ID: <20140318171126.844179673@linutronix.de> (raw)
In-Reply-To: 20140318171007.528610837@linutronix.de
[-- Attachment #1: can-c_can-use-if1-2.patch --]
[-- Type: text/plain, Size: 4418 bytes --]
The hardware has two message control interfaces, but the code only
uses the first one. So on SMP the following can be observed:
CPU0 CPU1
rx_poll()
write IF1 xmit()
write IF1
write IF1
That results in corrupted message object configurations. The TX/RX is
not globally serialized it's only serialized on a core.
Simple solution: Let RX use IF1 and TX use IF2 and all is good.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
drivers/net/can/c_can/c_can.c | 36 +++++++++++++++++++++---------------
1 file changed, 21 insertions(+), 15 deletions(-)
Index: linux/drivers/net/can/c_can/c_can.c
===================================================================
--- linux.orig/drivers/net/can/c_can/c_can.c
+++ linux/drivers/net/can/c_can/c_can.c
@@ -133,6 +133,12 @@
#define IF_MCONT_DLC_MASK 0xf
/*
+ * Use IF1 for RX and IF2 for TX
+ */
+#define IF_RX 0
+#define IF_TX 1
+
+/*
* IFx register masks:
* allow easy operation on 16-bit registers when the
* argument is 32-bit instead
@@ -420,7 +426,7 @@ static void c_can_handle_lost_msg_obj(st
priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface),
IF_MCONT_CLR_MSGLST);
- c_can_object_put(dev, 0, objno, IF_COMM_CONTROL);
+ c_can_object_put(dev, iface, objno, IF_COMM_CONTROL);
/* create an error msg */
skb = alloc_can_err_skb(dev, &frame);
@@ -551,7 +557,7 @@ static netdev_tx_t c_can_start_xmit(stru
msg_obj_no = get_tx_next_msg_obj(priv);
/* prepare message object for transmission */
- c_can_write_msg_object(dev, 0, frame, msg_obj_no);
+ c_can_write_msg_object(dev, IF_TX, frame, msg_obj_no);
can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
/*
@@ -634,14 +640,14 @@ static void c_can_configure_msg_objects(
/* first invalidate all message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_NO_OF_OBJECTS; i++)
- c_can_inval_msg_object(dev, 0, i);
+ c_can_inval_msg_object(dev, IF_RX, i);
/* setup receive message objects */
for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++)
- c_can_setup_receive_object(dev, 0, i, 0, 0,
+ c_can_setup_receive_object(dev, IF_RX, i, 0, 0,
(IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB);
- c_can_setup_receive_object(dev, 0, C_CAN_MSG_OBJ_RX_LAST, 0, 0,
+ c_can_setup_receive_object(dev, IF_RX, C_CAN_MSG_OBJ_RX_LAST, 0, 0,
IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK);
}
@@ -783,13 +789,13 @@ static void c_can_do_tx(struct net_devic
if (!(val & (1 << (msg_obj_no - 1)))) {
can_get_echo_skb(dev,
msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST);
- c_can_object_get(dev, 0, msg_obj_no, IF_COMM_ALL);
+ c_can_object_get(dev, IF_TX, msg_obj_no, IF_COMM_ALL);
stats->tx_bytes += priv->read_reg(priv,
- C_CAN_IFACE(MSGCTRL_REG, 0))
+ C_CAN_IFACE(MSGCTRL_REG, IF_TX))
& IF_MCONT_DLC_MASK;
stats->tx_packets++;
can_led_event(dev, CAN_LED_EVENT_TX);
- c_can_inval_msg_object(dev, 0, msg_obj_no);
+ c_can_inval_msg_object(dev, IF_TX, msg_obj_no);
} else {
break;
}
@@ -841,13 +847,13 @@ static int c_can_do_rx_poll(struct net_d
while ((msg_obj = ffs(val)) && quota > 0) {
val &= ~BIT(msg_obj - 1);
- c_can_object_get(dev, 0, msg_obj, IF_COMM_ALL &
+ c_can_object_get(dev, IF_RX, msg_obj, IF_COMM_ALL &
~IF_COMM_TXRQST);
msg_ctrl_save = priv->read_reg(priv,
- C_CAN_IFACE(MSGCTRL_REG, 0));
+ C_CAN_IFACE(MSGCTRL_REG, IF_RX));
if (msg_ctrl_save & IF_MCONT_MSGLST) {
- c_can_handle_lost_msg_obj(dev, 0, msg_obj);
+ c_can_handle_lost_msg_obj(dev, IF_RX, msg_obj);
num_rx_pkts++;
quota--;
continue;
@@ -860,19 +866,19 @@ static int c_can_do_rx_poll(struct net_d
continue;
/* read the data from the message object */
- c_can_read_msg_object(dev, 0, msg_ctrl_save);
+ c_can_read_msg_object(dev, IF_RX, msg_ctrl_save);
if (msg_obj < C_CAN_MSG_RX_LOW_LAST)
- c_can_mark_rx_msg_obj(dev, 0,
+ c_can_mark_rx_msg_obj(dev, IF_RX,
msg_ctrl_save, msg_obj);
else if (msg_obj > C_CAN_MSG_RX_LOW_LAST)
/* activate this msg obj */
- c_can_activate_rx_msg_obj(dev, 0,
+ c_can_activate_rx_msg_obj(dev, IF_RX,
msg_ctrl_save, msg_obj);
else if (msg_obj == C_CAN_MSG_RX_LOW_LAST)
/* activate all lower message objects */
c_can_activate_all_lower_rx_msg_obj(dev,
- 0, msg_ctrl_save);
+ IF_RX, msg_ctrl_save);
num_rx_pkts++;
quota--;
next prev parent reply other threads:[~2014-03-18 17:19 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-18 17:19 [patch 00/12] can: c_can: Fix a series of serious bugs and improve the performance Thomas Gleixner
2014-03-18 17:19 ` [patch 02/12] can: c_can: Fix hardware raminit function Thomas Gleixner
2014-03-18 18:38 ` Marc Kleine-Budde
2014-03-18 22:15 ` Thomas Gleixner
2014-03-19 6:37 ` Oliver Hartkopp
2014-03-19 9:22 ` Thomas Gleixner
2014-03-18 17:19 ` [patch 01/12] can: c_can: Wait for CONTROL_INIT to be cleared Thomas Gleixner
2014-03-18 18:11 ` Marc Kleine-Budde
2014-03-18 18:19 ` Thomas Gleixner
2014-03-18 17:19 ` Thomas Gleixner [this message]
2014-03-18 18:46 ` [patch 03/12] can: c_can: Make it SMP safe Marc Kleine-Budde
2014-03-18 19:40 ` Thomas Gleixner
2014-03-18 17:19 ` [patch 05/12] can: c_can: Fix the lost message handling Thomas Gleixner
2014-03-18 17:19 ` [patch 04/12] can: c_can: Fix buffer ordering for real Thomas Gleixner
2014-03-18 17:19 ` [patch 06/12] can: c_can: Remove braindamaged EOB exit Thomas Gleixner
2014-03-18 17:19 ` [patch 07/12] can: c_can: Provide protection in the xmit path Thomas Gleixner
2014-03-18 17:19 ` [patch 08/12] can: c_can: Makethe code readable Thomas Gleixner
2014-03-18 17:37 ` Joe Perches
2014-03-18 18:23 ` Thomas Gleixner
2014-03-18 18:27 ` [patch 08/12 V2] " Thomas Gleixner
2014-03-18 19:20 ` Joe Perches
2014-03-18 17:19 ` [patch 09/12] can: c_can: Reduce register access for real Thomas Gleixner
2014-03-18 17:19 ` [patch 10/12] can: c_can: Store dlc private Thomas Gleixner
2014-03-18 17:19 ` [patch 11/12] can: c_can: Simplify TX interrupt cleanup Thomas Gleixner
2014-03-18 17:19 ` [patch 12/12] can: c_can: Avoid led toggling for every packet Thomas Gleixner
2014-03-18 20:18 ` can: c_can: Reduce interrupt load by 50% Thomas Gleixner
2014-03-18 20:35 ` Joe Perches
2014-03-18 20:43 ` Thomas Gleixner
2014-03-18 21:27 ` Joe Perches
2014-03-31 22:35 ` [patch 00/12] can: c_can: Fix a series of serious bugs and improve the performance Thomas Gleixner
2014-04-01 8:09 ` Marc Kleine-Budde
2014-04-01 9:07 ` Thomas Gleixner
2014-04-01 9:09 ` Marc Kleine-Budde
2014-04-01 21:29 ` Marc Kleine-Budde
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140318171126.844179673@linutronix.de \
--to=tglx@linutronix.de \
--cc=b.spranger@linutronix.de \
--cc=linux-can@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mkl@pengutronix.de \
--cc=mpa@pengutronix.de \
--cc=netdev@vger.kernel.org \
--cc=wg@grandegger.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.