From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754019AbbKBUzi (ORCPT ); Mon, 2 Nov 2015 15:55:38 -0500 Received: from mout.kundenserver.de ([212.227.17.24]:60947 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753637AbbKBUzf (ORCPT ); Mon, 2 Nov 2015 15:55:35 -0500 From: Arnd Bergmann To: Sinan Kaya Cc: dmaengine@vger.kernel.org, timur@codeaurora.org, cov@codeaurora.org, jcm@redhat.com, Rob Herring , Pawel Moll , Mark Rutland , Ian Campbell , Kumar Gala , Vinod Koul , Dan Williams , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 2/2] dma: add Qualcomm Technologies HIDMA channel driver Date: Mon, 02 Nov 2015 21:55:13 +0100 Message-ID: <17979873.Bg2pv5SLy6@wuerfel> User-Agent: KMail/4.11.5 (Linux/3.16.0-10-generic; KDE/4.11.5; x86_64; ; ) In-Reply-To: <5637B7C1.2070200@codeaurora.org> References: <1446174501-8870-1-git-send-email-okaya@codeaurora.org> <3962829.iR3I63FEm8@wuerfel> <5637B7C1.2070200@codeaurora.org> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Provags-ID: V03:K0:5fkT0zy5C1kfA+EeW7d2C7ug34eLUeVnZPYST/IB+8TujpeUj4X 5d0i8LQzgET9XZi1ldJv+L86TABsgIv00ITAUgs/I9DJ139bViiCKVEg59mQNue1Y33qeEm ZnSeHVmMxpuZM0d6tFf38tOj7sXoZ9gthoJLexMMBWq60+cLabXSj798rGYUO5Fr4oD/ZZo Uy3btRlxG9IVihTKstPdw== X-UI-Out-Filterresults: notjunk:1;V01:K0:n0sjxWTIFU8=:ZtkuYtGD5z5gx3usJlYaEo wYPqlSzrtji3M5VppbPFeCHzP8X6TC/UkYL8M3/R+kh/0SXBjJgURT5biyY0skWGfl3S8oHuD rGRELRt7pugqXFS+/0I6sNaah3ax9qr6t5noyPy1T8Z3iIb3vMmDGLugdO/L2rFzPCMT/WBKy es5HDPgFB3GSEo3ULfQJvNobluhF6BitPi3FSdXXfy5eZ+IiCfoyyOQ4Vp+C1/bLfwa2/SMil jf3lLnZR6ru1IkhuRZA4aO1JpN2kZqnIydiDwt4lZ6erWt3QxgMhcFuM4rRTNIEGer9xy3plj iO69aeTpcKURqpSpJ/hi+/b8xRwBJbqjAe69MTuSd8JSe3OJvZm1ockDbWSQx3wRGOSFeJh+k dZHcqLwPHHXpaplKWAvvXyLj6yRTMmhmfFwyPpwZyYRb6H9XjXEkMgKPdNue4rMKZh6AV/VDt FEs3PLz8OhWF8gSThQI00s9XR7JpN3KvtP3TCjJg7J+RFP00jEsv0SbrdAkoQOaoV73idVUjk UCkoQmo48ys3iWK6vrmtu/dAO/8w+RceMnFnSLN8DPqczygNoUNFFLaUdb5ky1dDDummwn73O mht98mwNyJc8Z8vPR0HpvtIcPrIzFY2c5p3oFZYYgILydcL4E757tCkdt9PnBJN1PRtdnwMtv ydUiLWPNMK1x5FAjb6f5YcI60cS38zD2R8fMyLGaNYRYYSJDimwOIyBunOtaUVprMiMDsSpEb YLqiHf5cIgXowwob Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Monday 02 November 2015 14:21:37 Sinan Kaya wrote: > On 11/2/2015 11:33 AM, Arnd Bergmann wrote: > > On Sunday 01 November 2015 13:50:53 Sinan Kaya wrote: > > A barrier after the writel() has no effect, as MMIO writes are posted > > on the bus. > > I had two use cases in the original code. We are talking about start > routine here. I was giving reference to enable/reset/disable uses above. > > 1. Start routine > -------------- > spin_lock > writel_relaxed > spin_unlock > > and > > 2. enable/reset/disable > -------------- > writel_relaxed > wmb > > I changed writel_relaxed to writel now in start routine and submitted > the second version of the patchset yesterday. I hope you have received > it. I was relying on the spinlocks before. Ok > > > >> However, after issuing the command; I still need to wait some amount of > >> time until hardware acknowledges the commands like reset/enable/disable. > >> These are relatively faster operations happening in microseconds. That's > >> why, I have mdelay there. > >> > >> I'll take a look at workqueues but it could turn out to be an overkill > >> for few microseconds. > > > > Most devices are able to provide an interrupt for long-running commands. > > Are you sure that yours is unable to do this? If so, is this a design > > mistake or an implementation bug? > > I think I was not clear on how long these command take. These command > are really fast and get acknowledged at status register in few > microseconds. That's why I choose polling. > > I was waiting up to 10ms before and manually sleeping 1 milliseconds in > between each using mdelay. I followed your suggestion and got rid of the > mdelay. Then, I used polled read command which calls the usleep_range > function as you suggested. > > Hardware supports error interrupts but this is a SW design philosophy > discussion. Why would you want to trigger an interrupt for few > microseconds delay that only happens during the first time init from probe? If you get called in sleeping context and can use usleep_range() for delaying, that is fine, but in effect that just means you generate another interrupt from the timer that is not synchronized to your device, and hide the complexity behind the usleep_range() function call. My first choice would have been to use a struct completion to wait for the next interrupt here, which has similar complexity on the source code side, but never waits longer than necessary. If the hrtimer based method works for you, there is no need to change that. > >> I checked with the hardware designers. Hardware guarantees that by the > >> time interrupt is observed, all data transactions in flight are > >> delivered to their respective places and are visible to the CPU. I'll > >> add a comment in the code about this. > > > > I'm curious about this. Does that mean the device is not meant for > > high-performance transfers and just synchronizes the bus before > > triggering the interrupt? > > HIDMA meaning, as you probably guessed, is high performance DMA. We had > several name iterations in the company and this was the one that sticked. > > I'm a SW person. I don't have the expertise to go deeper into HW design. > I'm following the programming document. It says coherency and guaranteed > interrupt ordering. High performance can mean how fast you can move data > from one location to the other one vs. how fast you can queue up > multiple requests and get acks in response. > > I followed a simple design here. HW can take multiple requests > simultaneously and give me an ack when it is finished with interrupt. > > If there are requests in flight, other requests will get queued up in SW > and will not be serviced until the previous requests get acknowledged. > Then, as soon as HW stops processing; I queue a bunch of other requests > and kick start it. Current SW design does not allow simultaneous SW > queuing vs. HW processing. I can try this on the next iteration. This > implementation, IMO, is good enough now and has been working reliably > for a long time (since 2014). Are you using message signaled interrupts then? Typically MSI guarantees ordering against DMA, but level or edge triggered interrupts by definition cannot (at least on PCI, but most other buses are the same way), because the DMA master has no insight into when a DMA is actually complete. If you use MSI, please add a comment to the readl_relaxed() that it is safe because of that, otherwise the next person who tries to debug a problem with your driver has to look into this. > >>> In other words, when the hardware sends you data followed by an > >>> interrupt to tell you the data is there, your interrupt handler > >>> can tell the driver that is waiting for this data that the DMA > >>> is complete while the data itself is still in flight, e.g. waiting > >>> for an IOMMU to fetch page table entries. > >>> > >> There is HW guarantee for ordering. > >> > >> On demand paging for IOMMU is only supported for PCIe via PRI (Page > >> Request Interface) not for HIDMA. All other hardware instances work on > >> pinned DMA addresses. I'll drop a note about this too to the code as well. > > > > I wasn't talking about paging, just fetching the IOTLB from the > > preloaded page tables in RAM. This can takes several uncached memory > > accesses, so it would generally be slow. > > > I see. > > HIDMA is not aware of IOMMU presence since it follows the DMA API. All > IOMMU latency will be built into the data movement time. By the time > interrupt happens, IOMMU lookups + data movement has already taken place. Ok. Arnd