[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [PATCH] iommu: add preemption support to iommu_{un,}map()


  • To: Roger Pau Monne <roger.pau@xxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Henry Wang <Henry.Wang@xxxxxxx>
  • Date: Wed, 6 Jul 2022 07:31:07 +0000
  • Accept-language: zh-CN, en-US
  • Arc-authentication-results: i=2; mx.microsoft.com 1; spf=pass (sender ip is 63.35.35.123) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com; arc=pass (0 oda=1 ltdi=1 spf=[1,1,smtp.mailfrom=arm.com] dkim=[1,1,header.d=arm.com] dmarc=[1,1,header.from=arm.com])
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none
  • Arc-message-signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=md3rIj2LDbTz4axTFS01V8rBLYw1u5gaIdGmxouJJAc=; b=FVY0vkfFsasOj6XPrrhZM4cZGlWiOkxkZc6+8xwfMaHbW1cZReEU6EIhT+NHytWWi92S6A3ifnL1glyPvyEuxo2U8klM/ByXmTDOlsy0Z/tKx5jvN6OTlf1KTFNgOHWhbLGrsf262dWOFq6vAljxdCsrpl3C8QlNUUDvnqtlOaYixRgHLAtrC8xYO8cspYGMMOVJB97d/Qa4JL0xwJEmT47AyK8FyyjasTFVAiFVpwUEjZdlLdjaOGhA+8PWkRkxxTzIeDhiKQbIzW1LmCSAy70XlLrf8bWqoDaGoQV29SVgXUQMmEns1WLO7xOXmgz52cUBP0HLw2OAXSygf4Fwpw==
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=md3rIj2LDbTz4axTFS01V8rBLYw1u5gaIdGmxouJJAc=; b=L8bc90kAzmEwKHJNbDoHb1plDlcl/Yl83kQXRcnEOBegdVImqLSQJhlO1rcsDkgbJJb3/F8rKGq9A8PvoUircfBwSXEZX+RiG8Dt+67YkdYEFMzuSjxvTIPq5HnCzQflWzo3+1S2nIHCbEXEUoEz7Ezr2rKl7KcwCFI6yfwKKgnvt9U7SsYV+vI57XfrQEVKV2drvNyafVpbZrJuIRmBqRe50z3zvhOcF4BpJqLa8w/lks2NLdWyBDFY/Amuxsa+sQxN0C6Fiv/h1Syp0Lm5fKYqHHZBeg1yca0hdGepCuS2g9tI7C/dE3/tNSFIAAQpXqMmLAP6aknh3E57nBl/fA==
  • Arc-seal: i=2; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=pass; b=cQBymFvVxn42SkalXCFc0D8iytbQghAvwdfnURvWLwPBUlwbBMHpG8t6ICG0xAlIgdh2ic5que9pYHYSPVQ8cMYtcNsPZRaMqdhZZRE5YqR73bpDREj3sUW7dpx7CIyRA87dAvoEjCEa5iH5ZaR/TyFQ6CRajAzxZbAekGad1RNNgv2htwjQNxklMGFkUuaKZmBLrcJn/iTzdPm5hZ2nR7Ui4O/K0XgG5RsGQtlJAOhJUZAP2CP7n9d+kFIZNOCXtG10+sfFJvfhgBiL51QNNqLzIs18tzewhPgginbm9P5kXK6BbhAkSUGkaLPRi0tSBuPb0EI1a8QMitK4bfaVmg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FdodGb//XK0pVNwfS9mdd6QNFCy64O0CcuOeIjTOuT0yt9UYOJiRBMfN6o67xOucdMU5dImfff7YhQVHp3HVHDflDF0ZsLvo3ZVf8HWowOppuhNMQQNLXYAs1vU/5SUWrDTC3MYGhGbpMjaX1HImIl/upNUxx2m/E7ASrv9mxSP5UpI2HsdWFunQYiBxX+vZX7GjxvvxQ0lMlCiU7m5qmiOHGzea2YTRDgwJBy07qkUYx7YQ5jlL00/k8QNeu7kB8z4H+yl44n+aD6ftTjJZWdOxZC+nHgubLXr7egLtjg6c7W78/zpAqsOsEWmd6guT6jdzhqyng4HhUc9E37arCQ==
  • Authentication-results-original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Cc: Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Paul Durrant <paul@xxxxxxx>
  • Delivery-date: Wed, 06 Jul 2022 07:38:23 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Nodisclaimer: true
  • Original-authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com;
  • Thread-index: AQHYfKTqlNAQrdLOhUWuhz9XAirPe61xGNzw
  • Thread-topic: [PATCH] iommu: add preemption support to iommu_{un,}map()

Hi,

It seems that this patch has been stale for a month, with actions needed
from the author. So sending this email as a gentle reminder. Thanks!

Kind regards,
Henry

> -----Original Message-----
> Subject: [PATCH] iommu: add preemption support to iommu_{un,}map()
> 
> The loop in iommu_{un,}map() can be arbitrary large, and as such it
> needs to handle preemption.  Introduce a new parameter that allow
> returning the number of pages that have been processed, and which
> presence also signals whether the function should do preemption
> checks.
> 
> Note that the cleanup done in iommu_map() can now be incomplete if
> preemption has happened, and hence callers would need to take care of
> unmapping the whole range (ie: ranges already mapped by previously
> preempted calls).  So far none of the callers care about having those
> ranges unmapped, so error handling in iommu_memory_setup() and
> arch_iommu_hwdom_init() can be kept as-is.
> 
> Note that iommu_legacy_{un,}map() is left without preemption handling:
> callers of those interfaces are not modified to pass bigger chunks,
> and hence the functions won't be modified as are legacy and should be
> replaced with iommu_{un,}map() instead if preemption is required.
> 
> Fixes: f3185c165d ('IOMMU/x86: perform PV Dom0 mappings in batches')
> Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
> ---
>  xen/arch/x86/pv/dom0_build.c        | 15 ++++++++++++---
>  xen/drivers/passthrough/iommu.c     | 26 +++++++++++++++++++-------
>  xen/drivers/passthrough/x86/iommu.c | 13 +++++++++++--
>  xen/include/xen/iommu.h             |  4 ++--
>  4 files changed, 44 insertions(+), 14 deletions(-)
> 
> diff --git a/xen/arch/x86/pv/dom0_build.c b/xen/arch/x86/pv/dom0_build.c
> index 04a4ea3c18..e5a42870ec 100644
> --- a/xen/arch/x86/pv/dom0_build.c
> +++ b/xen/arch/x86/pv/dom0_build.c
> @@ -77,7 +77,8 @@ static __init void mark_pv_pt_pages_rdonly(struct
> domain *d,
>           * iommu_memory_setup() ended up mapping them.
>           */
>          if ( need_iommu_pt_sync(d) &&
> -             iommu_unmap(d, _dfn(mfn_x(page_to_mfn(page))), 1, flush_flags) )
> +             iommu_unmap(d, _dfn(mfn_x(page_to_mfn(page))), 1, flush_flags,
> +                         NULL) )
>              BUG();
> 
>          /* Read-only mapping + PGC_allocated + page-table page. */
> @@ -121,13 +122,21 @@ static void __init iommu_memory_setup(struct
> domain *d, const char *what,
>                                        unsigned int *flush_flags)
>  {
>      int rc;
> +    unsigned long done;
>      mfn_t mfn = page_to_mfn(page);
> 
>      if ( !need_iommu_pt_sync(d) )
>          return;
> 
> -    rc = iommu_map(d, _dfn(mfn_x(mfn)), mfn, nr,
> -                   IOMMUF_readable | IOMMUF_writable, flush_flags);
> +    while ( (rc = iommu_map(d, _dfn(mfn_x(mfn)), mfn, nr,
> +                            IOMMUF_readable | IOMMUF_writable,
> +                            flush_flags, &done)) == -ERESTART )
> +    {
> +        mfn_add(mfn, done);
> +        nr -= done;
> +        process_pending_softirqs();
> +    }
> +
>      if ( rc )
>      {
>          printk(XENLOG_ERR "pre-mapping %s MFN [%lx,%lx) into IOMMU
> failed: %d\n",
> diff --git a/xen/drivers/passthrough/iommu.c
> b/xen/drivers/passthrough/iommu.c
> index 75df3aa8dd..5c2a341112 100644
> --- a/xen/drivers/passthrough/iommu.c
> +++ b/xen/drivers/passthrough/iommu.c
> @@ -310,11 +310,11 @@ static unsigned int mapping_order(const struct
> domain_iommu *hd,
> 
>  int iommu_map(struct domain *d, dfn_t dfn0, mfn_t mfn0,
>                unsigned long page_count, unsigned int flags,
> -              unsigned int *flush_flags)
> +              unsigned int *flush_flags, unsigned long *done)
>  {
>      const struct domain_iommu *hd = dom_iommu(d);
>      unsigned long i;
> -    unsigned int order;
> +    unsigned int order, j = 0;
>      int rc = 0;
> 
>      if ( !is_iommu_enabled(d) )
> @@ -327,6 +327,12 @@ int iommu_map(struct domain *d, dfn_t dfn0,
> mfn_t mfn0,
>          dfn_t dfn = dfn_add(dfn0, i);
>          mfn_t mfn = mfn_add(mfn0, i);
> 
> +        if ( done && !(++j & 0xfffff) && general_preempt_check() )
> +        {
> +            *done = i;
> +            return -ERESTART;
> +        }
> +
>          order = mapping_order(hd, dfn, mfn, page_count - i);
> 
>          rc = iommu_call(hd->platform_ops, map_page, d, dfn, mfn,
> @@ -341,7 +347,7 @@ int iommu_map(struct domain *d, dfn_t dfn0, mfn_t
> mfn0,
>                     d->domain_id, dfn_x(dfn), mfn_x(mfn), rc);
> 
>          /* while statement to satisfy __must_check */
> -        while ( iommu_unmap(d, dfn0, i, flush_flags) )
> +        while ( iommu_unmap(d, dfn0, i, flush_flags, NULL) )
>              break;
> 
>          if ( !is_hardware_domain(d) )
> @@ -365,7 +371,7 @@ int iommu_legacy_map(struct domain *d, dfn_t dfn,
> mfn_t mfn,
>                       unsigned long page_count, unsigned int flags)
>  {
>      unsigned int flush_flags = 0;
> -    int rc = iommu_map(d, dfn, mfn, page_count, flags, &flush_flags);
> +    int rc = iommu_map(d, dfn, mfn, page_count, flags, &flush_flags, NULL);
> 
>      if ( !this_cpu(iommu_dont_flush_iotlb) && !rc )
>          rc = iommu_iotlb_flush(d, dfn, page_count, flush_flags);
> @@ -374,11 +380,11 @@ int iommu_legacy_map(struct domain *d, dfn_t
> dfn, mfn_t mfn,
>  }
> 
>  int iommu_unmap(struct domain *d, dfn_t dfn0, unsigned long page_count,
> -                unsigned int *flush_flags)
> +                unsigned int *flush_flags, unsigned long *done)
>  {
>      const struct domain_iommu *hd = dom_iommu(d);
>      unsigned long i;
> -    unsigned int order;
> +    unsigned int order, j = 0;
>      int rc = 0;
> 
>      if ( !is_iommu_enabled(d) )
> @@ -389,6 +395,12 @@ int iommu_unmap(struct domain *d, dfn_t dfn0,
> unsigned long page_count,
>          dfn_t dfn = dfn_add(dfn0, i);
>          int err;
> 
> +        if ( done && !(++j & 0xfffff) && general_preempt_check() )
> +        {
> +            *done = i;
> +            return -ERESTART;
> +        }
> +
>          order = mapping_order(hd, dfn, _mfn(0), page_count - i);
>          err = iommu_call(hd->platform_ops, unmap_page, d, dfn,
>                           order, flush_flags);
> @@ -425,7 +437,7 @@ int iommu_unmap(struct domain *d, dfn_t dfn0,
> unsigned long page_count,
>  int iommu_legacy_unmap(struct domain *d, dfn_t dfn, unsigned long
> page_count)
>  {
>      unsigned int flush_flags = 0;
> -    int rc = iommu_unmap(d, dfn, page_count, &flush_flags);
> +    int rc = iommu_unmap(d, dfn, page_count, &flush_flags, NULL);
> 
>      if ( !this_cpu(iommu_dont_flush_iotlb) && !rc )
>          rc = iommu_iotlb_flush(d, dfn, page_count, flush_flags);
> diff --git a/xen/drivers/passthrough/x86/iommu.c
> b/xen/drivers/passthrough/x86/iommu.c
> index 11a4f244e4..546e6dbe2a 100644
> --- a/xen/drivers/passthrough/x86/iommu.c
> +++ b/xen/drivers/passthrough/x86/iommu.c
> @@ -403,9 +403,18 @@ void __hwdom_init
> arch_iommu_hwdom_init(struct domain *d)
>          }
>          else if ( pfn != start + count || perms != start_perms )
>          {
> +            unsigned long done;
> +
>          commit:
> -            rc = iommu_map(d, _dfn(start), _mfn(start), count, start_perms,
> -                           &flush_flags);
> +            while ( (rc = iommu_map(d, _dfn(start), _mfn(start), count,
> +                                    start_perms, &flush_flags,
> +                                    &done)) == -ERESTART )
> +            {
> +                start += done;
> +                count -= done;
> +                process_pending_softirqs();
> +            }
> +
>              if ( rc )
>                  printk(XENLOG_WARNING
>                         "%pd: IOMMU identity mapping of [%lx,%lx) failed: 
> %d\n",
> diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h
> index 79529adf1f..e6643bcc1c 100644
> --- a/xen/include/xen/iommu.h
> +++ b/xen/include/xen/iommu.h
> @@ -155,10 +155,10 @@ enum
> 
>  int __must_check iommu_map(struct domain *d, dfn_t dfn, mfn_t mfn,
>                             unsigned long page_count, unsigned int flags,
> -                           unsigned int *flush_flags);
> +                           unsigned int *flush_flags, unsigned long *done);
>  int __must_check iommu_unmap(struct domain *d, dfn_t dfn,
>                               unsigned long page_count,
> -                             unsigned int *flush_flags);
> +                             unsigned int *flush_flags, unsigned long *done);
> 
>  int __must_check iommu_legacy_map(struct domain *d, dfn_t dfn, mfn_t
> mfn,
>                                    unsigned long page_count,
> --
> 2.36.1
> 


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.