606-rt2x00_no_realign.patch 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. [RFC] rt2x00: For drivers that only need L2 padding don't realign frames
  2. Signed-off-by: Helmut Schaa <helmut.schaa@...>
  3. ---
  4. Ivo, Gertjan, do you remeber by any chance why this alignment stuff was added
  5. in the first place? Was it because of DMA restrictions?
  6. While doing some profiling on the rt3052 SoC I noticed that 30-40% time was
  7. spent in memmove calls. And the culprit is the memmove aligning the payload
  8. to a 4byte boundary since that has to move a whole bunch of data.
  9. Interesstingly the legacy drivers insert an l2pad between the header and the
  10. payload but doesn't realign the payload itself to a 4-byte boundary. Hence,
  11. I came up with this patch and indeed CPU usage improves impressively.
  12. Only tested on rt2800pci!
  13. Thanks,
  14. Helmut
  15. drivers/net/wireless/rt2x00/rt2x00queue.c | 30 +++-------------------------
  16. 1 files changed, 4 insertions(+), 26 deletions(-)
  17. --- a/drivers/net/wireless/rt2x00/rt2x00queue.c
  18. +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
  19. @@ -161,36 +161,14 @@ void rt2x00queue_align_frame(struct sk_b
  20. void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
  21. {
  22. unsigned int payload_length = skb->len - header_length;
  23. - unsigned int header_align = ALIGN_SIZE(skb, 0);
  24. - unsigned int payload_align = ALIGN_SIZE(skb, header_length);
  25. unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
  26. - /*
  27. - * Adjust the header alignment if the payload needs to be moved more
  28. - * than the header.
  29. - */
  30. - if (payload_align > header_align)
  31. - header_align += 4;
  32. -
  33. - /* There is nothing to do if no alignment is needed */
  34. - if (!header_align)
  35. + if (!l2pad)
  36. return;
  37. - /* Reserve the amount of space needed in front of the frame */
  38. - skb_push(skb, header_align);
  39. -
  40. - /*
  41. - * Move the header.
  42. - */
  43. - memmove(skb->data, skb->data + header_align, header_length);
  44. -
  45. - /* Move the payload, if present and if required */
  46. - if (payload_length && payload_align)
  47. - memmove(skb->data + header_length + l2pad,
  48. - skb->data + header_length + l2pad + payload_align,
  49. - payload_length);
  50. -
  51. - /* Trim the skb to the correct size */
  52. + /* insert l2pad -> Move header */
  53. + skb_push(skb, l2pad);
  54. + memmove(skb->data, skb->data + l2pad, header_length);
  55. skb_trim(skb, header_length + l2pad + payload_length);
  56. }