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