forked from Minki/linux
net/mlx4_en: Add NAPI support for transmit side
Add NAPI for TX side, implement its support and provide NAPI callback. Signed-off-by: Yevgeny Petrilin <yevgenyp@mellanox.com> Signed-off-by: Eugenia Emantayev <eugenia@mellanox.com> Signed-off-by: Amir Vadai <amirv@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e4b59a1cb6
commit
0276a33061
@ -161,12 +161,16 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
|
||||
cq->mcq.comp = cq->is_tx ? mlx4_en_tx_irq : mlx4_en_rx_irq;
|
||||
cq->mcq.event = mlx4_en_cq_event;
|
||||
|
||||
if (!cq->is_tx) {
|
||||
if (cq->is_tx) {
|
||||
netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_tx_cq,
|
||||
NAPI_POLL_WEIGHT);
|
||||
} else {
|
||||
netif_napi_add(cq->dev, &cq->napi, mlx4_en_poll_rx_cq, 64);
|
||||
napi_hash_add(&cq->napi);
|
||||
napi_enable(&cq->napi);
|
||||
}
|
||||
|
||||
napi_enable(&cq->napi);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -188,12 +192,12 @@ void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq **pcq)
|
||||
|
||||
void mlx4_en_deactivate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
|
||||
{
|
||||
napi_disable(&cq->napi);
|
||||
if (!cq->is_tx) {
|
||||
napi_disable(&cq->napi);
|
||||
napi_hash_del(&cq->napi);
|
||||
synchronize_rcu();
|
||||
netif_napi_del(&cq->napi);
|
||||
}
|
||||
netif_napi_del(&cq->napi);
|
||||
|
||||
mlx4_cq_free(priv->mdev->dev, &cq->mcq);
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ static u32 mlx4_en_free_tx_desc(struct mlx4_en_priv *priv,
|
||||
}
|
||||
}
|
||||
}
|
||||
dev_kfree_skb_any(skb);
|
||||
dev_kfree_skb(skb);
|
||||
return tx_info->nr_txbb;
|
||||
}
|
||||
|
||||
@ -361,7 +361,9 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring)
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
|
||||
static int mlx4_en_process_tx_cq(struct net_device *dev,
|
||||
struct mlx4_en_cq *cq,
|
||||
int budget)
|
||||
{
|
||||
struct mlx4_en_priv *priv = netdev_priv(dev);
|
||||
struct mlx4_cq *mcq = &cq->mcq;
|
||||
@ -379,9 +381,10 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
|
||||
u32 bytes = 0;
|
||||
int factor = priv->cqe_factor;
|
||||
u64 timestamp = 0;
|
||||
int done = 0;
|
||||
|
||||
if (!priv->port_up)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
index = cons_index & size_mask;
|
||||
cqe = &buf[(index << factor) + factor];
|
||||
@ -390,7 +393,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
|
||||
|
||||
/* Process all completed CQEs */
|
||||
while (XNOR(cqe->owner_sr_opcode & MLX4_CQE_OWNER_MASK,
|
||||
cons_index & size)) {
|
||||
cons_index & size) && (done < budget)) {
|
||||
/*
|
||||
* make sure we read the CQE after we read the
|
||||
* ownership bit
|
||||
@ -428,7 +431,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
|
||||
txbbs_stamp = txbbs_skipped;
|
||||
packets++;
|
||||
bytes += ring->tx_info[ring_index].nr_bytes;
|
||||
} while (ring_index != new_index);
|
||||
} while ((++done < budget) && (ring_index != new_index));
|
||||
|
||||
++cons_index;
|
||||
index = cons_index & size_mask;
|
||||
@ -454,6 +457,7 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
|
||||
netif_tx_wake_queue(ring->tx_queue);
|
||||
priv->port_stats.wake_queue++;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
void mlx4_en_tx_irq(struct mlx4_cq *mcq)
|
||||
@ -461,10 +465,31 @@ void mlx4_en_tx_irq(struct mlx4_cq *mcq)
|
||||
struct mlx4_en_cq *cq = container_of(mcq, struct mlx4_en_cq, mcq);
|
||||
struct mlx4_en_priv *priv = netdev_priv(cq->dev);
|
||||
|
||||
mlx4_en_process_tx_cq(cq->dev, cq);
|
||||
mlx4_en_arm_cq(priv, cq);
|
||||
if (priv->port_up)
|
||||
napi_schedule(&cq->napi);
|
||||
else
|
||||
mlx4_en_arm_cq(priv, cq);
|
||||
}
|
||||
|
||||
/* TX CQ polling - called by NAPI */
|
||||
int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct mlx4_en_cq *cq = container_of(napi, struct mlx4_en_cq, napi);
|
||||
struct net_device *dev = cq->dev;
|
||||
struct mlx4_en_priv *priv = netdev_priv(dev);
|
||||
int done;
|
||||
|
||||
done = mlx4_en_process_tx_cq(dev, cq, budget);
|
||||
|
||||
/* If we used up all the quota - we're probably not done yet... */
|
||||
if (done < budget) {
|
||||
/* Done for now */
|
||||
napi_complete(napi);
|
||||
mlx4_en_arm_cq(priv, cq);
|
||||
return done;
|
||||
}
|
||||
return budget;
|
||||
}
|
||||
|
||||
static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv,
|
||||
struct mlx4_en_tx_ring *ring,
|
||||
|
@ -744,6 +744,7 @@ int mlx4_en_process_rx_cq(struct net_device *dev,
|
||||
struct mlx4_en_cq *cq,
|
||||
int budget);
|
||||
int mlx4_en_poll_rx_cq(struct napi_struct *napi, int budget);
|
||||
int mlx4_en_poll_tx_cq(struct napi_struct *napi, int budget);
|
||||
void mlx4_en_fill_qp_context(struct mlx4_en_priv *priv, int size, int stride,
|
||||
int is_tx, int rss, int qpn, int cqn, int user_prio,
|
||||
struct mlx4_qp_context *context);
|
||||
|
Loading…
Reference in New Issue
Block a user