1. 19 5月, 2014 4 次提交
  2. 28 4月, 2014 1 次提交
  3. 24 4月, 2014 1 次提交
  4. 23 4月, 2014 2 次提交
  5. 14 4月, 2014 1 次提交
  6. 03 4月, 2014 6 次提交
  7. 02 4月, 2014 16 次提交
  8. 01 4月, 2014 9 次提交
    • T
      can: c_can: Avoid led toggling for every packet. · b1d8e431
      Thomas Gleixner 提交于
      There is no point to toggle the RX led for every packet. Especially if
      we have a full FIFO we want to avoid everything we can.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
      b1d8e431
    • T
      can: c_can: Simplify TX interrupt cleanup · 5a7513ad
      Thomas Gleixner 提交于
      The function loads the message object from the hardware to get the
      payload length. The previous patch stores that information in an
      array, so we can avoid the hardware access.
      
      Remove the hardware access and move the led toggle outside of the
      spinlocked region. Toggle the led only once when at least one packet
      has been received.
      
      Binary size shrinks along with the code
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
      5a7513ad
    • T
      can: c_can: Store dlc private · 90247008
      Thomas Gleixner 提交于
      We can avoid the HW access in TX cleanup path for retrieving the DLC
      of the sent package if we store the DLC in a private array.
      
      Ideally this should be handled in the can_echo_skb functions, but I
      leave that exercise to the CAN folks.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
      90247008
    • T
      can: c_can: Reduce register access · c0a9f4d3
      Thomas Gleixner 提交于
      commit 4ce78a83 (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: NThomas Gleixner <tglx@linutronix.de>
      [mkl: adjusted subject and commit message]
      Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
      c0a9f4d3
    • T
      can: c_can: Make the code readable · 520f570c
      Thomas Gleixner 提交于
      If every other line contains line breaks, that's a clear sign for
      indentation level madness. Split out the inner loop and move the code
      to a separate function. gcc creates slightly worse code for that, but
      we'll fix that in the next step.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      [mkl: adjusted subject]
      Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
      520f570c
    • T
      can: c_can: Provide protection in the xmit path · bf88a206
      Thomas Gleixner 提交于
      The network core does not serialize the access to the hardware. The
      xmit related code lets the following happen:
      
      CPU0 	     	       CPU1
      interrupt()
       do_poll()
         c_can_do_tx()
          Fiddle with HW and	xmit()
          internal data	  Fiddle with HW and
          	     		  internal data
      
      due the complete lack of serialization.
      
      Add proper locking.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
      bf88a206
    • T
      can: c_can: Remove EOB exit · 710c5610
      Thomas Gleixner 提交于
      The rx_poll code has the following gem:
      
      	if (msg_ctrl_save & IF_MCONT_EOB)
      		return num_rx_pkts;
      
      The EOB bit is the indicator for the hardware that this is the last
      configured FIFO object. But this object can contain valid data, if we
      manage to free up objects before the overrun case hits.
      
      Now if the code exits due to the EOB bit set, then this buffer is
      stale and the interrupt bit and NewDat bit of the buffer are still
      set. Results in a nice interrupt storm unless we come into an overrun
      situation where the MSGLST bit gets set.
      
           ksoftirqd/0-3     [000] ..s.    79.124101: c_can_poll: rx_poll: val: 00008001 pend 00008001
           ksoftirqd/0-3     [000] ..s.    79.124176: c_can_poll: rx_poll: val: 00008000 pend 00008000
           ksoftirqd/0-3     [000] ..s.    79.124187: c_can_poll: rx_poll: val: 00008002 pend 00008002
           ksoftirqd/0-3     [000] ..s.    79.124256: c_can_poll: rx_poll: val: 00008000 pend 00008000
           ksoftirqd/0-3     [000] ..s.    79.124267: c_can_poll: rx_poll: val: 00008000 pend 00008000
      
      The amazing thing is that the check of the MSGLST (aka overrun bit)
      used to be after the check of the EOB bit. That was "fixed" in commit
      5d0f801a(can: c_can: Fix RX message handling, handle lost message
      before EOB). But the author of this "fix" did not even understand that
      the EOB check is broken as well.
      
      Again a simple solution: Remove
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      [mkl: adjusted subject and commit message]
      Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
      710c5610
    • T
      can: c_can: Fix the lost message handling · 07c7b6f6
      Thomas Gleixner 提交于
      The lost message handling is broken in several ways.
      
      1) Clearing the message lost flag is done by writing 0 to the
         message control register of the object.
      
         #define IF_MCONT_CLR_MSGLST    (0 << 14)
      
         That clears the object buffer configuration in the worst case,
         which results in a loss of the EOB flag. That leaves the FIFO chain
         without a limit and causes a complete lockup of the HW
      
      2) In case that the error skb allocation fails, the code happily
         claims that it handed down a packet. Just an accounting bug, but ....
      
      3) The code adds a lot of pointless overhead to that error case, where
         we need to get stuff done as fast as possible to avoid more packet
         loss.
      
         - printk an annoying error message
         - reread the object buffer for nothing
      
      Fix is simple again:
      
        - Use the already known MSGCTRL content and only clear the MSGLST bit
        - Fix the buffer accounting by adding a proper return code
        - Remove the pointless operations
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
      07c7b6f6
    • T
      can: c_can: Fix buffer ordering · 64f08f2f
      Thomas Gleixner 提交于
      The buffer handling of c_can has been broken forever. That leads to
      message reordering:
      
      ksoftirqd/0-3     [000] ..s.    79.123776: c_can_poll: rx_poll: val: 00007fff
      ksoftirqd/0-3     [000] ..s.    79.124101: c_can_poll: rx_poll: val: 00008001
      
      What happens is:
      
      CPU				HW
      				queue new packet into obj 16 (0-15 are busy)
      read obj 1-15
      return because pending is 0
      				set pending obj 16 -> pending reg 8000
      				queue new packet into obj 1
      				set pending obj 1 -> pending reg 8001
      
      So the current algorithmus reads the newest message first, which
      violates the ordering rules of CAN.
      
      Add proper handling of that situation by analyzing the contents of the
      pending register for gaps.
      
      This does NOT fix the message object corruption which can lead to
      interrupt storms. Thats addressed in the next patches.
      Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
      [mkl: adjusted subject]
      Signed-off-by: NMarc Kleine-Budde <mkl@pengutronix.de>
      64f08f2f