From patchwork Thu Jun 7 08:44:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 926202 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=kvm-ppc-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ozlabs.ru Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 411fH80S9fzB3sh for ; Thu, 7 Jun 2018 18:44:36 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753325AbeFGIod (ORCPT ); Thu, 7 Jun 2018 04:44:33 -0400 Received: from 107-173-13-209-host.colocrossing.com ([107.173.13.209]:33078 "EHLO ozlabs.ru" rhost-flags-OK-FAIL-OK-OK) by vger.kernel.org with ESMTP id S932569AbeFGIob (ORCPT ); Thu, 7 Jun 2018 04:44:31 -0400 Received: from vpl1.ozlabs.ibm.com (localhost [IPv6:::1]) by ozlabs.ru (Postfix) with ESMTP id 3DF25AE8003B; Thu, 7 Jun 2018 04:43:23 -0400 (EDT) From: Alexey Kardashevskiy To: linuxppc-dev@lists.ozlabs.org Cc: Alexey Kardashevskiy , David Gibson , kvm-ppc@vger.kernel.org, Alex Williamson , Benjamin Herrenschmidt , Ram Pai , kvm@vger.kernel.org, Alistair Popple Subject: [RFC PATCH kernel 2/5] powerpc/iommu_context: Change referencing in API Date: Thu, 7 Jun 2018 18:44:17 +1000 Message-Id: <20180607084420.29513-3-aik@ozlabs.ru> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20180607084420.29513-1-aik@ozlabs.ru> References: <20180607084420.29513-1-aik@ozlabs.ru> Sender: kvm-ppc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm-ppc@vger.kernel.org At the moment a single function - mm_iommu_get() - allocates a new region or just references it if it is already registered with the current MM context. We are going to allow API to be used for memory devices and different variant of mm_iommu_get() will be needed so let's move referencing part to where it belongs - mm_iommu_find(). This turns mm_iommu_get() into a wrapper as the actual function will be extended later and renames it to mm_iommu_new() to illustrate the change. Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/include/asm/mmu_context.h | 2 +- arch/powerpc/mm/mmu_context_iommu.c | 19 +++++++++++++++---- drivers/vfio/vfio_iommu_spapr_tce.c | 21 +++++++++++---------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 1835ca1..b598ec4 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -21,7 +21,7 @@ struct mm_iommu_table_group_mem_t; extern int isolate_lru_page(struct page *page); /* from internal.h */ extern bool mm_iommu_preregistered(struct mm_struct *mm); -extern long mm_iommu_get(struct mm_struct *mm, +extern long mm_iommu_new(struct mm_struct *mm, unsigned long ua, unsigned long entries, struct mm_iommu_table_group_mem_t **pmem); extern long mm_iommu_put(struct mm_struct *mm, diff --git a/arch/powerpc/mm/mmu_context_iommu.c b/arch/powerpc/mm/mmu_context_iommu.c index 4c615fc..6b471d2 100644 --- a/arch/powerpc/mm/mmu_context_iommu.c +++ b/arch/powerpc/mm/mmu_context_iommu.c @@ -120,7 +120,8 @@ static int mm_iommu_move_page_from_cma(struct page *page) return 0; } -long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries, +static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua, + unsigned long entries, struct mm_iommu_table_group_mem_t **pmem) { struct mm_iommu_table_group_mem_t *mem; @@ -132,8 +133,7 @@ long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries, list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) { if ((mem->ua == ua) && (mem->entries == entries)) { - ++mem->used; - *pmem = mem; + ret = -EBUSY; goto unlock_exit; } @@ -218,7 +218,13 @@ long mm_iommu_get(struct mm_struct *mm, unsigned long ua, unsigned long entries, return ret; } -EXPORT_SYMBOL_GPL(mm_iommu_get); + +long mm_iommu_new(struct mm_struct *mm, unsigned long ua, unsigned long entries, + struct mm_iommu_table_group_mem_t **pmem) +{ + return mm_iommu_do_alloc(mm, ua, entries, pmem); +} +EXPORT_SYMBOL_GPL(mm_iommu_new); static void mm_iommu_unpin(struct mm_iommu_table_group_mem_t *mem) { @@ -337,13 +343,18 @@ struct mm_iommu_table_group_mem_t *mm_iommu_find(struct mm_struct *mm, { struct mm_iommu_table_group_mem_t *mem, *ret = NULL; + mutex_lock(&mem_list_mutex); + list_for_each_entry_rcu(mem, &mm->context.iommu_group_mem_list, next) { if ((mem->ua == ua) && (mem->entries == entries)) { ret = mem; + ++mem->used; break; } } + mutex_unlock(&mem_list_mutex); + return ret; } EXPORT_SYMBOL_GPL(mm_iommu_find); diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 2c4a048..7f1effd 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -149,9 +149,9 @@ static long tce_iommu_prereg_free(struct tce_container *container, static long tce_iommu_unregister_pages(struct tce_container *container, __u64 vaddr, __u64 size) { + long ret = -ENOENT; struct mm_iommu_table_group_mem_t *mem; struct tce_iommu_prereg *tcemem; - bool found = false; if ((vaddr & ~PAGE_MASK) || (size & ~PAGE_MASK)) return -EINVAL; @@ -162,15 +162,14 @@ static long tce_iommu_unregister_pages(struct tce_container *container, list_for_each_entry(tcemem, &container->prereg_list, next) { if (tcemem->mem == mem) { - found = true; + ret = tce_iommu_prereg_free(container, tcemem); break; } } - if (!found) - return -ENOENT; + mm_iommu_put(container->mm, mem); - return tce_iommu_prereg_free(container, tcemem); + return ret; } static long tce_iommu_register_pages(struct tce_container *container, @@ -188,15 +187,17 @@ static long tce_iommu_register_pages(struct tce_container *container, mem = mm_iommu_find(container->mm, vaddr, entries); if (mem) { list_for_each_entry(tcemem, &container->prereg_list, next) { - if (tcemem->mem == mem) + if (tcemem->mem == mem) { + mm_iommu_put(container->mm, mem); return -EBUSY; + } } + } else { + ret = mm_iommu_new(container->mm, vaddr, entries, &mem); + if (ret) + return ret; } - ret = mm_iommu_get(container->mm, vaddr, entries, &mem); - if (ret) - return ret; - tcemem = kzalloc(sizeof(*tcemem), GFP_KERNEL); if (!tcemem) { mm_iommu_put(container->mm, mem);