mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-19 10:53:58 +00:00
Optimise use of doorbell and remove redundant NOPs
Store the last doorbell write in the mlx5e_sq structure and write the doorbell to the hardware when the transmit routine finishes transmitting all queued mbufs. Sponsored by: Mellanox Technologies Tested by: Netflix MFC after: 1 week
This commit is contained in:
parent
376bcf6331
commit
af89c4aff6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=300280
@ -505,6 +505,10 @@ struct mlx5e_sq {
|
||||
#define MLX5E_CEV_STATE_SEND_NOPS 1 /* send NOPs */
|
||||
#define MLX5E_CEV_STATE_HOLD_NOPS 2 /* don't send NOPs yet */
|
||||
struct callout cev_callout;
|
||||
union {
|
||||
u32 d32[2];
|
||||
u64 d64;
|
||||
} doorbell;
|
||||
struct mlx5e_sq_stats stats;
|
||||
|
||||
struct mlx5e_cq cq;
|
||||
@ -752,8 +756,7 @@ int mlx5e_add_all_vlan_rules(struct mlx5e_priv *priv);
|
||||
void mlx5e_del_all_vlan_rules(struct mlx5e_priv *priv);
|
||||
|
||||
static inline void
|
||||
mlx5e_tx_notify_hw(struct mlx5e_sq *sq,
|
||||
struct mlx5e_tx_wqe *wqe, int bf_sz)
|
||||
mlx5e_tx_notify_hw(struct mlx5e_sq *sq, u32 *wqe, int bf_sz)
|
||||
{
|
||||
u16 ofst = MLX5_BF_OFFSET + sq->bf_offset;
|
||||
|
||||
@ -769,13 +772,13 @@ mlx5e_tx_notify_hw(struct mlx5e_sq *sq,
|
||||
wmb();
|
||||
|
||||
if (bf_sz) {
|
||||
__iowrite64_copy(sq->uar_bf_map + ofst, &wqe->ctrl, bf_sz);
|
||||
__iowrite64_copy(sq->uar_bf_map + ofst, wqe, bf_sz);
|
||||
|
||||
/* flush the write-combining mapped buffer */
|
||||
wmb();
|
||||
|
||||
} else {
|
||||
mlx5_write64((__be32 *)&wqe->ctrl, sq->uar_map + ofst, NULL);
|
||||
mlx5_write64(wqe, sq->uar_map + ofst, NULL);
|
||||
}
|
||||
|
||||
sq->bf_offset ^= sq->bf_buf_size;
|
||||
@ -795,7 +798,7 @@ void mlx5e_create_ethtool(struct mlx5e_priv *);
|
||||
void mlx5e_create_stats(struct sysctl_ctx_list *,
|
||||
struct sysctl_oid_list *, const char *,
|
||||
const char **, unsigned, u64 *);
|
||||
void mlx5e_send_nop(struct mlx5e_sq *, u32, bool);
|
||||
void mlx5e_send_nop(struct mlx5e_sq *, u32);
|
||||
void mlx5e_sq_cev_timeout(void *);
|
||||
int mlx5e_refresh_channel_params(struct mlx5e_priv *);
|
||||
|
||||
|
@ -850,7 +850,6 @@ mlx5e_open_rq(struct mlx5e_channel *c,
|
||||
struct mlx5e_rq *rq)
|
||||
{
|
||||
int err;
|
||||
int i;
|
||||
|
||||
err = mlx5e_create_rq(c, param, rq);
|
||||
if (err)
|
||||
@ -866,12 +865,6 @@ mlx5e_open_rq(struct mlx5e_channel *c,
|
||||
|
||||
c->rq.enabled = 1;
|
||||
|
||||
/*
|
||||
* Test send queues, which will trigger
|
||||
* "mlx5e_post_rx_wqes()":
|
||||
*/
|
||||
for (i = 0; i != c->num_tc; i++)
|
||||
mlx5e_send_nop(&c->sq[i], 1, true);
|
||||
return (0);
|
||||
|
||||
err_disable_rq:
|
||||
@ -1198,9 +1191,16 @@ mlx5e_sq_send_nops_locked(struct mlx5e_sq *sq, int can_sleep)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
mlx5e_send_nop(sq, 1, true);
|
||||
/* send a single NOP */
|
||||
mlx5e_send_nop(sq, 1);
|
||||
wmb();
|
||||
}
|
||||
done:
|
||||
/* Check if we need to write the doorbell */
|
||||
if (likely(sq->doorbell.d64 != 0)) {
|
||||
mlx5e_tx_notify_hw(sq, sq->doorbell.d32, 0);
|
||||
sq->doorbell.d64 = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ mlx5e_do_send_cqe(struct mlx5e_sq *sq)
|
||||
}
|
||||
|
||||
void
|
||||
mlx5e_send_nop(struct mlx5e_sq *sq, u32 ds_cnt, bool notify_hw)
|
||||
mlx5e_send_nop(struct mlx5e_sq *sq, u32 ds_cnt)
|
||||
{
|
||||
u16 pi = sq->pc & sq->wq.sz_m1;
|
||||
struct mlx5e_tx_wqe *wqe = mlx5_wq_cyc_get_wqe(&sq->wq, pi);
|
||||
@ -55,12 +55,13 @@ mlx5e_send_nop(struct mlx5e_sq *sq, u32 ds_cnt, bool notify_hw)
|
||||
else
|
||||
wqe->ctrl.fm_ce_se = 0;
|
||||
|
||||
/* Copy data for doorbell */
|
||||
memcpy(sq->doorbell.d32, &wqe->ctrl, sizeof(sq->doorbell.d32));
|
||||
|
||||
sq->mbuf[pi].mbuf = NULL;
|
||||
sq->mbuf[pi].num_bytes = 0;
|
||||
sq->mbuf[pi].num_wqebbs = DIV_ROUND_UP(ds_cnt, MLX5_SEND_WQEBB_NUM_DS);
|
||||
sq->pc += sq->mbuf[pi].num_wqebbs;
|
||||
if (notify_hw)
|
||||
mlx5e_tx_notify_hw(sq, wqe, 0);
|
||||
}
|
||||
|
||||
#if (__FreeBSD_version >= 1100000)
|
||||
@ -221,7 +222,7 @@ mlx5e_sq_xmit(struct mlx5e_sq *sq, struct mbuf **mbp)
|
||||
pi = ((~sq->pc) & sq->wq.sz_m1);
|
||||
if (pi < (MLX5_SEND_WQE_MAX_WQEBBS - 1)) {
|
||||
/* Send one multi NOP message instead of many */
|
||||
mlx5e_send_nop(sq, (pi + 1) * MLX5_SEND_WQEBB_NUM_DS, false);
|
||||
mlx5e_send_nop(sq, (pi + 1) * MLX5_SEND_WQEBB_NUM_DS);
|
||||
pi = ((~sq->pc) & sq->wq.sz_m1);
|
||||
if (pi < (MLX5_SEND_WQE_MAX_WQEBBS - 1)) {
|
||||
m_freem(mb);
|
||||
@ -360,6 +361,9 @@ mlx5e_sq_xmit(struct mlx5e_sq *sq, struct mbuf **mbp)
|
||||
else
|
||||
wqe->ctrl.fm_ce_se = 0;
|
||||
|
||||
/* Copy data for doorbell */
|
||||
memcpy(sq->doorbell.d32, &wqe->ctrl, sizeof(sq->doorbell.d32));
|
||||
|
||||
/* Store pointer to mbuf */
|
||||
sq->mbuf[pi].mbuf = mb;
|
||||
sq->mbuf[pi].num_wqebbs = DIV_ROUND_UP(ds_cnt, MLX5_SEND_WQEBB_NUM_DS);
|
||||
@ -369,8 +373,6 @@ mlx5e_sq_xmit(struct mlx5e_sq *sq, struct mbuf **mbp)
|
||||
if (mb != NULL)
|
||||
bus_dmamap_sync(sq->dma_tag, sq->mbuf[pi].dma_map, BUS_DMASYNC_PREWRITE);
|
||||
|
||||
mlx5e_tx_notify_hw(sq, wqe, 0);
|
||||
|
||||
sq->stats.packets++;
|
||||
return (0);
|
||||
|
||||
@ -474,6 +476,11 @@ mlx5e_xmit_locked(struct ifnet *ifp, struct mlx5e_sq *sq, struct mbuf *mb)
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
break;
|
||||
}
|
||||
/* Check if we need to write the doorbell */
|
||||
if (likely(sq->doorbell.d64 != 0)) {
|
||||
mlx5e_tx_notify_hw(sq, sq->doorbell.d32, 0);
|
||||
sq->doorbell.d64 = 0;
|
||||
}
|
||||
/*
|
||||
* Check if we need to start the event timer which flushes the
|
||||
* transmit ring on timeout:
|
||||
|
Loading…
Reference in New Issue
Block a user