svn commit: r301259 - stable/10/sys/dev/mlx5/mlx5_en
Hans Petter Selasky
hselasky at FreeBSD.org
Fri Jun 3 09:05:51 UTC 2016
Author: hselasky
Date: Fri Jun 3 09:05:49 2016
New Revision: 301259
URL: https://svnweb.freebsd.org/changeset/base/301259
Log:
MFC r300280:
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
Modified:
stable/10/sys/dev/mlx5/mlx5_en/en.h
stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/mlx5/mlx5_en/en.h
==============================================================================
--- stable/10/sys/dev/mlx5/mlx5_en/en.h Fri Jun 3 09:03:44 2016 (r301258)
+++ stable/10/sys/dev/mlx5/mlx5_en/en.h Fri Jun 3 09:05:49 2016 (r301259)
@@ -507,6 +507,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;
@@ -754,8 +758,7 @@ int mlx5e_add_all_vlan_rules(struct mlx5
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;
@@ -771,13 +774,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;
@@ -797,7 +800,7 @@ void mlx5e_create_ethtool(struct mlx5e_p
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 *);
Modified: stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c
==============================================================================
--- stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Fri Jun 3 09:03:44 2016 (r301258)
+++ stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Fri Jun 3 09:05:49 2016 (r301259)
@@ -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_s
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;
}
Modified: stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c
==============================================================================
--- stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Fri Jun 3 09:03:44 2016 (r301258)
+++ stable/10/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Fri Jun 3 09:05:49 2016 (r301259)
@@ -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
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, struc
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 @@ skip_dma:
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 @@ skip_dma:
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, str
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:
More information about the svn-src-stable-10
mailing list