Skip to content

Commit

Permalink
net: hns3: fix user's coalesce configuration lost issue
Browse files Browse the repository at this point in the history
Currently, when adaptive is on, the user's coalesce configuration
may be overwritten by the dynamic one. The reason is that user's
configurations are saved in struct hns3_enet_tqp_vector whose
value maybe changed by the dynamic algorithm. To fix it, use
struct hns3_nic_priv instead of struct hns3_enet_tqp_vector to
save and get the user's configuration.

BTW, operations of storing and restoring coalesce info in the reset
process are unnecessary now, so remove them as well.

Fixes: 434776a ("net: hns3: add ethtool_ops.set_coalesce support to PF")
Fixes: 7e96adc ("net: hns3: add ethtool_ops.get_coalesce support to PF")
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Huazhong Tan authored and davem330 committed May 18, 2021
1 parent a289a7e commit 73a13d8
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 85 deletions.
84 changes: 40 additions & 44 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,22 +264,17 @@ static void hns3_vector_coalesce_init(struct hns3_enet_tqp_vector *tqp_vector,
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
struct hns3_enet_coalesce *tx_coal = &tqp_vector->tx_group.coal;
struct hns3_enet_coalesce *rx_coal = &tqp_vector->rx_group.coal;
struct hns3_enet_coalesce *ptx_coal = &priv->tx_coal;
struct hns3_enet_coalesce *prx_coal = &priv->rx_coal;

/* initialize the configuration for interrupt coalescing.
* 1. GL (Interrupt Gap Limiter)
* 2. RL (Interrupt Rate Limiter)
* 3. QL (Interrupt Quantity Limiter)
*
* Default: enable interrupt coalescing self-adaptive and GL
*/
tx_coal->adapt_enable = 1;
rx_coal->adapt_enable = 1;
tx_coal->adapt_enable = ptx_coal->adapt_enable;
rx_coal->adapt_enable = prx_coal->adapt_enable;

tx_coal->int_gl = HNS3_INT_GL_50K;
rx_coal->int_gl = HNS3_INT_GL_50K;
tx_coal->int_gl = ptx_coal->int_gl;
rx_coal->int_gl = prx_coal->int_gl;

rx_coal->flow_level = HNS3_FLOW_LOW;
tx_coal->flow_level = HNS3_FLOW_LOW;
rx_coal->flow_level = prx_coal->flow_level;
tx_coal->flow_level = ptx_coal->flow_level;

/* device version above V3(include V3), GL can configure 1us
* unit, so uses 1us unit.
Expand All @@ -294,8 +289,8 @@ static void hns3_vector_coalesce_init(struct hns3_enet_tqp_vector *tqp_vector,
rx_coal->ql_enable = 1;
tx_coal->int_ql_max = ae_dev->dev_specs.int_ql_max;
rx_coal->int_ql_max = ae_dev->dev_specs.int_ql_max;
tx_coal->int_ql = HNS3_INT_QL_DEFAULT_CFG;
rx_coal->int_ql = HNS3_INT_QL_DEFAULT_CFG;
tx_coal->int_ql = ptx_coal->int_ql;
rx_coal->int_ql = prx_coal->int_ql;
}
}

Expand Down Expand Up @@ -3844,6 +3839,34 @@ static int hns3_nic_init_vector_data(struct hns3_nic_priv *priv)
return ret;
}

static void hns3_nic_init_coal_cfg(struct hns3_nic_priv *priv)
{
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(priv->ae_handle->pdev);
struct hns3_enet_coalesce *tx_coal = &priv->tx_coal;
struct hns3_enet_coalesce *rx_coal = &priv->rx_coal;

/* initialize the configuration for interrupt coalescing.
* 1. GL (Interrupt Gap Limiter)
* 2. RL (Interrupt Rate Limiter)
* 3. QL (Interrupt Quantity Limiter)
*
* Default: enable interrupt coalescing self-adaptive and GL
*/
tx_coal->adapt_enable = 1;
rx_coal->adapt_enable = 1;

tx_coal->int_gl = HNS3_INT_GL_50K;
rx_coal->int_gl = HNS3_INT_GL_50K;

rx_coal->flow_level = HNS3_FLOW_LOW;
tx_coal->flow_level = HNS3_FLOW_LOW;

if (ae_dev->dev_specs.int_ql_max) {
tx_coal->int_ql = HNS3_INT_QL_DEFAULT_CFG;
rx_coal->int_ql = HNS3_INT_QL_DEFAULT_CFG;
}
}

static int hns3_nic_alloc_vector_data(struct hns3_nic_priv *priv)
{
struct hnae3_handle *h = priv->ae_handle;
Expand Down Expand Up @@ -4295,6 +4318,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
goto out_get_ring_cfg;
}

hns3_nic_init_coal_cfg(priv);

ret = hns3_nic_alloc_vector_data(priv);
if (ret) {
ret = -ENOMEM;
Expand Down Expand Up @@ -4571,31 +4596,6 @@ int hns3_nic_reset_all_ring(struct hnae3_handle *h)
return 0;
}

static void hns3_store_coal(struct hns3_nic_priv *priv)
{
/* ethtool only support setting and querying one coal
* configuration for now, so save the vector 0' coal
* configuration here in order to restore it.
*/
memcpy(&priv->tx_coal, &priv->tqp_vector[0].tx_group.coal,
sizeof(struct hns3_enet_coalesce));
memcpy(&priv->rx_coal, &priv->tqp_vector[0].rx_group.coal,
sizeof(struct hns3_enet_coalesce));
}

