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 /drivers/net/ethernet/mellanox | |
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>
Diffstat (limited to 'drivers/net/ethernet/mellanox')
-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; |