From: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org> To: joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org Cc: iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org Subject: [PATCH RESEND 2/3] iommu/dma: Clean up MSI IOVA allocation Date: Fri, 31 Mar 2017 15:46:06 +0100 [thread overview] Message-ID: <0d9ed41de4b88964e5bd0d653eed1094959e7276.1490971180.git.robin.murphy@arm.com> (raw) In-Reply-To: <cover.1490971180.git.robin.murphy-5wv7dgnIgG8@public.gmane.org> Now that allocation is suitably abstracted, our private alloc/free helpers can drive the trivial MSI cookie allocator directly as well, which lets us clean up its exposed guts from iommu_dma_map_msi_msg() and simplify things quite a bit. Reviewed-by: Nate Watterson <nwatters-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> Tested-by: Nate Watterson <nwatters-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org> Signed-off-by: Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org> --- drivers/iommu/dma-iommu.c | 58 ++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 8e0b684da1ba..1b94beb43036 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -61,15 +61,6 @@ static inline size_t cookie_msi_granule(struct iommu_dma_cookie *cookie) return PAGE_SIZE; } -static inline struct iova_domain *cookie_iovad(struct iommu_domain *domain) -{ - struct iommu_dma_cookie *cookie = domain->iova_cookie; - - if (cookie->type == IOMMU_DMA_IOVA_COOKIE) - return &cookie->iovad; - return NULL; -} - static struct iommu_dma_cookie *cookie_alloc(enum iommu_dma_cookie_type type) { struct iommu_dma_cookie *cookie; @@ -368,11 +359,19 @@ int dma_info_to_prot(enum dma_data_direction dir, bool coherent, static dma_addr_t iommu_dma_alloc_iova(struct iommu_domain *domain, size_t size, dma_addr_t dma_limit, struct device *dev) { - struct iova_domain *iovad = cookie_iovad(domain); - unsigned long shift = iova_shift(iovad); - unsigned long iova_len = size >> shift; + struct iommu_dma_cookie *cookie = domain->iova_cookie; + struct iova_domain *iovad = &cookie->iovad; + unsigned long shift, iova_len; struct iova *iova = NULL; + if (cookie->type == IOMMU_DMA_MSI_COOKIE) { + cookie->msi_iova += size; + return cookie->msi_iova - size; + } + + shift = iova_shift(iovad); + iova_len = size >> shift; + if (domain->geometry.force_aperture) dma_limit = min(dma_limit, domain->geometry.aperture_end); @@ -396,6 +395,12 @@ static void iommu_dma_free_iova(struct iommu_dma_cookie *cookie, struct iova_domain *iovad = &cookie->iovad; struct iova *iova_rbnode; + /* The MSI case is only ever cleaning up its most recent allocation */ + if (cookie->type == IOMMU_DMA_MSI_COOKIE) { + cookie->msi_iova -= size; + return; + } + iova_rbnode = find_iova(iovad, iova_pfn(iovad, iova)); if (WARN_ON(!iova_rbnode)) return; @@ -406,14 +411,15 @@ static void iommu_dma_free_iova(struct iommu_dma_cookie *cookie, static void __iommu_dma_unmap(struct iommu_domain *domain, dma_addr_t dma_addr, size_t size) { - struct iova_domain *iovad = cookie_iovad(domain); + struct iommu_dma_cookie *cookie = domain->iova_cookie; + struct iova_domain *iovad = &cookie->iovad; size_t iova_off = iova_offset(iovad, dma_addr); dma_addr -= iova_off; size = iova_align(iovad, size + iova_off); WARN_ON(iommu_unmap(domain, dma_addr, size) != size); - iommu_dma_free_iova(domain->iova_cookie, dma_addr, size); + iommu_dma_free_iova(cookie, dma_addr, size); } static void __iommu_dma_free_pages(struct page **pages, int count) @@ -838,7 +844,6 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, { struct iommu_dma_cookie *cookie = domain->iova_cookie; struct iommu_dma_msi_page *msi_page; - struct iova_domain *iovad = cookie_iovad(domain); dma_addr_t iova; int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO; size_t size = cookie_msi_granule(cookie); @@ -852,29 +857,16 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, if (!msi_page) return NULL; - msi_page->phys = msi_addr; - if (iovad) { - iova = iommu_dma_alloc_iova(domain, size, dma_get_mask(dev), dev); - if (!iova) - goto out_free_page; - msi_page->iova = iova; - } else { - msi_page->iova = cookie->msi_iova; - cookie->msi_iova += size; - } - - if (iommu_map(domain, msi_page->iova, msi_addr, size, prot)) - goto out_free_iova; + iova = __iommu_dma_map(dev, msi_addr, size, prot); + if (iommu_dma_mapping_error(dev, iova)) + goto out_free_page; INIT_LIST_HEAD(&msi_page->list); + msi_page->phys = msi_addr; + msi_page->iova = iova; list_add(&msi_page->list, &cookie->msi_page_list); return msi_page; -out_free_iova: - if (iovad) - iommu_dma_free_iova(cookie, iova, size); - else - cookie->msi_iova -= size; out_free_page: kfree(msi_page); return NULL; -- 2.11.0.dirty
WARNING: multiple messages have this Message-ID (diff)
From: robin.murphy@arm.com (Robin Murphy) To: linux-arm-kernel@lists.infradead.org Subject: [PATCH RESEND 2/3] iommu/dma: Clean up MSI IOVA allocation Date: Fri, 31 Mar 2017 15:46:06 +0100 [thread overview] Message-ID: <0d9ed41de4b88964e5bd0d653eed1094959e7276.1490971180.git.robin.murphy@arm.com> (raw) In-Reply-To: <cover.1490971180.git.robin.murphy@arm.com> Now that allocation is suitably abstracted, our private alloc/free helpers can drive the trivial MSI cookie allocator directly as well, which lets us clean up its exposed guts from iommu_dma_map_msi_msg() and simplify things quite a bit. Reviewed-by: Nate Watterson <nwatters@codeaurora.org> Tested-by: Nate Watterson <nwatters@codeaurora.org> Signed-off-by: Robin Murphy <robin.murphy@arm.com> --- drivers/iommu/dma-iommu.c | 58 ++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 8e0b684da1ba..1b94beb43036 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -61,15 +61,6 @@ static inline size_t cookie_msi_granule(struct iommu_dma_cookie *cookie) return PAGE_SIZE; } -static inline struct iova_domain *cookie_iovad(struct iommu_domain *domain) -{ - struct iommu_dma_cookie *cookie = domain->iova_cookie; - - if (cookie->type == IOMMU_DMA_IOVA_COOKIE) - return &cookie->iovad; - return NULL; -} - static struct iommu_dma_cookie *cookie_alloc(enum iommu_dma_cookie_type type) { struct iommu_dma_cookie *cookie; @@ -368,11 +359,19 @@ int dma_info_to_prot(enum dma_data_direction dir, bool coherent, static dma_addr_t iommu_dma_alloc_iova(struct iommu_domain *domain, size_t size, dma_addr_t dma_limit, struct device *dev) { - struct iova_domain *iovad = cookie_iovad(domain); - unsigned long shift = iova_shift(iovad); - unsigned long iova_len = size >> shift; + struct iommu_dma_cookie *cookie = domain->iova_cookie; + struct iova_domain *iovad = &cookie->iovad; + unsigned long shift, iova_len; struct iova *iova = NULL; + if (cookie->type == IOMMU_DMA_MSI_COOKIE) { + cookie->msi_iova += size; + return cookie->msi_iova - size; + } + + shift = iova_shift(iovad); + iova_len = size >> shift; + if (domain->geometry.force_aperture) dma_limit = min(dma_limit, domain->geometry.aperture_end); @@ -396,6 +395,12 @@ static void iommu_dma_free_iova(struct iommu_dma_cookie *cookie, struct iova_domain *iovad = &cookie->iovad; struct iova *iova_rbnode; + /* The MSI case is only ever cleaning up its most recent allocation */ + if (cookie->type == IOMMU_DMA_MSI_COOKIE) { + cookie->msi_iova -= size; + return; + } + iova_rbnode = find_iova(iovad, iova_pfn(iovad, iova)); if (WARN_ON(!iova_rbnode)) return; @@ -406,14 +411,15 @@ static void iommu_dma_free_iova(struct iommu_dma_cookie *cookie, static void __iommu_dma_unmap(struct iommu_domain *domain, dma_addr_t dma_addr, size_t size) { - struct iova_domain *iovad = cookie_iovad(domain); + struct iommu_dma_cookie *cookie = domain->iova_cookie; + struct iova_domain *iovad = &cookie->iovad; size_t iova_off = iova_offset(iovad, dma_addr); dma_addr -= iova_off; size = iova_align(iovad, size + iova_off); WARN_ON(iommu_unmap(domain, dma_addr, size) != size); - iommu_dma_free_iova(domain->iova_cookie, dma_addr, size); + iommu_dma_free_iova(cookie, dma_addr, size); } static void __iommu_dma_free_pages(struct page **pages, int count) @@ -838,7 +844,6 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, { struct iommu_dma_cookie *cookie = domain->iova_cookie; struct iommu_dma_msi_page *msi_page; - struct iova_domain *iovad = cookie_iovad(domain); dma_addr_t iova; int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO; size_t size = cookie_msi_granule(cookie); @@ -852,29 +857,16 @@ static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, if (!msi_page) return NULL; - msi_page->phys = msi_addr; - if (iovad) { - iova = iommu_dma_alloc_iova(domain, size, dma_get_mask(dev), dev); - if (!iova) - goto out_free_page; - msi_page->iova = iova; - } else { - msi_page->iova = cookie->msi_iova; - cookie->msi_iova += size; - } - - if (iommu_map(domain, msi_page->iova, msi_addr, size, prot)) - goto out_free_iova; + iova = __iommu_dma_map(dev, msi_addr, size, prot); + if (iommu_dma_mapping_error(dev, iova)) + goto out_free_page; INIT_LIST_HEAD(&msi_page->list); + msi_page->phys = msi_addr; + msi_page->iova = iova; list_add(&msi_page->list, &cookie->msi_page_list); return msi_page; -out_free_iova: - if (iovad) - iommu_dma_free_iova(cookie, iova, size); - else - cookie->msi_iova -= size; out_free_page: kfree(msi_page); return NULL; -- 2.11.0.dirty
next prev parent reply other threads:[~2017-03-31 14:46 UTC|newest] Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2017-03-31 14:46 [PATCH RESEND 0/3] IOVA allocation improvements for iommu-dma Robin Murphy 2017-03-31 14:46 ` Robin Murphy [not found] ` <cover.1490971180.git.robin.murphy-5wv7dgnIgG8@public.gmane.org> 2017-03-31 14:46 ` [PATCH RESEND 1/3] iommu/dma: Convert to address-based allocation Robin Murphy 2017-03-31 14:46 ` Robin Murphy 2017-04-06 18:11 ` [RESEND,1/3] " Manoj Iyer 2017-04-06 18:11 ` Manoj Iyer 2017-03-31 14:46 ` Robin Murphy [this message] 2017-03-31 14:46 ` [PATCH RESEND 2/3] iommu/dma: Clean up MSI IOVA allocation Robin Murphy 2017-04-06 18:14 ` [RESEND,2/3] " Manoj Iyer 2017-04-06 18:14 ` Manoj Iyer 2017-03-31 14:46 ` [PATCH RESEND 3/3] iommu/dma: Plumb in the per-CPU IOVA caches Robin Murphy 2017-03-31 14:46 ` Robin Murphy 2017-04-06 18:15 ` [RESEND,3/3] " Manoj Iyer 2017-04-06 18:15 ` Manoj Iyer 2017-04-06 18:56 ` Robin Murphy 2017-04-06 18:56 ` Robin Murphy [not found] ` <c43b1f8f-02fd-978c-0dee-cc3f76a9924b-5wv7dgnIgG8@public.gmane.org> 2017-04-07 7:22 ` Nate Watterson 2017-04-07 7:22 ` Nate Watterson 2017-04-03 10:45 ` [PATCH RESEND 0/3] IOVA allocation improvements for iommu-dma Joerg Roedel 2017-04-03 10:45 ` Joerg Roedel
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=0d9ed41de4b88964e5bd0d653eed1094959e7276.1490971180.git.robin.murphy@arm.com \ --to=robin.murphy-5wv7dgnigg8@public.gmane.org \ --cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \ --cc=joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org \ --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.