Rajkumar Manoharan <rmano...@codeaurora.org> writes:

> Once a txq is selected for transmission by next_txq(), all data from
> txq are dequeued by driver till hardware descriptors are drained.
> i.e the driver is still allowed to dequeue frames from txq even when
> its fairness deficit goes negative during transmission. This breaks
> fairness and also cause inefficient fq-codel in mac80211 when data
> queues are maintained in driver/firmware. To address this problem,
> pause txq transmission immediately upon driver airtime report.

Hmm, interesting observation about the queues moving to mac80211. Not
sure it will actually work that way; depends on how timely the ath10k
airtime report is, I guess. But would be interesting to test! :)

Just one comment on your patch, below.

> +static bool ieee80211_txq_requeued(struct ieee80211_local *local,
> +                                struct txq_info *txqi)
> +{
> +     struct sta_info *sta;
> +
> +     lockdep_assert_held(&local->active_txq_lock);
> +
> +     if (!txqi->txq.sta)
> +             return false;
> +
> +     sta = container_of(txqi->txq.sta, struct sta_info, sta);
> +
> +     if (sta->airtime.deficit[txqi->txq.ac] > 0) {
> +             clear_bit(IEEE80211_TXQ_PAUSE, &txqi->flags);
> +             return false;
> +     }
> +
> +     sta->airtime.deficit[txqi->txq.ac] +=
> +             local->airtime_quantum * sta->airtime.weight;
> +     list_move_tail(&txqi->schedule_order,
> +                    &local->active_txqs[txqi->txq.ac]);
> +
> +     return true;
> +}
> +
>  struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, s8 ac,
>                                        bool inc_seqno)
>  {
> @@ -3655,18 +3682,8 @@ struct ieee80211_txq *ieee80211_next_txq(struct 
> ieee80211_hw *hw, s8 ac,
>       if (!txqi)
>               goto out;
>  
> -     if (txqi->txq.sta) {
> -             struct sta_info *sta = container_of(txqi->txq.sta,
> -                                             struct sta_info, sta);
> -
> -             if (sta->airtime.deficit[txqi->txq.ac] < 0) {
> -                     sta->airtime.deficit[txqi->txq.ac] +=
> -                             local->airtime_quantum * sta->airtime.weight;
> -                     list_move_tail(&txqi->schedule_order,
> -                                    &local->active_txqs[txqi->txq.ac]);
> -                     goto begin;
> -             }
> -     }
> +     if (ieee80211_txq_requeued(local, txqi))
> +             goto begin;
>  
>       /* If seqnos are equal, we've seen this txqi before in this scheduling
>        * round, so abort.
> @@ -3687,6 +3704,39 @@ struct ieee80211_txq *ieee80211_next_txq(struct 
> ieee80211_hw *hw, s8 ac,
>  }
>  EXPORT_SYMBOL(ieee80211_next_txq);
>  
> +bool ieee80211_txq_can_transmit(struct ieee80211_hw *hw,
> +                             struct ieee80211_txq *txq)
> +{
> +     struct ieee80211_local *local = hw_to_local(hw);
> +     struct txq_info *txqi, *f_txqi;
> +     bool can_tx;
> +
> +     txqi = to_txq_info(txq);
> +     /* Check whether txq is paused or not */
> +     if (test_bit(IEEE80211_TXQ_PAUSE, &txqi->flags))
> +             return false;
> +
> +     can_tx = false;
> +     spin_lock_bh(&local->active_txq_lock);
> +     f_txqi = find_txqi(local, txq->ac);
> +     if (!f_txqi)
> +             goto out;
> +
> +     /* Allow only head node to ensure fairness */
> +     if (f_txqi != txqi)
> +             goto out;
> +
> +     /* Check if txq is in negative deficit */
> +     if (!ieee80211_txq_requeued(local, txqi))
> +             can_tx = true;
> +
> +     list_del_init(&txqi->schedule_order);

Why are you removing the txq from the list here, and how do you expect
it to get added back?

-Toke

Reply via email to