Date: Fri, 3 Jun 2016 09:05:50 +0000 (UTC) From: Hans Petter Selasky <hselasky@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r301259 - stable/10/sys/dev/mlx5/mlx5_en Message-ID: <201606030905.u5395ojT028780@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201606030905.u5395ojT028780>