360-mac80211-when-using-iTXQ-select-the-queue-in-ieee802.patch 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. From: Felix Fietkau <nbd@nbd.name>
  2. Date: Fri, 22 Mar 2019 18:06:03 +0100
  3. Subject: [PATCH] mac80211: when using iTXQ, select the queue in
  4. ieee80211_subif_start_xmit
  5. When using iTXQ, the network stack does not need the real queue number, since
  6. mac80211 is using its internal queues anyway. In that case we can defer
  7. selecting the queue and remove a redundant station lookup in the tx path to save
  8. some CPU cycles.
  9. Signed-off-by: Felix Fietkau <nbd@nbd.name>
  10. ---
  11. --- a/net/mac80211/tx.c
  12. +++ b/net/mac80211/tx.c
  13. @@ -3772,6 +3772,7 @@ void __ieee80211_subif_start_xmit(struct
  14. u32 ctrl_flags)
  15. {
  16. struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
  17. + struct ieee80211_local *local = sdata->local;
  18. struct sta_info *sta;
  19. struct sk_buff *next;
  20. @@ -3785,7 +3786,15 @@ void __ieee80211_subif_start_xmit(struct
  21. if (ieee80211_lookup_ra_sta(sdata, skb, &sta))
  22. goto out_free;
  23. - if (!IS_ERR_OR_NULL(sta)) {
  24. + if (IS_ERR(sta))
  25. + sta = NULL;
  26. +
  27. + if (local->ops->wake_tx_queue) {
  28. + u16 queue = __ieee80211_select_queue(sdata, sta, skb);
  29. + skb_set_queue_mapping(skb, queue);
  30. + }
  31. +
  32. + if (sta) {
  33. struct ieee80211_fast_tx *fast_tx;
  34. /* We need a bit of data queued to build aggregates properly, so
  35. --- a/net/mac80211/wme.c
  36. +++ b/net/mac80211/wme.c
  37. @@ -141,6 +141,42 @@ u16 ieee80211_select_queue_80211(struct
  38. return ieee80211_downgrade_queue(sdata, NULL, skb);
  39. }
  40. +u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
  41. + struct sta_info *sta, struct sk_buff *skb)
  42. +{
  43. + struct mac80211_qos_map *qos_map;
  44. + bool qos;
  45. +
  46. + /* all mesh/ocb stations are required to support WME */
  47. + if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
  48. + sdata->vif.type == NL80211_IFTYPE_OCB)
  49. + qos = true;
  50. + else if (sta)
  51. + qos = sta->sta.wme;
  52. + else
  53. + qos = false;
  54. +
  55. + if (!qos) {
  56. + skb->priority = 0; /* required for correct WPA/11i MIC */
  57. + return IEEE80211_AC_BE;
  58. + }
  59. +
  60. + if (skb->protocol == sdata->control_port_protocol) {
  61. + skb->priority = 7;
  62. + goto downgrade;
  63. + }
  64. +
  65. + /* use the data classifier to determine what 802.1d tag the
  66. + * data frame has */
  67. + qos_map = rcu_dereference(sdata->qos_map);
  68. + skb->priority = cfg80211_classify8021d(skb, qos_map ?
  69. + &qos_map->qos_map : NULL);
  70. +
  71. + downgrade:
  72. + return ieee80211_downgrade_queue(sdata, sta, skb);
  73. +}
  74. +
  75. +
  76. /* Indicate which queue to use. */
  77. u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
  78. struct sk_buff *skb)
  79. @@ -148,10 +184,12 @@ u16 ieee80211_select_queue(struct ieee80
  80. struct ieee80211_local *local = sdata->local;
  81. struct sta_info *sta = NULL;
  82. const u8 *ra = NULL;
  83. - bool qos = false;
  84. - struct mac80211_qos_map *qos_map;
  85. u16 ret;
  86. + /* when using iTXQ, we can do this later */
  87. + if (local->ops->wake_tx_queue)
  88. + return 0;
  89. +
  90. if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) {
  91. skb->priority = 0; /* required for correct WPA/11i MIC */
  92. return 0;
  93. @@ -161,10 +199,8 @@ u16 ieee80211_select_queue(struct ieee80
  94. switch (sdata->vif.type) {
  95. case NL80211_IFTYPE_AP_VLAN:
  96. sta = rcu_dereference(sdata->u.vlan.sta);
  97. - if (sta) {
  98. - qos = sta->sta.wme;
  99. + if (sta)
  100. break;
  101. - }
  102. /* fall through */
  103. case NL80211_IFTYPE_AP:
  104. ra = skb->data;
  105. @@ -172,56 +208,26 @@ u16 ieee80211_select_queue(struct ieee80
  106. case NL80211_IFTYPE_WDS:
  107. ra = sdata->u.wds.remote_addr;
  108. break;
  109. -#ifdef CPTCFG_MAC80211_MESH
  110. - case NL80211_IFTYPE_MESH_POINT:
  111. - qos = true;
  112. - break;
  113. -#endif
  114. case NL80211_IFTYPE_STATION:
  115. /* might be a TDLS station */
  116. sta = sta_info_get(sdata, skb->data);
  117. if (sta)
  118. - qos = sta->sta.wme;
  119. + break;
  120. ra = sdata->u.mgd.bssid;
  121. break;
  122. case NL80211_IFTYPE_ADHOC:
  123. ra = skb->data;
  124. break;
  125. - case NL80211_IFTYPE_OCB:
  126. - /* all stations are required to support WME */
  127. - qos = true;
  128. - break;
  129. default:
  130. break;
  131. }
  132. - if (!sta && ra && !is_multicast_ether_addr(ra)) {
  133. + if (!sta && ra && !is_multicast_ether_addr(ra))
  134. sta = sta_info_get(sdata, ra);
  135. - if (sta)
  136. - qos = sta->sta.wme;
  137. - }
  138. - if (!qos) {
  139. - skb->priority = 0; /* required for correct WPA/11i MIC */
  140. - ret = IEEE80211_AC_BE;
  141. - goto out;
  142. - }
  143. + ret = __ieee80211_select_queue(sdata, sta, skb);
  144. - if (skb->protocol == sdata->control_port_protocol) {
  145. - skb->priority = 7;
  146. - goto downgrade;
  147. - }
  148. -
  149. - /* use the data classifier to determine what 802.1d tag the
  150. - * data frame has */
  151. - qos_map = rcu_dereference(sdata->qos_map);
  152. - skb->priority = cfg80211_classify8021d(skb, qos_map ?
  153. - &qos_map->qos_map : NULL);
  154. -
  155. - downgrade:
  156. - ret = ieee80211_downgrade_queue(sdata, sta, skb);
  157. - out:
  158. rcu_read_unlock();
  159. return ret;
  160. }
  161. --- a/net/mac80211/wme.h
  162. +++ b/net/mac80211/wme.h
  163. @@ -16,6 +16,8 @@
  164. u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata,
  165. struct sk_buff *skb,
  166. struct ieee80211_hdr *hdr);
  167. +u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
  168. + struct sta_info *sta, struct sk_buff *skb);
  169. u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
  170. struct sk_buff *skb);
  171. void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata,