2
0

307-mac80211-add-a-function-for-running-rx-without-passi.patch 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. From: Felix Fietkau <[email protected]>
  2. Date: Sat, 25 Jul 2020 20:53:23 +0200
  3. Subject: [PATCH] mac80211: add a function for running rx without passing skbs
  4. to the stack
  5. This can be used to run mac80211 rx processing on a batch of frames in NAPI
  6. poll before passing them to the network stack in a large batch.
  7. This can improve icache footprint, or it can be used to pass frames via
  8. netif_receive_skb_list.
  9. Signed-off-by: Felix Fietkau <[email protected]>
  10. ---
  11. --- a/include/net/mac80211.h
  12. +++ b/include/net/mac80211.h
  13. @@ -4358,6 +4358,31 @@ void ieee80211_free_hw(struct ieee80211_
  14. void ieee80211_restart_hw(struct ieee80211_hw *hw);
  15. /**
  16. + * ieee80211_rx_list - receive frame and store processed skbs in a list
  17. + *
  18. + * Use this function to hand received frames to mac80211. The receive
  19. + * buffer in @skb must start with an IEEE 802.11 header. In case of a
  20. + * paged @skb is used, the driver is recommended to put the ieee80211
  21. + * header of the frame on the linear part of the @skb to avoid memory
  22. + * allocation and/or memcpy by the stack.
  23. + *
  24. + * This function may not be called in IRQ context. Calls to this function
  25. + * for a single hardware must be synchronized against each other. Calls to
  26. + * this function, ieee80211_rx_ni() and ieee80211_rx_irqsafe() may not be
  27. + * mixed for a single hardware. Must not run concurrently with
  28. + * ieee80211_tx_status() or ieee80211_tx_status_ni().
  29. + *
  30. + * This function must be called with BHs disabled and RCU read lock
  31. + *
  32. + * @hw: the hardware this frame came in on
  33. + * @sta: the station the frame was received from, or %NULL
  34. + * @skb: the buffer to receive, owned by mac80211 after this call
  35. + * @list: the destination list
  36. + */
  37. +void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
  38. + struct sk_buff *skb, struct list_head *list);
  39. +
  40. +/**
  41. * ieee80211_rx_napi - receive frame from NAPI context
  42. *
  43. * Use this function to hand received frames to mac80211. The receive
  44. --- a/net/mac80211/ieee80211_i.h
  45. +++ b/net/mac80211/ieee80211_i.h
  46. @@ -218,7 +218,7 @@ enum ieee80211_rx_flags {
  47. };
  48. struct ieee80211_rx_data {
  49. - struct napi_struct *napi;
  50. + struct list_head *list;
  51. struct sk_buff *skb;
  52. struct ieee80211_local *local;
  53. struct ieee80211_sub_if_data *sdata;
  54. --- a/net/mac80211/rx.c
  55. +++ b/net/mac80211/rx.c
  56. @@ -2578,8 +2578,8 @@ static void ieee80211_deliver_skb_to_loc
  57. memset(skb->cb, 0, sizeof(skb->cb));
  58. /* deliver to local stack */
  59. - if (rx->napi)
  60. - napi_gro_receive(rx->napi, skb);
  61. + if (rx->list)
  62. + list_add_tail(&skb->list, rx->list);
  63. else
  64. netif_receive_skb(skb);
  65. }
  66. @@ -3869,7 +3869,6 @@ void ieee80211_release_reorder_timeout(s
  67. /* This is OK -- must be QoS data frame */
  68. .security_idx = tid,
  69. .seqno_idx = tid,
  70. - .napi = NULL, /* must be NULL to not have races */
  71. };
  72. struct tid_ampdu_rx *tid_agg_rx;
  73. @@ -4479,8 +4478,8 @@ static bool ieee80211_invoke_fast_rx(str
  74. /* deliver to local stack */
  75. skb->protocol = eth_type_trans(skb, fast_rx->dev);
  76. memset(skb->cb, 0, sizeof(skb->cb));
  77. - if (rx->napi)
  78. - napi_gro_receive(rx->napi, skb);
  79. + if (rx->list)
  80. + list_add_tail(&skb->list, rx->list);
  81. else
  82. netif_receive_skb(skb);
  83. @@ -4547,7 +4546,7 @@ static bool ieee80211_prepare_and_rx_han
  84. static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
  85. struct ieee80211_sta *pubsta,
  86. struct sk_buff *skb,
  87. - struct napi_struct *napi)
  88. + struct list_head *list)
  89. {
  90. struct ieee80211_local *local = hw_to_local(hw);
  91. struct ieee80211_sub_if_data *sdata;
  92. @@ -4562,7 +4561,7 @@ static void __ieee80211_rx_handle_packet
  93. memset(&rx, 0, sizeof(rx));
  94. rx.skb = skb;
  95. rx.local = local;
  96. - rx.napi = napi;
  97. + rx.list = list;
  98. if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
  99. I802_DEBUG_INC(local->dot11ReceivedFragmentCount);
  100. @@ -4670,8 +4669,8 @@ static void __ieee80211_rx_handle_packet
  101. * This is the receive path handler. It is called by a low level driver when an
  102. * 802.11 MPDU is received from the hardware.
  103. */
  104. -void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
  105. - struct sk_buff *skb, struct napi_struct *napi)
  106. +void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
  107. + struct sk_buff *skb, struct list_head *list)
  108. {
  109. struct ieee80211_local *local = hw_to_local(hw);
  110. struct ieee80211_rate *rate = NULL;
  111. @@ -4763,36 +4762,53 @@ void ieee80211_rx_napi(struct ieee80211_
  112. status->rx_flags = 0;
  113. /*
  114. - * key references and virtual interfaces are protected using RCU
  115. - * and this requires that we are in a read-side RCU section during
  116. - * receive processing
  117. - */
  118. - rcu_read_lock();
  119. -
  120. - /*
  121. * Frames with failed FCS/PLCP checksum are not returned,
  122. * all other frames are returned without radiotap header
  123. * if it was previously present.
  124. * Also, frames with less than 16 bytes are dropped.
  125. */
  126. skb = ieee80211_rx_monitor(local, skb, rate);
  127. - if (!skb) {
  128. - rcu_read_unlock();
  129. + if (!skb)
  130. return;
  131. - }
  132. ieee80211_tpt_led_trig_rx(local,
  133. ((struct ieee80211_hdr *)skb->data)->frame_control,
  134. skb->len);
  135. - __ieee80211_rx_handle_packet(hw, pubsta, skb, napi);
  136. -
  137. - rcu_read_unlock();
  138. + __ieee80211_rx_handle_packet(hw, pubsta, skb, list);
  139. return;
  140. drop:
  141. kfree_skb(skb);
  142. }
  143. +EXPORT_SYMBOL(ieee80211_rx_list);
  144. +
  145. +void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
  146. + struct sk_buff *skb, struct napi_struct *napi)
  147. +{
  148. + struct sk_buff *tmp;
  149. + LIST_HEAD(list);
  150. +
  151. +
  152. + /*
  153. + * key references and virtual interfaces are protected using RCU
  154. + * and this requires that we are in a read-side RCU section during
  155. + * receive processing
  156. + */
  157. + rcu_read_lock();
  158. + ieee80211_rx_list(hw, pubsta, skb, &list);
  159. + rcu_read_unlock();
  160. +
  161. + if (!napi) {
  162. + netif_receive_skb_list(&list);
  163. + return;
  164. + }
  165. +
  166. + list_for_each_entry_safe(skb, tmp, &list, list) {
  167. + skb_list_del_init(skb);
  168. + napi_gro_receive(napi, skb);
  169. + }
  170. +}
  171. EXPORT_SYMBOL(ieee80211_rx_napi);
  172. /* This is a version of the rx handler that can be called from hard irq