lkml.org 
[lkml]   [2020]   [May]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.6 013/118] cxgb4: fix EOTID leak when disabling TC-MQPRIO offload
    Date
    From: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>

    [ Upstream commit 69422a7e5d578aab277091f4ebb7c1b387f3e355 ]

    Under heavy load, the EOTID termination FLOWC request fails to get
    enqueued to the end of the Tx ring due to lack of credits. This
    results in EOTID leak.

    When disabling TC-MQPRIO offload, the link is already brought down
    to cleanup EOTIDs. So, flush any pending enqueued skbs that can't be
    sent outside the wire, to make room for FLOWC request. Also, move the
    FLOWC descriptor consumption logic closer to when the FLOWC request is
    actually posted to hardware.

    Fixes: 0e395b3cb1fb ("cxgb4: add FLOWC based QoS offload")
    Signed-off-by: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/ethernet/chelsio/cxgb4/sge.c | 39 ++++++++++++++++++++++++++++---
    1 file changed, 36 insertions(+), 3 deletions(-)

    --- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
    +++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
    @@ -2202,6 +2202,9 @@ static void ethofld_hard_xmit(struct net
    if (unlikely(skip_eotx_wr)) {
    start = (u64 *)wr;
    eosw_txq->state = next_state;
    + eosw_txq->cred -= wrlen16;
    + eosw_txq->ncompl++;
    + eosw_txq->last_compl = 0;
    goto write_wr_headers;
    }

    @@ -2360,6 +2363,34 @@ netdev_tx_t t4_start_xmit(struct sk_buff
    return cxgb4_eth_xmit(skb, dev);
    }

    +static void eosw_txq_flush_pending_skbs(struct sge_eosw_txq *eosw_txq)
    +{
    + int pktcount = eosw_txq->pidx - eosw_txq->last_pidx;
    + int pidx = eosw_txq->pidx;
    + struct sk_buff *skb;
    +
    + if (!pktcount)
    + return;
    +
    + if (pktcount < 0)
    + pktcount += eosw_txq->ndesc;
    +
    + while (pktcount--) {
    + pidx--;
    + if (pidx < 0)
    + pidx += eosw_txq->ndesc;
    +
    + skb = eosw_txq->desc[pidx].skb;
    + if (skb) {
    + dev_consume_skb_any(skb);
    + eosw_txq->desc[pidx].skb = NULL;
    + eosw_txq->inuse--;
    + }
    + }
    +
    + eosw_txq->pidx = eosw_txq->last_pidx + 1;
    +}
    +
    /**
    * cxgb4_ethofld_send_flowc - Send ETHOFLD flowc request to bind eotid to tc.
    * @dev - netdevice
    @@ -2435,9 +2466,11 @@ int cxgb4_ethofld_send_flowc(struct net_
    FW_FLOWC_MNEM_EOSTATE_CLOSING :
    FW_FLOWC_MNEM_EOSTATE_ESTABLISHED);

    - eosw_txq->cred -= len16;
    - eosw_txq->ncompl++;
    - eosw_txq->last_compl = 0;
    + /* Free up any pending skbs to ensure there's room for
    + * termination FLOWC.
    + */
    + if (tc == FW_SCHED_CLS_NONE)
    + eosw_txq_flush_pending_skbs(eosw_txq);

    ret = eosw_txq_enqueue(eosw_txq, skb);
    if (ret) {

    \
     
     \ /
      Last update: 2020-05-13 12:10    [W:4.104 / U:1.200 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site