[RFC]: can: mcp251xfd: coalescing support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,

this is a preview series for the mcp251xfd which adds IRQ coalescing
support.

- What is IRQ coalescing and how does the mcp251xfd driver implement it?

The idea behind IRQ coalescing is to not serve every interrupt (CAN
frame RX'ed and CAN frame TX complete) as soon as possible, but to
delay it and handle several RX/TX complete frames at once. This
reduces the number of IRQs and SPI transfers.

With activated RX IRQ coalescing, the RX IRQ handler deactivated the
"RX FIFO not empty interrupt" and activated the "FIFO half full" (or
"FIFO full IRQ" - depending on configuration) instead.

To ensure that a single RX'ed CAN frame (which doesn't trigger the
FIFO half full IRQ) doesn't starve in the FIFO, a hrtimer is started
that activates the "FIFO not empty" IRQ after a configurable delay.

TX IRQ coalescing does the same thing, but for TX complete IRQs

- How to configure this?

Configuration is a bit tricky, it consists of several parameters,
which are all influencing each other and the number of buffers is
limited to power-of-two, to up to 32 per FIFO.

1) Configure the CAN mode (classical CAN-2.0 or CAN-FD) mode. Do not
   bring the interface up.

2) Configure RX and TX FIFOs. In ethtool's speak this is called "ring"
   configuration. The current ring configuration is shown with the
   "-g" parameter:

| $ ethtool -g mcp251xfd1
|
| Ring parameters for mcp251xfd1:
| Pre-set maximums:
| RX:             96
| RX Mini:        n/a
| RX Jumbo:       n/a
| TX:             16
| Current hardware settings:
| RX:             80
| RX Mini:        n/a
| RX Jumbo:       n/a
| TX:             8

   For TX, 1 FIFO is used with the default depth 8 (CAN-2.0 mode) and
   4 (CAN-FD mode). In default configuration the driver uses the
   remaining space for RX. In CAN-2.0 mode, this leads to 80 RX
   buffers and 8 TX buffers. A more detailed overview is printed when
   the interface is brought up:

| FIFO setup: TEF:         0x400:  8*12 bytes =   96 bytes
| FIFO setup: RX-0: FIFO 1/0x460: 32*20 bytes =  640 bytes
| FIFO setup: RX-1: FIFO 2/0x6e0: 32*20 bytes =  640 bytes
| FIFO setup: RX-2: FIFO 3/0x960: 16*20 bytes =  320 bytes
| FIFO setup: TX:   FIFO 4/0xaa0:  8*16 bytes =  128 bytes
| FIFO setup: free:                              224 bytes

   Note:
   - The number of RX buffers takes more priority than the number of
     TX buffers.
   - Ring configuration is reset by CAN mode configuration.
   - Ring configuration resets coalescing configuration.
   - Configuration is only possible if the interface is down.

   Let's increase the number of RX buffers to the max of 96.

| $ ethtool -G mcp251xfd1 rx 96 tx 4

   Check config with "-g":

| $ sudo ethtool -g mcp251xfd1
| Ring parameters for mcp251xfd1:
| Pre-set maximums:
| RX:             96
| RX Mini:        n/a
| RX Jumbo:       n/a
| TX:             16
| Current hardware settings:
| RX:             96
| RX Mini:        n/a
| RX Jumbo:       n/a
| TX:             4

   The detailed output during ifup:

| FIFO setup: TEF:         0x400:  4*12 bytes =   48 bytes
| FIFO setup: RX-0: FIFO 1/0x430: 32*20 bytes =  640 bytes
| FIFO setup: RX-1: FIFO 2/0x6b0: 32*20 bytes =  640 bytes
| FIFO setup: RX-2: FIFO 3/0x930: 32*20 bytes =  640 bytes
| FIFO setup: TX:   FIFO 4/0xbb0:  4*16 bytes =   64 bytes
| FIFO setup: free:                               16 bytes

3) Configure the RX/TX IRQ coalescing.
   The driver supports both RX and TX coalescing. The configuration is
   done again with ethtool, the interface must be down for this.

   There are 2 parameters to configure:
   1) FIFO fill level that triggers IRQ
   2) Delay after IRQ processing to enable FIFO not empty IRQ

   In this example we configure RX coalescing for 32 buffers with a
   delay of 10ms:

| $ ethtool -C mcp251xfd1 rx-usecs-irq 10000 rx-frames-irq 32

   Check with "-c":

| $ ethtool -c mcp251xfd1
|
| Coalesce parameters for mcp251xfd1:
| Adaptive RX: n/a  TX: n/a
| stats-block-usecs: n/a
| sample-interval: n/a
| pkt-rate-low: n/a
| pkt-rate-high: n/a
|
| rx-usecs: n/a
| rx-frames: n/a
| rx-usecs-irq: 10000
| rx-frames-irq: 32
|
| tx-usecs: n/a
| tx-frames: n/a
| tx-usecs-irq: 0
| tx-frames-irq: 1
|
| rx-usecs-low: n/a
| rx-frame-low: n/a
| tx-usecs-low: n/a
| tx-frame-low: n/a
|
| rx-usecs-high: n/a
| rx-frame-high: n/a
| tx-usecs-high: n/a
| tx-frame-high: n/a

   The TX IRQ coalescing parameters we see in this example output are
   "tx-usecs-irq=0" and "tx-frames-irq=1". This means no coalescing,
   i.e. every TX complete event triggers an IRQ and is directly served
   in the driver.

   Note:
   - Use "rx-usecs-irq=0" and "rx-frames-irq=1" to switch off RX
     coalescing, accordingly for TX.
   - Coalescing configuration is reset by ring configuration.
   - Configuration is only possible if the interface is down.

Known issues:
- ifup with RX-coalescing configuration sometimes leads to RX stopping
  after a few CAN frames on heavy loaded busses.
- Patches need proper description.

Happy testing. I'm especially interested in numbers regarding
reduction of system load and max CAN bus utilization. Further numbers
to look at is the number of IRQs from the mcp251xfd chip and number of
SPI host controller IRQs.

Note: small transfers on the rapi don't use IRQ mode per default, you
might see an increase of SPI IRQs if the driver reads a lot of CAN
frames from the FIFO in one transfer.

regards,
Marc

PS: The patches are available as a git branch on kernel.org:

https://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can-next.git/log/?h=mcp251xfd-coalesce






[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux