From owner-svn-src-all@FreeBSD.ORG Wed Mar 25 13:48:55 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 74E526CF; Wed, 25 Mar 2015 13:48:55 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::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 53815645; Wed, 25 Mar 2015 13:48:55 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t2PDmt2l086256; Wed, 25 Mar 2015 13:48:55 GMT (envelope-from arybchik@FreeBSD.org) Received: (from arybchik@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t2PDmtHA086255; Wed, 25 Mar 2015 13:48:55 GMT (envelope-from arybchik@FreeBSD.org) Message-Id: <201503251348.t2PDmtHA086255@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: arybchik set sender to arybchik@FreeBSD.org using -f From: Andrew Rybchenko Date: Wed, 25 Mar 2015 13:48:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r280605 - stable/10/sys/dev/sfxge/common X-SVN-Group: stable-10 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.18-1 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: Wed, 25 Mar 2015 13:48:55 -0000 Author: arybchik Date: Wed Mar 25 13:48:54 2015 New Revision: 280605 URL: https://svnweb.freebsd.org/changeset/base/280605 Log: MFC: 280375 sfxge: add barriers to BAR write macros In theory the barriers are required to cope with write combining and reordering. Two barriers are added (sometimes merged to one): 1. Before the first write to guarantee that previous writes to the region have been done 2. Before the last write to guarantee that write to the last dword/qword is done after previous writes Barriers are inserted before in the assumption that it is better to postpone barriers as much as it is possible (more chances that the operation has already been already done and barrier does not stall CPU). On x86 and amd64 bus space write barriers are just compiler memory barriers which are definitely required. Sponsored by: Solarflare Communications, Inc. Original Differential Revision: https://reviews.freebsd.org/D2077 Modified: stable/10/sys/dev/sfxge/common/efsys.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/dev/sfxge/common/efsys.h ============================================================================== --- stable/10/sys/dev/sfxge/common/efsys.h Wed Mar 25 13:47:48 2015 (r280604) +++ stable/10/sys/dev/sfxge/common/efsys.h Wed Mar 25 13:48:54 2015 (r280605) @@ -786,6 +786,14 @@ typedef struct efsys_bar_s { EFSYS_PROBE2(bar_writed, unsigned int, (_offset), \ uint32_t, (_edp)->ed_u32[0]); \ \ + /* \ + * Make sure that previous writes to the dword have \ + * been done. It should be cheaper than barrier just \ + * after the write below. \ + */ \ + bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), sizeof (efx_dword_t), \ + BUS_SPACE_BARRIER_WRITE); \ bus_space_write_stream_4((_esbp)->esb_tag, \ (_esbp)->esb_handle, \ (_offset), (_edp)->ed_u32[0]); \ @@ -809,6 +817,14 @@ typedef struct efsys_bar_s { uint32_t, (_eqp)->eq_u32[1], \ uint32_t, (_eqp)->eq_u32[0]); \ \ + /* \ + * Make sure that previous writes to the qword have \ + * been done. It should be cheaper than barrier just \ + * after the write below. \ + */ \ + bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), sizeof (efx_qword_t), \ + BUS_SPACE_BARRIER_WRITE); \ bus_space_write_stream_8((_esbp)->esb_tag, \ (_esbp)->esb_handle, \ (_offset), (_eqp)->eq_u64[0]); \ @@ -829,9 +845,25 @@ typedef struct efsys_bar_s { uint32_t, (_eqp)->eq_u32[1], \ uint32_t, (_eqp)->eq_u32[0]); \ \ + /* \ + * Make sure that previous writes to the qword have \ + * been done. It should be cheaper than barrier just \ + * after the last write below. \ + */ \ + bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), sizeof (efx_qword_t), \ + BUS_SPACE_BARRIER_WRITE); \ bus_space_write_stream_4((_esbp)->esb_tag, \ (_esbp)->esb_handle, \ (_offset), (_eqp)->eq_u32[0]); \ + /* \ + * It should be guaranteed that the last dword comes \ + * the last, so barrier entire qword to be sure that \ + * neither above nor below writes are reordered. \ + */ \ + bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), sizeof (efx_qword_t), \ + BUS_SPACE_BARRIER_WRITE); \ bus_space_write_stream_4((_esbp)->esb_tag, \ (_esbp)->esb_handle, \ (_offset) + 4, (_eqp)->eq_u32[1]); \ @@ -858,9 +890,25 @@ typedef struct efsys_bar_s { uint32_t, (_eop)->eo_u32[1], \ uint32_t, (_eop)->eo_u32[0]); \ \ + /* \ + * Make sure that previous writes to the oword have \ + * been done. It should be cheaper than barrier just \ + * after the last write below. \ + */ \ + bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), sizeof (efx_oword_t), \ + BUS_SPACE_BARRIER_WRITE); \ bus_space_write_stream_8((_esbp)->esb_tag, \ (_esbp)->esb_handle, \ (_offset), (_eop)->eo_u64[0]); \ + /* \ + * It should be guaranteed that the last qword comes \ + * the last, so barrier entire oword to be sure that \ + * neither above nor below writes are reordered. \ + */ \ + bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), sizeof (efx_oword_t), \ + BUS_SPACE_BARRIER_WRITE); \ bus_space_write_stream_8((_esbp)->esb_tag, \ (_esbp)->esb_handle, \ (_offset) + 8, (_eop)->eo_u64[1]); \ @@ -888,6 +936,14 @@ typedef struct efsys_bar_s { uint32_t, (_eop)->eo_u32[1], \ uint32_t, (_eop)->eo_u32[0]); \ \ + /* \ + * Make sure that previous writes to the oword have \ + * been done. It should be cheaper than barrier just \ + * after the last write below. \ + */ \ + bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), sizeof (efx_oword_t), \ + BUS_SPACE_BARRIER_WRITE); \ bus_space_write_stream_4((_esbp)->esb_tag, \ (_esbp)->esb_handle, \ (_offset), (_eop)->eo_u32[0]); \ @@ -897,6 +953,14 @@ typedef struct efsys_bar_s { bus_space_write_stream_4((_esbp)->esb_tag, \ (_esbp)->esb_handle, \ (_offset) + 8, (_eop)->eo_u32[2]); \ + /* \ + * It should be guaranteed that the last dword comes \ + * the last, so barrier entire oword to be sure that \ + * neither above nor below writes are reordered. \ + */ \ + bus_space_barrier((_esbp)->esb_tag, (_esbp)->esb_handle,\ + (_offset), sizeof (efx_oword_t), \ + BUS_SPACE_BARRIER_WRITE); \ bus_space_write_stream_4((_esbp)->esb_tag, \ (_esbp)->esb_handle, \ (_offset) + 12, (_eop)->eo_u32[3]); \