linux_dsm_epyc7002/drivers/net/can
Thomas Gleixner c0a9f4d396 can: c_can: Reduce register access
commit 4ce78a838c (can: c_can: Speed up rx_poll function) hyped a
performance improvement by reducing the access to the interrupt
pending register from a dual 16 bit to a single 16 bit access. Wow!

Thereby it crippled the driver to cast the 16 msg objects in stone,
which is completly braindead as contemporary hardware has up to 128
message objects. Supporting larger object buffers is a major surgery,
but it'd be definitely worth it especially as the driver does not
support HW message filtering ....

The logic of the "FIFO" implementation is to split the FIFO in half.

For the lower half we read the buffers and clear the interrupt pending
bit, but keep the newdat bit set, so the HW will queue above those
buffers.

When we read out the last low buffer then we reenable all the low half
buffers by clearing the newdat bit.

The upper half buffers clear the newdat and the interrupt pending bit
right away as we know that the lower half bits are clear and give us a
headstart against the hardware.

Now the implementation is:

    transfer_message_object()
    read_object_and_put_into_skb();

    if (obj < END_OF_LOW_BUF)
       clear_intpending(obj)
    else if (obj > END_OF_LOW_BUF)
       clear_intpending_and_newdat(obj)
    else if (obj == END_OF_LOW_BUF)
       clear_newdat_of_all_low_objects()

The hardware allows to avoid most of the mess simply because we can
tell the transfer_message_object() function to clear bits right away.

So we can be clever and do:

   if (obj <= END_OF_LOW_BUF)
      ctrl = TRANSFER_MSG | CLEAR_INTPND;
   else
      ctrl = TRANSFER_MSG | CLEAR_INTPND | CLEAR_NEWDAT;

    transfer_message_object(ctrl)
    read_object_and_put_into_skb();

    if (obj == END_OF_LOW_BUF)
       clear_newdat_of_all_low_objects()

So we save a complete control operation on all message objects except
the one which is the end of the low buffer. That's a few micro seconds
per object.

I'm not adding a boasting profile to that, simply because it's self
explaining.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[mkl: adjusted subject and commit message]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
2014-04-01 11:55:01 +02:00
..
c_can can: c_can: Reduce register access 2014-04-01 11:55:01 +02:00
cc770 can: cc770: use dev_get_platdata() 2013-09-21 15:43:13 +02:00
mscan Merge remote-tracking branch 'agust/next' into next 2014-01-29 16:53:55 +11:00
sja1000 can: sja1000: add support for Elcus CAN200PCI 2014-01-11 19:43:16 +01:00
softing drivers/net: delete non-required instances of include <linux/init.h> 2014-01-16 11:53:26 -08:00
usb can: usb_8dev: Fix memory leak in usb_8dev_start_xmit 2014-04-01 11:54:55 +02:00
at91_can.c drivers/net: delete non-required instances of include <linux/init.h> 2014-01-16 11:53:26 -08:00
bfin_can.c drivers/net: delete non-required instances of include <linux/init.h> 2014-01-16 11:53:26 -08:00
dev.c can: add destructor for self generated skbs 2014-01-30 16:25:49 -08:00
flexcan.c can: flexcan: factor out soft reset into seperate funtion 2014-03-03 14:29:51 +01:00
grcan.c drivers: remove unnecessary prom.h includes 2013-10-09 20:03:58 -05:00
janz-ican3.c linux-can-fixes-for-3.14-20140129 2014-01-30 16:48:17 -08:00
Kconfig can: flexcan: fix flexcan driver build for big endian on ARM and little endian on PowerPc 2014-01-29 20:23:22 +01:00
led.c net: pass info struct via netdevice notifier 2013-05-28 13:11:01 -07:00
Makefile can: add tx/rx LED trigger support 2013-01-26 16:58:59 +01:00
mcp251x.c can: mcp251x: Add device tree support 2013-12-21 15:04:24 +01:00
pch_can.c drivers/net: delete non-required instances of include <linux/init.h> 2014-01-16 11:53:26 -08:00
slcan.c can: Fix FSF address in file headers 2013-12-17 11:47:21 +01:00
ti_hecc.c drivers/net: delete non-required instances of include <linux/init.h> 2014-01-16 11:53:26 -08:00
vcan.c can: add destructor for self generated skbs 2014-01-30 16:25:49 -08:00