diff options
| author | Amir Vadai <amirv@mellanox.com> | 2014-07-08 04:28:12 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-07-08 23:00:49 -0400 |
| commit | fbc6daf19745b372c0d909e5d74ab02e42b70e51 (patch) | |
| tree | 261af07430baed5f056fde747f73e9f9879bf02c | |
| parent | 0b0302449110ca5ca4350458ed57b971fcb78ec1 (diff) | |
net/mlx4_en: Ignore budget on TX napi polling
It is recommended that TX work not count against the quota.
The cost of TX packet liberation is a minute percentage of what it costs to
process an RX frame. Furthermore, that SKB freeing makes memory available for
other paths in the stack.
Give the TX a larger budget and be more aggressive about cleaning up the Tx
descriptors this budget could be changed using ethtool:
$ ethtool -C eth1 tx-frames-irq <budget>
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 7 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_tx.c | 28 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 3 |
4 files changed, 24 insertions, 15 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c index fa1a069e14e6..68d763d2d030 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | |||
| @@ -417,6 +417,8 @@ static int mlx4_en_get_coalesce(struct net_device *dev, | |||
| 417 | 417 | ||
| 418 | coal->tx_coalesce_usecs = priv->tx_usecs; | 418 | coal->tx_coalesce_usecs = priv->tx_usecs; |
| 419 | coal->tx_max_coalesced_frames = priv->tx_frames; | 419 | coal->tx_max_coalesced_frames = priv->tx_frames; |
| 420 | coal->tx_max_coalesced_frames_irq = priv->tx_work_limit; | ||
| 421 | |||
| 420 | coal->rx_coalesce_usecs = priv->rx_usecs; | 422 | coal->rx_coalesce_usecs = priv->rx_usecs; |
| 421 | coal->rx_max_coalesced_frames = priv->rx_frames; | 423 | coal->rx_max_coalesced_frames = priv->rx_frames; |
| 422 | 424 | ||
| @@ -426,6 +428,7 @@ static int mlx4_en_get_coalesce(struct net_device *dev, | |||
| 426 | coal->rx_coalesce_usecs_high = priv->rx_usecs_high; | 428 | coal->rx_coalesce_usecs_high = priv->rx_usecs_high; |
| 427 | coal->rate_sample_interval = priv->sample_interval; | 429 | coal->rate_sample_interval = priv->sample_interval; |
| 428 | coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal; | 430 | coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal; |
| 431 | |||
| 429 | return 0; | 432 | return 0; |
| 430 | } | 433 | } |
| 431 | 434 | ||
| @@ -434,6 +437,9 @@ static int mlx4_en_set_coalesce(struct net_device *dev, | |||
| 434 | { | 437 | { |
| 435 | struct mlx4_en_priv *priv = netdev_priv(dev); | 438 | struct mlx4_en_priv *priv = netdev_priv(dev); |
| 436 | 439 | ||
| 440 | if (!coal->tx_max_coalesced_frames_irq) | ||
| 441 | return -EINVAL; | ||
| 442 | |||
| 437 | priv->rx_frames = (coal->rx_max_coalesced_frames == | 443 | priv->rx_frames = (coal->rx_max_coalesced_frames == |
| 438 | MLX4_EN_AUTO_CONF) ? | 444 | MLX4_EN_AUTO_CONF) ? |
| 439 | MLX4_EN_RX_COAL_TARGET : | 445 | MLX4_EN_RX_COAL_TARGET : |
| @@ -457,6 +463,7 @@ static int mlx4_en_set_coalesce(struct net_device *dev, | |||
| 457 | priv->rx_usecs_high = coal->rx_coalesce_usecs_high; | 463 | priv->rx_usecs_high = coal->rx_coalesce_usecs_high; |
| 458 | priv->sample_interval = coal->rate_sample_interval; | 464 | priv->sample_interval = coal->rate_sample_interval; |
| 459 | priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce; | 465 | priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce; |
| 466 | priv->tx_work_limit = coal->tx_max_coalesced_frames_irq; | ||
| 460 | 467 | ||
| 461 | return mlx4_en_moderation_update(priv); | 468 | return mlx4_en_moderation_update(priv); |
| 462 | } | 469 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index e94d96f0ef55..7345c43b019e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c | |||
| @@ -2473,6 +2473,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, | |||
| 2473 | MLX4_WQE_CTRL_SOLICITED); | 2473 | MLX4_WQE_CTRL_SOLICITED); |
| 2474 | priv->num_tx_rings_p_up = mdev->profile.num_tx_rings_p_up; | 2474 | priv->num_tx_rings_p_up = mdev->profile.num_tx_rings_p_up; |
| 2475 | priv->tx_ring_num = prof->tx_ring_num; | 2475 | priv->tx_ring_num = prof->tx_ring_num; |
| 2476 | priv->tx_work_limit = MLX4_EN_DEFAULT_TX_WORK; | ||
| 2476 | 2477 | ||
| 2477 | priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring *) * MAX_TX_RINGS, | 2478 | priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring *) * MAX_TX_RINGS, |
| 2478 | GFP_KERNEL); | 2479 | GFP_KERNEL); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index ac3dead3792c..5045bab59633 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
| @@ -351,9 +351,8 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring) | |||
| 351 | return cnt; | 351 | return cnt; |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | static int mlx4_en_process_tx_cq(struct net_device *dev, | 354 | static bool mlx4_en_process_tx_cq(struct net_device *dev, |
| 355 | struct mlx4_en_cq *cq, | 355 | struct mlx4_en_cq *cq) |
| 356 | int budget) | ||
| 357 | { | 356 | { |
| 358 | struct mlx4_en_priv *priv = netdev_priv(dev); | 357 | struct mlx4_en_priv *priv = netdev_priv(dev); |
| 359 | struct mlx4_cq *mcq = &cq->mcq; | 358 | struct mlx4_cq *mcq = &cq->mcq; |
| @@ -372,9 +371,10 @@ static int mlx4_en_process_tx_cq(struct net_device *dev, | |||
| 372 | int factor = priv->cqe_factor; | 371 | int factor = priv->cqe_factor; |
| 373 | u64 timestamp = 0; | 372 | u64 timestamp = 0; |
| 374 | int done = 0; | 373 | int done = 0; |
| 374 | int budget = priv->tx_work_limit; | ||
| 375 | 375 | ||
| 376 | if (!priv->port_up) | 376 | if (!priv->port_up) |
| 377 | return 0; | 377 | return true; |
| 378 | 378 | ||
| 379 | index = cons_index & size_mask; | 379 | index = cons_index & size_mask; |
| 380 | cqe = &buf[(index << factor) + factor]; | 380 | cqe = &buf[(index << factor) + factor]; |
| @@ -447,7 +447,7 @@ static int mlx4_en_process_tx_cq(struct net_device *dev, | |||
| 447 | netif_tx_wake_queue(ring->tx_queue); | 447 | netif_tx_wake_queue(ring->tx_queue); |
| 448 | ring->wake_queue++; | 448 | ring->wake_queue++; |
| 449 | } | 449 | } |
| 450 | return done; | 450 | return done < budget; |
| 451 | } | 451 | } |
| 452 | 452 | ||
| 453 | void mlx4_en_tx_irq(struct mlx4_cq *mcq) | 453 | void mlx4_en_tx_irq(struct mlx4_cq *mcq) |
| @@ -467,18 +467,16 @@ int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget) | |||
| 467 | struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi); | 467 | struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi); |
| 468 | struct net_device *dev = cq->dev; | 468 | struct net_device *dev = cq->dev; |
| 469 | struct mlx4_en_priv *priv = netdev_priv(dev); | 469 | struct mlx4_en_priv *priv = netdev_priv(dev); |
| 470 | int done; | 470 | int clean_complete; |
| 471 | 471 | ||
| 472 | done = mlx4_en_process_tx_cq(dev, cq, budget); | 472 | clean_complete = mlx4_en_process_tx_cq(dev, cq); |
| 473 | if (!clean_complete) | ||
| 474 | return budget; | ||
| 473 | 475 | ||
| 474 | /* If we used up all the quota - we're probably not done yet... */ | 476 | napi_complete(napi); |
| 475 | if (done < budget) { | 477 | mlx4_en_arm_cq(priv, cq); |
| 476 | /* Done for now */ | 478 | |
| 477 | napi_complete(napi); | 479 | return 0; |
| 478 | mlx4_en_arm_cq(priv, cq); | ||
| 479 | return done; | ||
| 480 | } | ||
| 481 | return budget; | ||
| 482 | } | 480 | } |
| 483 | 481 | ||
| 484 | static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv, | 482 | static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 624e1939e9ee..d72a5a894fc6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | |||
| @@ -126,6 +126,8 @@ enum { | |||
| 126 | #define MAX_TX_RINGS (MLX4_EN_MAX_TX_RING_P_UP * \ | 126 | #define MAX_TX_RINGS (MLX4_EN_MAX_TX_RING_P_UP * \ |
| 127 | MLX4_EN_NUM_UP) | 127 | MLX4_EN_NUM_UP) |
| 128 | 128 | ||
| 129 | #define MLX4_EN_DEFAULT_TX_WORK 256 | ||
| 130 | |||
| 129 | /* Target number of packets to coalesce with interrupt moderation */ | 131 | /* Target number of packets to coalesce with interrupt moderation */ |
| 130 | #define MLX4_EN_RX_COAL_TARGET 44 | 132 | #define MLX4_EN_RX_COAL_TARGET 44 |
| 131 | #define MLX4_EN_RX_COAL_TIME 0x10 | 133 | #define MLX4_EN_RX_COAL_TIME 0x10 |
| @@ -543,6 +545,7 @@ struct mlx4_en_priv { | |||
| 543 | __be32 ctrl_flags; | 545 | __be32 ctrl_flags; |
| 544 | u32 flags; | 546 | u32 flags; |
| 545 | u8 num_tx_rings_p_up; | 547 | u8 num_tx_rings_p_up; |
| 548 | u32 tx_work_limit; | ||
| 546 | u32 tx_ring_num; | 549 | u32 tx_ring_num; |
| 547 | u32 rx_ring_num; | 550 | u32 rx_ring_num; |
| 548 | u32 rx_skb_size; | 551 | u32 rx_skb_size; |
