From: Thomas Gleixner <tglx@linutronix.de>
To: linux-can <linux-can@vger.kernel.org>
Cc: Alexander Stein <alexander.stein@systec-electronic.com>,
Oliver Hartkopp <socketcan@hartkopp.net>,
Marc Kleine-Budde <mkl@pengutronix.de>,
Wolfgang Grandegger <wg@grandegger.com>, Mark <mark5@del-llc.com>
Subject: [patch V2 21/21] can: c_can: Speed up tx buffer invalidation
Date: Fri, 11 Apr 2014 08:13:22 -0000 [thread overview]
Message-ID: <20140411080654.280509182@linutronix.de> (raw)
In-Reply-To: 20140411080547.845836199@linutronix.de
[-- Attachment #1: can-c_can-speed-up-tx-inval.patch --]
[-- Type: text/plain, Size: 4466 bytes --]
It's suffcient to kill the TXIE bit in the message control register
even if the documentation of C and D CAN says that it's not allowed to
do that while MSGVAL is set. Reality tells a different story and this
change gives us another 2% of CPU back for not waiting on I/O.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
drivers/net/can/c_can/c_can.c | 54 ++++++++++++++++++++++++++++++------------
drivers/net/can/c_can/c_can.h | 1
2 files changed, 40 insertions(+), 15 deletions(-)
Index: linux-2.6/drivers/net/can/c_can/c_can.c
===================================================================
--- linux-2.6.orig/drivers/net/can/c_can/c_can.c
+++ linux-2.6/drivers/net/can/c_can/c_can.c
@@ -276,11 +276,34 @@ static inline void c_can_object_put(stru
c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj);
}
+/*
+ * Note: According to documentation clearing TXIE while MSGVAL is set
+ * is not allowed, but works nicely on C/DCAN. And that lowers the I/O
+ * load significantly.
+ */
+static void c_can_inval_tx_object(struct net_device *dev, int iface, int obj)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
+ c_can_object_put(dev, iface, obj, IF_COMM_INVAL);
+}
+
+static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj)
+{
+ struct c_can_priv *priv = netdev_priv(dev);
+
+ priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0);
+ priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0);
+ c_can_inval_tx_object(dev, iface, obj);
+}
+
static void c_can_setup_tx_object(struct net_device *dev, int iface,
- struct can_frame *frame, int obj)
+ struct can_frame *frame, int idx)
{
struct c_can_priv *priv = netdev_priv(dev);
u16 ctrl = IF_MCONT_TX | frame->can_dlc;
+ bool rtr = frame->can_id & CAN_RTR_FLAG;
u32 arb = IF_ARB_MSGVAL;
int i;
@@ -291,9 +314,20 @@ static void c_can_setup_tx_object(struct
arb |= (frame->can_id & CAN_SFF_MASK) << 18;
}
- if (!(frame->can_id & CAN_RTR_FLAG))
+ if (!rtr)
arb |= IF_ARB_TRANSMIT;
+ /*
+ * If we change the DIR bit, we need to invalidate the buffer
+ * first, i.e. clear the MSGVAL flag in the arbiter.
+ */
+ if (rtr != (bool)test_bit(idx, &priv->tx_dir)) {
+ u32 obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
+
+ c_can_inval_msg_object(dev, iface, obj);
+ change_bit(idx, &priv->tx_dir);
+ }
+
priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), arb);
priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), arb >> 16);
@@ -401,17 +435,6 @@ static void c_can_setup_receive_object(s
c_can_object_put(dev, iface, obj, IF_COMM_RCV_SETUP);
}
-static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj)
-{
- struct c_can_priv *priv = netdev_priv(dev);
-
- priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0);
- priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0);
- priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0);
-
- c_can_object_put(dev, iface, obj, IF_COMM_INVAL);
-}
-
static netdev_tx_t c_can_start_xmit(struct sk_buff *skb,
struct net_device *dev)
{
@@ -436,7 +459,7 @@ static netdev_tx_t c_can_start_xmit(stru
* can_put_echo_skb(). We must do this before we enable
* transmit as we might race against do_tx().
*/
- c_can_setup_tx_object(dev, IF_TX, frame, obj);
+ c_can_setup_tx_object(dev, IF_TX, frame, idx);
priv->dlc[idx] = frame->can_dlc;
can_put_echo_skb(skb, dev, idx);
@@ -563,6 +586,7 @@ static int c_can_chip_config(struct net_
/* Clear all internal status */
atomic_set(&priv->tx_active, 0);
priv->rxmasked = 0;
+ priv->tx_dir = 0;
/* set bittiming params */
return c_can_set_bittiming(dev);
@@ -654,7 +678,7 @@ static void c_can_do_tx(struct net_devic
idx--;
pend &= ~(1 << idx);
obj = idx + C_CAN_MSG_OBJ_TX_FIRST;
- c_can_inval_msg_object(dev, IF_RX, obj);
+ c_can_inval_tx_object(dev, IF_RX, obj);
can_get_echo_skb(dev, idx);
bytes += priv->dlc[idx];
pkts++;
Index: linux-2.6/drivers/net/can/c_can/c_can.h
===================================================================
--- linux-2.6.orig/drivers/net/can/c_can/c_can.h
+++ linux-2.6/drivers/net/can/c_can/c_can.h
@@ -174,6 +174,7 @@ struct c_can_priv {
struct net_device *dev;
struct device *device;
atomic_t tx_active;
+ unsigned long tx_dir;
int last_status;
u16 (*read_reg) (struct c_can_priv *priv, enum reg index);
void (*write_reg) (struct c_can_priv *priv, enum reg index, u16 val);
next prev parent reply other threads:[~2014-04-11 8:13 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-04-11 8:13 [patch V2 00/21] can: c_can: Another pile of fixes and improvements Thomas Gleixner
2014-04-11 8:13 ` [patch V2 02/21] can: c_can: Fix startup logic Thomas Gleixner
2014-04-11 8:13 ` [patch V2 01/21] can: c_can_pci: Set the type of the IP core Thomas Gleixner
2014-04-11 8:13 ` [patch V2 03/21] can: c_can: Make bus off interrupt disable logic work Thomas Gleixner
2014-04-11 8:13 ` [patch V2 04/21] can: c_can: Do not access skb after net_receive_skb() Thomas Gleixner
2014-04-11 8:13 ` [patch V2 05/21] can: c_can: Handle state change correctly Thomas Gleixner
2014-04-11 8:13 ` [patch V2 07/21] can: c_can: Always update error stats Thomas Gleixner
2014-04-11 8:13 ` [patch V2 06/21] can: c_can: Fix berr reporting Thomas Gleixner
2014-04-11 8:13 ` [patch V2 08/21] can: c_can: Simplify buffer reenabling Thomas Gleixner
2014-04-11 8:13 ` [patch V2 10/21] can: c_can: Get rid of pointless interrupts Thomas Gleixner
2014-04-11 8:13 ` [patch V2 09/21] can: c_can: Avoid status register update for D_CAN Thomas Gleixner
2014-04-11 8:13 ` [patch V2 11/21] can: c_can : Disable rx split as workaround Thomas Gleixner
2014-04-11 8:13 ` [patch V2 13/21] can: c_can: Cleanup irq enable/disable Thomas Gleixner
2014-04-11 8:13 ` [patch V2 12/21] can: c_can": Work around C_CAN RX wreckage Thomas Gleixner
2014-04-14 8:38 ` Alexander Stein
2014-04-14 20:13 ` Thomas Gleixner
2014-04-14 20:17 ` Marc Kleine-Budde
2014-04-11 8:13 ` [patch V2 14/21] can: c_can: Cleanup c_can_read_msg_object() Thomas Gleixner
2014-04-11 8:13 ` [patch V2 15/21] can: c_can Cleanup setup of receive buffers Thomas Gleixner
2014-04-11 8:13 ` [patch V2 16/21] can: c_can: Cleanup c_can_inval_msg_object() Thomas Gleixner
2014-04-11 8:13 ` [patch V2 17/21] can: c_can: Cleanup c_can_msg_obj_put/get() Thomas Gleixner
2014-04-11 8:13 ` [patch V2 19/21] can: c_can: Use proper u32 variables in c_can_write_msg_object() Thomas Gleixner
2014-04-11 8:13 ` [patch V2 18/21] can: c_can: Cleanup c_can_write_msg_object() Thomas Gleixner
2014-04-11 8:13 ` Thomas Gleixner [this message]
2014-04-11 8:13 ` [patch V2 20/21] can: c_can: Remove tx locking Thomas Gleixner
2014-04-14 8:38 ` [patch V2 00/21] can: c_can: Another pile of fixes and improvements Alexander Stein
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=20140411080654.280509182@linutronix.de \
--to=tglx@linutronix.de \
--cc=alexander.stein@systec-electronic.com \
--cc=linux-can@vger.kernel.org \
--cc=mark5@del-llc.com \
--cc=mkl@pengutronix.de \
--cc=socketcan@hartkopp.net \
--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.