static void hns3_restore_coal(struct hns3_nic_priv *priv)
{
u16 vector_num = priv->vector_num;
int i;

for (i = 0; i < vector_num; i++) {
memcpy(&priv->tqp_vector[i].tx_group.coal, &priv->tx_coal,
sizeof(struct hns3_enet_coalesce));
memcpy(&priv->tqp_vector[i].rx_group.coal, &priv->rx_coal,
sizeof(struct hns3_enet_coalesce));
}
}

static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
{
struct hnae3_knic_private_info *kinfo = &handle->kinfo;
Expand Down Expand Up @@ -4654,8 +4654,6 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
if (ret)
goto err_put_ring;

hns3_restore_coal(priv);

ret = hns3_nic_init_vector_data(priv);
if (ret)
goto err_dealloc_vector;
Expand Down Expand Up @@ -4721,8 +4719,6 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)

hns3_nic_uninit_vector_data(priv);

hns3_store_coal(priv);

hns3_nic_dealloc_vector_data(priv);

hns3_uninit_all_ring(priv);
Expand Down
64 changes: 23 additions & 41 deletions drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -1134,50 +1134,32 @@ static void hns3_get_channels(struct net_device *netdev,
h->ae_algo->ops->get_channels(h, ch);
}

static int hns3_get_coalesce_per_queue(struct net_device *netdev, u32 queue,
struct ethtool_coalesce *cmd)
static int hns3_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *cmd)
{
struct hns3_enet_tqp_vector *tx_vector, *rx_vector;
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hns3_enet_coalesce *tx_coal = &priv->tx_coal;
struct hns3_enet_coalesce *rx_coal = &priv->rx_coal;
struct hnae3_handle *h = priv->ae_handle;
u16 queue_num = h->kinfo.num_tqps;

if (hns3_nic_resetting(netdev))
return -EBUSY;

if (queue >= queue_num) {
netdev_err(netdev,
"Invalid queue value %u! Queue max id=%u\n",
queue, queue_num - 1);
return -EINVAL;
}

tx_vector = priv->ring[queue].tqp_vector;
rx_vector = priv->ring[queue_num + queue].tqp_vector;
cmd->use_adaptive_tx_coalesce = tx_coal->adapt_enable;
cmd->use_adaptive_rx_coalesce = rx_coal->adapt_enable;

cmd->use_adaptive_tx_coalesce =
tx_vector->tx_group.coal.adapt_enable;
cmd->use_adaptive_rx_coalesce =
rx_vector->rx_group.coal.adapt_enable;

cmd->tx_coalesce_usecs = tx_vector->tx_group.coal.int_gl;
cmd->rx_coalesce_usecs = rx_vector->rx_group.coal.int_gl;
cmd->tx_coalesce_usecs = tx_coal->int_gl;
cmd->rx_coalesce_usecs = rx_coal->int_gl;

cmd->tx_coalesce_usecs_high = h->kinfo.int_rl_setting;
cmd->rx_coalesce_usecs_high = h->kinfo.int_rl_setting;

cmd->tx_max_coalesced_frames = tx_vector->tx_group.coal.int_ql;
cmd->rx_max_coalesced_frames = rx_vector->rx_group.coal.int_ql;
cmd->tx_max_coalesced_frames = tx_coal->int_ql;
cmd->rx_max_coalesced_frames = rx_coal->int_ql;

return 0;
}

static int hns3_get_coalesce(struct net_device *netdev,
struct ethtool_coalesce *cmd)
{
return hns3_get_coalesce_per_queue(netdev, 0, cmd);
}

static int hns3_check_gl_coalesce_para(struct net_device *netdev,
struct ethtool_coalesce *cmd)
{
Expand Down Expand Up @@ -1292,19 +1274,7 @@ static int hns3_check_coalesce_para(struct net_device *netdev,
return ret;
}

ret = hns3_check_ql_coalesce_param(netdev, cmd);
if (ret)
return ret;

if (cmd->use_adaptive_tx_coalesce == 1 ||
cmd->use_adaptive_rx_coalesce == 1) {
netdev_info(netdev,
"adaptive-tx=%u and adaptive-rx=%u, tx_usecs or rx_usecs will changed dynamically.\n",
cmd->use_adaptive_tx_coalesce,
cmd->use_adaptive_rx_coalesce);
}

return 0;
return hns3_check_ql_coalesce_param(netdev, cmd);
}

static void hns3_set_coalesce_per_queue(struct net_device *netdev,
Expand Down Expand Up @@ -1350,6 +1320,9 @@ static int hns3_set_coalesce(struct net_device *netdev,
struct ethtool_coalesce *cmd)
{
struct hnae3_handle *h = hns3_get_handle(netdev);
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hns3_enet_coalesce *tx_coal = &priv->tx_coal;
struct hns3_enet_coalesce *rx_coal = &priv->rx_coal;
u16 queue_num = h->kinfo.num_tqps;
int ret;
int i;
Expand All @@ -1364,6 +1337,15 @@ static int hns3_set_coalesce(struct net_device *netdev,
h->kinfo.int_rl_setting =
hns3_rl_round_down(cmd->rx_coalesce_usecs_high);

tx_coal->adapt_enable = cmd->use_adaptive_tx_coalesce;
rx_coal->adapt_enable = cmd->use_adaptive_rx_coalesce;

tx_coal->int_gl = cmd->tx_coalesce_usecs;
rx_coal->int_gl = cmd->rx_coalesce_usecs;

tx_coal->int_ql = cmd->tx_max_coalesced_frames;
rx_coal->int_ql = cmd->rx_max_coalesced_frames;

for (i = 0; i < queue_num; i++)
hns3_set_coalesce_per_queue(netdev, cmd, i);

Expand Down

0 comments on commit 73a13d8

Please sign in to comment.