svn commit: r337273 - head/sys/dev/nvme

Konstantin Belousov kostikbel at gmail.com
Sat Aug 4 13:03:32 UTC 2018


On Sat, Aug 04, 2018 at 05:14:31AM -0700, John Baldwin wrote:
> On 8/4/18 1:08 AM, Konstantin Belousov wrote:
> > On Fri, Aug 03, 2018 at 08:04:06PM +0000, Justin Hibbits wrote:
> >> Author: jhibbits
> >> Date: Fri Aug  3 20:04:06 2018
> >> New Revision: 337273
> >> URL: https://svnweb.freebsd.org/changeset/base/337273
> >>
> >> Log:
> >>   nvme(4): Add bus_dmamap_sync() at the end of the request path
> >>   
> >>   Summary:
> >>   Some architectures, in this case powerpc64, need explicit synchronization
> >>   barriers vs device accesses.
> >>   
> >>   Prior to this change, when running 'make buildworld -j72' on a 18-core
> >>   (72-thread) POWER9, I would see controller resets often.  With this change, I
> >>   don't see these resets messages, though another tester still does, for yet to be
> >>   determined reasons, so this may not be a complete fix.  Additionally, I see a
> >>   ~5-10% speed up in buildworld times, likely due to not needing to reset the
> >>   controller.
> >>   
> >>   Reviewed By: jimharris
> >>   Differential Revision: https://reviews.freebsd.org/D16570
> >>
> >> Modified:
> >>   head/sys/dev/nvme/nvme_qpair.c
> >>
> >> Modified: head/sys/dev/nvme/nvme_qpair.c
> >> ==============================================================================
> >> --- head/sys/dev/nvme/nvme_qpair.c	Fri Aug  3 19:24:04 2018	(r337272)
> >> +++ head/sys/dev/nvme/nvme_qpair.c	Fri Aug  3 20:04:06 2018	(r337273)
> >> @@ -401,9 +401,13 @@ nvme_qpair_complete_tracker(struct nvme_qpair *qpair, 
> >>  		req->retries++;
> >>  		nvme_qpair_submit_tracker(qpair, tr);
> >>  	} else {
> >> -		if (req->type != NVME_REQUEST_NULL)
> >> +		if (req->type != NVME_REQUEST_NULL) {
> >> +			bus_dmamap_sync(qpair->dma_tag_payload,
> >> +			    tr->payload_dma_map,
> >> +			    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
> >>  			bus_dmamap_unload(qpair->dma_tag_payload,
> >>  			    tr->payload_dma_map);
> >> +		}
> >>  
> >>  		nvme_free_request(req);
> >>  		tr->req = NULL;
> >> @@ -487,6 +491,8 @@ nvme_qpair_process_completions(struct nvme_qpair *qpai
> >>  		 */
> >>  		return (false);
> >>  
> >> +	bus_dmamap_sync(qpair->dma_tag, qpair->queuemem_map,
> >> +	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
> >>  	while (1) {
> >>  		cpl = qpair->cpl[qpair->cq_head];
> >>  
> >> @@ -828,7 +834,16 @@ nvme_qpair_submit_tracker(struct nvme_qpair *qpair, st
> >>  	if (++qpair->sq_tail == qpair->num_entries)
> >>  		qpair->sq_tail = 0;
> >>  
> >> +	bus_dmamap_sync(qpair->dma_tag, qpair->queuemem_map,
> >> +	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
> >> +#ifndef __powerpc__
> >> +	/*
> >> +	 * powerpc's bus_dmamap_sync() already includes a heavyweight sync, but
> >> +	 * no other archs do.
> >> +	 */
> >>  	wmb();
> >> +#endif
> > What is the purpose of this call ?  It is useless without paired read
> > barrier.  So where is the reciprocal rmb() ?
> 
> For DMA, the rmb is in the device controller.  However, architectures
> that need this kind of ordering should do it in their bus_dmmap_sync op,
> and this explicit one needs to be removed.  (Alpha had a wmb in its
> bus_dmamap_sync op for this reason.)
Yes, if something special is needed, it should happen in platform-specific
busdma code.

Also, if wmb() is needed, then it is not a supposed semantic or
wmb(), but a specific side-effects of one of the instruction in the
implementation of wmb().

As I noted, on x86 it is not needed and detrimental to the performance.


More information about the svn-src-all mailing list