lkml.org 
[lkml]   [2020]   [Nov]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V2 net-next 05/11] net: hns3: add support for dynamic interrupt moderation
    Date
    Add dynamic interrupt moderation support for the HNS3 driver.

    Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
    ---
    drivers/net/ethernet/hisilicon/Kconfig | 1 +
    drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 87 ++++++++++++++++++++++++-
    drivers/net/ethernet/hisilicon/hns3/hns3_enet.h | 4 ++
    3 files changed, 91 insertions(+), 1 deletion(-)

    diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/hisilicon/Kconfig
    index 44f9279..fa6025d 100644
    --- a/drivers/net/ethernet/hisilicon/Kconfig
    +++ b/drivers/net/ethernet/hisilicon/Kconfig
    @@ -130,6 +130,7 @@ config HNS3_ENET
    default m
    depends on 64BIT && PCI
    depends on INET
    + select DIMLIB
    help
    This selects the Ethernet Driver for Hisilicon Network Subsystem 3 for hip08
    family of SoCs. This module depends upon HNAE3 driver to access the HNAE3
    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
    index 999a2aa..9e895b9 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
    @@ -96,6 +96,7 @@ static irqreturn_t hns3_irq_handle(int irq, void *vector)
    struct hns3_enet_tqp_vector *tqp_vector = vector;

    napi_schedule_irqoff(&tqp_vector->napi);
    + tqp_vector->event_cnt++;

    return IRQ_HANDLED;
    }
    @@ -199,6 +200,8 @@ static void hns3_vector_disable(struct hns3_enet_tqp_vector *tqp_vector)

    disable_irq(tqp_vector->vector_irq);
    napi_disable(&tqp_vector->napi);
    + cancel_work_sync(&tqp_vector->rx_group.dim.work);
    + cancel_work_sync(&tqp_vector->tx_group.dim.work);
    }

    void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
    @@ -3401,6 +3404,32 @@ static void hns3_update_new_int_gl(struct hns3_enet_tqp_vector *tqp_vector)
    tqp_vector->last_jiffies = jiffies;
    }

    +static void hns3_update_rx_int_coalesce(struct hns3_enet_tqp_vector *tqp_vector)
    +{
    + struct hns3_enet_ring_group *rx_group = &tqp_vector->rx_group;
    + struct dim_sample sample = {};
    +
    + if (!rx_group->coal.adapt_enable)
    + return;
    +
    + dim_update_sample(tqp_vector->event_cnt, rx_group->total_packets,
    + rx_group->total_bytes, &sample);
    + net_dim(&rx_group->dim, sample);
    +}
    +
    +static void hns3_update_tx_int_coalesce(struct hns3_enet_tqp_vector *tqp_vector)
    +{
    + struct hns3_enet_ring_group *tx_group = &tqp_vector->tx_group;
    + struct dim_sample sample = {};
    +
    + if (!tx_group->coal.adapt_enable)
    + return;
    +
    + dim_update_sample(tqp_vector->event_cnt, tx_group->total_packets,
    + tx_group->total_bytes, &sample);
    + net_dim(&tx_group->dim, sample);
    +}
    +
    static int hns3_nic_common_poll(struct napi_struct *napi, int budget)
    {
    struct hns3_nic_priv *priv = netdev_priv(napi->dev);
    @@ -3444,7 +3473,13 @@ static int hns3_nic_common_poll(struct napi_struct *napi, int budget)

    if (napi_complete(napi) &&
    likely(!test_bit(HNS3_NIC_STATE_DOWN, &priv->state))) {
    - hns3_update_new_int_gl(tqp_vector);
    + if (test_bit(HNS3_NIC_STATE_DIM_ENABLE, &priv->state)) {
    + hns3_update_rx_int_coalesce(tqp_vector);
    + hns3_update_tx_int_coalesce(tqp_vector);
    + } else {
    + hns3_update_new_int_gl(tqp_vector);
    + }
    +
    hns3_mask_vector_irq(tqp_vector, 1);
    }

    @@ -3575,6 +3610,54 @@ static void hns3_nic_set_cpumask(struct hns3_nic_priv *priv)
    }
    }

    +static void hns3_rx_dim_work(struct work_struct *work)
    +{
    + struct dim *dim = container_of(work, struct dim, work);
    + struct hns3_enet_ring_group *group = container_of(dim,
    + struct hns3_enet_ring_group, dim);
    + struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
    + struct dim_cq_moder cur_moder =
    + net_dim_get_rx_moderation(dim->mode, dim->profile_ix);
    +
    + hns3_set_vector_coalesce_rx_gl(group->ring->tqp_vector, cur_moder.usec);
    + tqp_vector->rx_group.coal.int_gl = cur_moder.usec;
    +
    + if (cur_moder.pkts < tqp_vector->rx_group.coal.int_ql_max) {
    + hns3_set_vector_coalesce_rx_ql(tqp_vector, cur_moder.pkts);
    + tqp_vector->rx_group.coal.int_ql = cur_moder.pkts;
    + }
    +
    + dim->state = DIM_START_MEASURE;
    +}
    +
    +static void hns3_tx_dim_work(struct work_struct *work)
    +{
    + struct dim *dim = container_of(work, struct dim, work);
    + struct hns3_enet_ring_group *group = container_of(dim,
    + struct hns3_enet_ring_group, dim);
    + struct hns3_enet_tqp_vector *tqp_vector = group->ring->tqp_vector;
    + struct dim_cq_moder cur_moder =
    + net_dim_get_tx_moderation(dim->mode, dim->profile_ix);
    +
    + hns3_set_vector_coalesce_tx_gl(tqp_vector, cur_moder.usec);
    + tqp_vector->tx_group.coal.int_gl = cur_moder.usec;
    +
    + if (cur_moder.pkts < tqp_vector->tx_group.coal.int_ql_max) {
    + hns3_set_vector_coalesce_tx_ql(tqp_vector, cur_moder.pkts);
    + tqp_vector->tx_group.coal.int_ql = cur_moder.pkts;
    + }
    +
    + dim->state = DIM_START_MEASURE;
    +}
    +
    +static void hns3_nic_init_dim(struct hns3_enet_tqp_vector *tqp_vector)
    +{
    + INIT_WORK(&tqp_vector->rx_group.dim.work, hns3_rx_dim_work);
    + tqp_vector->rx_group.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
    + INIT_WORK(&tqp_vector->tx_group.dim.work, hns3_tx_dim_work);
    + tqp_vector->tx_group.dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
    +}
    +
    static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
    {
    struct hnae3_ring_chain_node vector_ring_chain;
    @@ -3589,6 +3672,7 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
    tqp_vector = &priv->tqp_vector[i];
    hns3_vector_coalesce_init_hw(tqp_vector, priv);
    tqp_vector->num_tqps = 0;
    + hns3_nic_init_dim(tqp_vector);
    }

    for (i = 0; i < h->kinfo.num_tqps; i++) {
    @@ -4161,6 +4245,7 @@ static int hns3_client_init(struct hnae3_handle *handle)
    netdev->max_mtu = HNS3_MAX_MTU;

    set_bit(HNS3_NIC_STATE_INITED, &priv->state);
    + set_bit(HNS3_NIC_STATE_DIM_ENABLE, &priv->state);

    if (netif_msg_drv(handle))
    hns3_info_show(priv);
    diff --git a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
    index 8d33652..eb4e7ef 100644
    --- a/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
    +++ b/drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
    @@ -4,6 +4,7 @@
    #ifndef __HNS3_ENET_H
    #define __HNS3_ENET_H

    +#include <linux/dim.h>
    #include <linux/if_vlan.h>

    #include "hnae3.h"
    @@ -18,6 +19,7 @@ enum hns3_nic_state {
    HNS3_NIC_STATE_SERVICE_INITED,
    HNS3_NIC_STATE_SERVICE_SCHED,
    HNS3_NIC_STATE2_RESET_REQUESTED,
    + HNS3_NIC_STATE_DIM_ENABLE,
    HNS3_NIC_STATE_MAX
    };

    @@ -449,6 +451,7 @@ struct hns3_enet_ring_group {
    u64 total_packets; /* total packets processed this group */
    u16 count;
    struct hns3_enet_coalesce coal;
    + struct dim dim;
    };

    struct hns3_enet_tqp_vector {
    @@ -471,6 +474,7 @@ struct hns3_enet_tqp_vector {
    char name[HNAE3_INT_NAME_LEN];

    unsigned long last_jiffies;
    + u64 event_cnt;
    } ____cacheline_internodealigned_in_smp;

    struct hns3_nic_priv {
    --
    2.7.4
    \
     
     \ /
      Last update: 2020-11-09 04:24    [W:4.312 / U:0.152 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site