diff options
author | Eric Dumazet <edumazet@google.com> | 2014-09-25 10:17:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-09-28 17:27:36 -0400 |
commit | 5804283d7cb1da46485950d545dd7869137dcda5 (patch) | |
tree | ba4656cb940b502838058edbf81d15cf147d0171 | |
parent | a8404ce5ae7a6054322afb5aa77cefe3ad54475e (diff) |
mlx4: exploit skb->xmit_more to conditionally send doorbell
skb->xmit_more tells us if another skb is coming next.
We need to send doorbell when : xmit_more is not set,
or txqueue is stopped (preventing next skb to come immediately)
Tested with a modified pktgen version, I got a 40% increase of
throughput.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx4/en_tx.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index c44f4237b9be..adedc47e947d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c | |||
@@ -667,6 +667,7 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
667 | int lso_header_size; | 667 | int lso_header_size; |
668 | void *fragptr; | 668 | void *fragptr; |
669 | bool bounce = false; | 669 | bool bounce = false; |
670 | bool send_doorbell; | ||
670 | 671 | ||
671 | if (!priv->port_up) | 672 | if (!priv->port_up) |
672 | goto tx_drop; | 673 | goto tx_drop; |
@@ -878,12 +879,16 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
878 | 879 | ||
879 | skb_tx_timestamp(skb); | 880 | skb_tx_timestamp(skb); |
880 | 881 | ||
881 | if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && !vlan_tx_tag_present(skb)) { | 882 | send_doorbell = !skb->xmit_more || netif_xmit_stopped(ring->tx_queue); |
883 | |||
884 | if (ring->bf_enabled && desc_size <= MAX_BF && !bounce && | ||
885 | !vlan_tx_tag_present(skb) && send_doorbell) { | ||
882 | tx_desc->ctrl.bf_qpn |= cpu_to_be32(ring->doorbell_qpn); | 886 | tx_desc->ctrl.bf_qpn |= cpu_to_be32(ring->doorbell_qpn); |
883 | 887 | ||
884 | op_own |= htonl((bf_index & 0xffff) << 8); | 888 | op_own |= htonl((bf_index & 0xffff) << 8); |
885 | /* Ensure new descirptor hits memory | 889 | /* Ensure new descriptor hits memory |
886 | * before setting ownership of this descriptor to HW */ | 890 | * before setting ownership of this descriptor to HW |
891 | */ | ||
887 | wmb(); | 892 | wmb(); |
888 | tx_desc->ctrl.owner_opcode = op_own; | 893 | tx_desc->ctrl.owner_opcode = op_own; |
889 | 894 | ||
@@ -896,12 +901,16 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) | |||
896 | 901 | ||
897 | ring->bf.offset ^= ring->bf.buf_size; | 902 | ring->bf.offset ^= ring->bf.buf_size; |
898 | } else { | 903 | } else { |
899 | /* Ensure new descirptor hits memory | 904 | /* Ensure new descriptor hits memory |
900 | * before setting ownership of this descriptor to HW */ | 905 | * before setting ownership of this descriptor to HW |
906 | */ | ||
901 | wmb(); | 907 | wmb(); |
902 | tx_desc->ctrl.owner_opcode = op_own; | 908 | tx_desc->ctrl.owner_opcode = op_own; |
903 | wmb(); | 909 | if (send_doorbell) { |
904 | iowrite32be(ring->doorbell_qpn, ring->bf.uar->map + MLX4_SEND_DOORBELL); | 910 | wmb(); |
911 | iowrite32be(ring->doorbell_qpn, | ||
912 | ring->bf.uar->map + MLX4_SEND_DOORBELL); | ||
913 | } | ||
905 | } | 914 | } |
906 | 915 | ||
907 | return NETDEV_TX_OK; | 916 | return NETDEV_TX_OK; |