From owner-svn-src-all@freebsd.org Fri May 20 06:59:40 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 36A62B38D69; Fri, 20 May 2016 06:59:40 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E9EFD19B9; Fri, 20 May 2016 06:59:39 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u4K6xd7E091318; Fri, 20 May 2016 06:59:39 GMT (envelope-from hselasky@FreeBSD.org) Received: (from hselasky@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u4K6xcq9091315; Fri, 20 May 2016 06:59:38 GMT (envelope-from hselasky@FreeBSD.org) Message-Id: <201605200659.u4K6xcq9091315@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hselasky set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky Date: Fri, 20 May 2016 06:59:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r300280 - head/sys/dev/mlx5/mlx5_en X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 May 2016 06:59:40 -0000 Author: hselasky Date: Fri May 20 06:59:38 2016 New Revision: 300280 URL: https://svnweb.freebsd.org/changeset/base/300280 Log: 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 Modified: head/sys/dev/mlx5/mlx5_en/en.h head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c head/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Modified: head/sys/dev/mlx5/mlx5_en/en.h ============================================================================== --- head/sys/dev/mlx5/mlx5_en/en.h Fri May 20 06:56:43 2016 (r300279) +++ head/sys/dev/mlx5/mlx5_en/en.h Fri May 20 06:59:38 2016 (r300280) @@ -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 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; @@ -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_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: head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c ============================================================================== --- head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Fri May 20 06:56:43 2016 (r300279) +++ head/sys/dev/mlx5/mlx5_en/mlx5_en_main.c Fri May 20 06:59:38 2016 (r300280) @@ -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: head/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c ============================================================================== --- head/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Fri May 20 06:56:43 2016 (r300279) +++ head/sys/dev/mlx5/mlx5_en/mlx5_en_tx.c Fri May 20 06:59:38 2016 (r300280) @@ -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: