Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751925AbdL0JVF (ORCPT ); Wed, 27 Dec 2017 04:21:05 -0500 Received: from mail-sn1nam02on0046.outbound.protection.outlook.com ([104.47.36.46]:43692 "EHLO NAM02-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751888AbdL0JVA (ORCPT ); Wed, 27 Dec 2017 04:21:00 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Suravee.Suthikulpanit@amd.com; From: Suravee Suthikulpanit To: linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org Cc: joro@8bytes.org, jroedel@suse.de, alex.williamson@redhat.com, Suravee Suthikulpanit Subject: [RFC PATCH v2 1/2] vfio/type1: Adopt fast IOTLB flush interface when unmap IOVAs Date: Wed, 27 Dec 2017 04:20:34 -0500 Message-Id: <1514366435-12723-2-git-send-email-suravee.suthikulpanit@amd.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1514366435-12723-1-git-send-email-suravee.suthikulpanit@amd.com> References: <1514366435-12723-1-git-send-email-suravee.suthikulpanit@amd.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [114.109.128.54] X-ClientProxiedBy: HK2PR02CA0155.apcprd02.prod.outlook.com (10.171.30.15) To MWHPR12MB1742.namprd12.prod.outlook.com (10.175.55.13) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 101733d4-6f51-48a5-e6f9-08d54d0b23c8 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(4534020)(4602075)(4627115)(201703031133081)(201702281549075)(5600026)(4604075)(48565401081)(2017052603307)(7153060);SRVR:MWHPR12MB1742; X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1742;3:2ah0eIz/QnLCQPcR9HwVp9t5zFT9bsBncXreJhGCfiHeS+GJYTLmPZK7sxnDPjrkmC/TjA7U7GFEsEOqKE/5YpOpEQwiBF2f0HpifoIHkgG7XJii6Rgi9iCH/0PLQqVRX6w1GYXphLm5cOmonMy/kYZ9Kia9G0Z/PpfYQim0er1eqL7OBnDvvuKhnFC/V4gVuymvCsr5CWVC3Zpv2QyzPINln+ARxwZ1asO4YwOfMdNa8Rvsi8BwTlKgb4pHOrhc;25:WBppp39LDdGs+hv2Ffgs6RutPHNShaymPTolsSKZFfkjjoXxh4c2LAn+s4esA1RupCMqOkp8pU6Dl6l3P0QVI2a0JJJFrdLFqyYip4TyN9hY5VVOjJngLuC3bnhR8umfnVvjw4vuLJ2MXlmQHWhyIhp18qVuQghZX6sEvfa1wTCC5wCQsfLi0wUjFJhozyccbT2scTgfMgFXESdGUgRm32yzvoDOvGfDnlH+mUcUcnGnli4/bQlUfYuStKZdqp7yb70O0qdWBHOUctFCu4+epfATc37J6uR1DVDdKxQgHwCe24+P4xjUKYHtBRM8oqW4yBT4WKxEPZ7YyG+/p9kihw==;31:MjyBv20zsIHymbUnBEW5FIemV/Hdo6Of07dtzT5/yEgsPQppsmPW1xHOQBOMOfjYEdq2Ng/xxsdr2G7Ydi3Rm9yC1C8b5jHDI6itbme00V+aLmo8u58Ibcb4aBJjKdo+bPPCai06LSL0pPzjotgJtfH/48a1F9UrR1xOIx7sgRvalDfzyvoYmyto8wxIgT3pML0V2Pv0GdZOmN08Op8w4FBBTzzwfoKamUQjSrpG9a8= X-MS-TrafficTypeDiagnostic: MWHPR12MB1742: X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1742;20:qbu9xrz4z1mnj1ROTgDdAL6Lom6aHKr88bgOpTsGZuYQUk7RjyA9So0mPIiQur1wm0AfhMElmu+Ju8OSa6rhBndzgnbY8EeQeLKEn1wIR5i19XzQ4xRe9NVdPHahzZbrjmAISnVKhWWZIgEFQFRygQ733O5B6FVnF9/42JdUkD2+OQxleGIFIGtbzCVvIjGmBEhmKyR0ekBYn2CVu4BHUlb5X7JmfSN6mD/0hzxb8cO4gpuMnms1OPLoGdXsq8X8NMM3PLbpQLgsn2BkBAAI2Z3WPHSfi9TZE1QaZ1dst4ND4dVSO/b0tIzdSlc0K5/vCErNXid8bI0ahKW7Qf2GCe9Z9mq0sOzSniid9SMgIEhibon0B2lHnkYxXzZPqbp4b9NW+k5cJqkT47s9lCZfgV3Z+ACMR9cDeZgMQtcbWdTH2qJ3mgClIhDIjt5GbIsmnid74+XLvH5hT/BNFyPFmwRvWcdROIhzIQ7vHdr2ljzdHz75UrheVaudc5s5XFd2;4:YZClyASfBe18VepvbeStMAplrjy7WId6rFYJWaLzxmUKm39e8C0WUwiruCh6ExuUgZbmkp7Y3tRkrQ9UWgnwRcAHcNhVBcMXUngAPjUAwla5R353/u9B5Ch7qV62uJDeekW/Ou2pe/GvrsXcMJrZu6GbKrhrlhgA3YidRg6fxg/pGHEBHChf0Zvyi7Xa8fJyHTsPEGAyU3mpyssXye+L1V9jA4j2oXo70on8V66Ls9qjgDIRPrVLNs9nA77Eg9jP5h8QakXVR+ys0q3Lw3GwyRfG9Qs5slKvOMkU4ywAjSkkgugRV7yMImIOojs6twc7 X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040470)(2401047)(5005006)(8121501046)(3231023)(944501075)(93006095)(93001095)(10201501046)(3002001)(6055026)(6041268)(20161123564045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123560045)(20161123558120)(6072148)(201708071742011);SRVR:MWHPR12MB1742;BCL:0;PCL:0;RULEID:(100000803101)(100110400095);SRVR:MWHPR12MB1742; X-Forefront-PRVS: 0534947130 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(396003)(376002)(39380400002)(366004)(346002)(39860400002)(199004)(189003)(68736007)(25786009)(106356001)(105586002)(6486002)(8936002)(97736004)(66066001)(86362001)(47776003)(3846002)(6116002)(4720700003)(5660300001)(7736002)(305945005)(6666003)(2950100002)(8676002)(81166006)(81156014)(50226002)(72206003)(478600001)(316002)(16526018)(16586007)(2906002)(4326008)(59450400001)(53936002)(51416003)(50466002)(48376002)(6512007)(36756003)(52116002)(386003)(6506007)(76176011)(217873001);DIR:OUT;SFP:1101;SCL:1;SRVR:MWHPR12MB1742;H:ssuthiku-rhel74.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;MWHPR12MB1742;23:nJxOVdGFwGNGMUKhIrFFjjQvTAq5drRT0MHCdBLwO?= =?us-ascii?Q?gyFgsPeKVzqzM5s0DFUZZGxrNXhNK7TuJ14N12wjrS6+i6WF+FnhhZs0UlHa?= =?us-ascii?Q?mTUoyHC4w5AYJNOWfduarpSIHa2nmipzwqmle9IJWI/5vC1V5D/lOsC/yA6q?= =?us-ascii?Q?Fxho/G6GOo33xPBJvvGoTMUB7AMEdaz/Mz0556F0GCR57afCbQChAFnyGlCG?= =?us-ascii?Q?u656GjtOEAOV1Hrk/4PJwKt4788J9QIHGTK6mNxRoL45GdDEFJmbFF9OtG98?= =?us-ascii?Q?cMAogu0SE7OqxpcrTrzJ8VtBio4tSRwfm1s0RQPQ0Mtnl6GApr/5v2KmJ5Ra?= =?us-ascii?Q?I3asDxnZSN0oq68pBflH9ndAwxPU3SRmU91srRKPvsaUZgVO+rBZ0p4GIUyM?= =?us-ascii?Q?gRw3nw+YTW7Bx9W5HAu0iueGwTZThceLSzTKCaholrw+BQr/VgnV3WQU2pqi?= =?us-ascii?Q?fhr23jDa1tcEZEy3krLPC2ZoWmjPmlWMu58xDLfMb1jQOjmlMpDZf/lKJhqH?= =?us-ascii?Q?24r9fSNXd2DRTIi4VEmMRsU1+sLpS24ZINbO1eHp9obGQCW2rg0J4VAkyKQU?= =?us-ascii?Q?KlFPObUV2MJQkiuI/rDp7V8AKMHINUKFyhCupLpsmAHhSmDjuvorz7J5vPcv?= =?us-ascii?Q?n/E2oDKkM5vkG90HusmUhi5Gn9MnoPj5+h29ya0gC2fU1S/m7zGOJCwtNgDb?= =?us-ascii?Q?khYz+pZnDYlTLOrJnj9dNYGNOZA5H4qfNqH7/FI3kVdfBk+0ns4CQLzCn+gq?= =?us-ascii?Q?bh2Qz8S1/buAAYz3kF3gpFNzgmPDv80kwVzzqe1f7jxVcHWWAu2je6P22RK2?= =?us-ascii?Q?+D22/dgR7H0ogCAd6O2iLKKKJnNdzudWWpSHC1as0s28lDr6D9b8DysVZcdx?= =?us-ascii?Q?KpCuyk4jYxltp52zXdMwmC63q+z13ett1nA2AgWUhuHUX5ake7AiSprGOUWx?= =?us-ascii?Q?+deSzgcWHKq3Wh7ywOmSTA3X7Q9Gf3NgtD9XRZagaFnuwBVq4hJ8KVcJ9UbI?= =?us-ascii?Q?pB5tvFOTHPEmsaEyCCsFxkoZPDH2e1opiKthQRC3tTJ0K9+UxI0BBAzQ6F2P?= =?us-ascii?Q?mEqUbEEgfgU9TiuUhthzuW0Tk4K5KAXGyfzK8TwncFcNf2SzAgtSQzvYKWuU?= =?us-ascii?Q?XyNdz2P17MJnKIs+ethYkYEVz/irZpH?= X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1742;6:bNW6Dpdc0VeX3R3PrTlUfNRsAMGYDKENFuYvqiWmUH6Hhq1+96LXMM7wqXXWFj6VtHLChOi3ODqaQ8vKQR2FLXCY4b2DgIZjOjcUMxE7YXYEptuYJmy/0UUkooE2BAqHoVZXjAHjC0ckpYm6e6LrTRZSfBKRHzx19PYTXKsmr/7QQz8QME4/ru7lhuVM8WR21er+2ZJZ3j+Gal1Jst/I/eeSUct4ZnTx+fOWBpJFhbw8FkThm8/h2vJJJn2jEfO+OFUtll664zbeu31myrFFRPdCFRT9sOV8a24wTinsi4cuucBuw/FB3bCZXmEQFswNYt+Hc+5dQr3QeTQ4MUutSL19WOxj/DvTasW3Lntx+Sw=;5:SIY/mWvIdzRFkFokedhzBo2nkq/pY5pApqa5RzMvSzY46AhztFWaMTeIkdhqG4+hAm4xRO/WjG4VRLMOFCf09BSHBnDH2lXpJqoCrm3bpCrnpxpUO1gW2HA12yP8WkRl4/dsg7K/a0Wx3ZDGkGPeUJpUaCwe3jOOQhGDUNE8iUQ=;24:yhGJPa1avkzz34/KPe5tHPJIo94UTjflTLGLOc7/eIJEO44Sj/ct5vBI8SZ1btaiQD2p9FBj4pXOq3xekRzSzfbiDSS3kJKHhQ0ReM7T0xA=;7:6/f4OJNKw0itr/elEIwesA+aR4/6GMVibCgHmkVE2oXygvfA7IK7wFIwSC/MmdzpmR1Csj4o6Fn8kKiNDJweTA0XWURmXheED042iPQd3jviAPNerxBNSpiuMb+ATVX8CG7kEudQTgtDTQAINFHLzVBrhhwYgaz+ts74HIdx9SBshfpEapMWWdC21yC/B6GzyIAsyfGcYqp8LI6t4hM8Dn4vnIwwT5+iRfgHTI5fTSI+iNq5YdLB4ZLw55vtlbA5 SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;MWHPR12MB1742;20:xUNrV2V+1mhA/bhzTjTmuxOs6RQe2DfjazFQfAaUrahGWtyeX5Jziam+Ac/gEeFbyVo47NdYdCfnCdNVy7CsQ4wWoudc819ps3/GiJQUDwhY+WRoCnBm33tap31pw4mwF0aEYTTRIQHfkL5XPjYEVMLtUKOoCv6oViI3RJgKfQl/psFZIHacNhV/r04vbLfd60+9IfUU8Enlvwxhivnto6jv+t955ouiV1uJbZuaNqz/aIXdO73xWPr8UfFLiAn8 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 27 Dec 2017 09:20:56.2984 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 101733d4-6f51-48a5-e6f9-08d54d0b23c8 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1742 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4824 Lines: 167 VFIO IOMMU type1 currently upmaps IOVA pages synchronously, which requires IOTLB flushing for every unmapping. This results in large IOTLB flushing overhead when handling pass-through devices has a large number of mapped IOVAs. This can be avoided by using the new IOTLB flushing interface. Cc: Alex Williamson Cc: Joerg Roedel Signed-off-by: Suravee Suthikulpanit --- drivers/vfio/vfio_iommu_type1.c | 89 +++++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 12 deletions(-) diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index e30e29a..f000844 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -102,6 +102,13 @@ struct vfio_pfn { atomic_t ref_count; }; +struct vfio_regions{ + struct list_head list; + dma_addr_t iova; + phys_addr_t phys; + size_t len; +}; + #define IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu) \ (!list_empty(&iommu->domain_list)) @@ -479,6 +486,40 @@ static long vfio_unpin_pages_remote(struct vfio_dma *dma, dma_addr_t iova, return unlocked; } +/* + * Generally, VFIO needs to unpin remote pages after each IOTLB flush. + * Therefore, when using IOTLB flush sync interface, VFIO need to keep track + * of these regions (currently using a list). + * + * This value specifies maximum number of regions for each IOTLB flush sync. + */ +#define VFIO_IOMMU_TLB_SYNC_MAX 512 + +static long vfio_sync_and_unpin(struct vfio_dma *dma, struct vfio_domain *domain, + struct list_head *regions, bool do_accounting) +{ + long unlocked = 0; + struct vfio_regions *entry, *next; + + iommu_tlb_sync(domain->domain); + + list_for_each_entry_safe(entry, next, regions, list) { + unlocked += vfio_unpin_pages_remote(dma, + entry->iova, + entry->phys >> PAGE_SHIFT, + entry->len >> PAGE_SHIFT, + false); + list_del(&entry->list); + kfree(entry); + } + + if (do_accounting) { + vfio_lock_acct(dma->task, -unlocked, NULL); + return 0; + } + return unlocked; +} + static int vfio_pin_page_external(struct vfio_dma *dma, unsigned long vaddr, unsigned long *pfn_base, bool do_accounting) { @@ -653,7 +694,10 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma, { dma_addr_t iova = dma->iova, end = dma->iova + dma->size; struct vfio_domain *domain, *d; + struct list_head unmapped_regions; + struct vfio_regions *entry; long unlocked = 0; + int cnt = 0; if (!dma->size) return 0; @@ -661,6 +705,8 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma, if (!IS_IOMMU_CAP_DOMAIN_IN_CONTAINER(iommu)) return 0; + INIT_LIST_HEAD(&unmapped_regions); + /* * We use the IOMMU to track the physical addresses, otherwise we'd * need a much more complicated tracking system. Unfortunately that @@ -698,24 +744,36 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma, break; } - unmapped = iommu_unmap(domain->domain, iova, len); - if (WARN_ON(!unmapped)) + entry = kzalloc(sizeof(*entry), GFP_KERNEL); + if (!entry) break; - unlocked += vfio_unpin_pages_remote(dma, iova, - phys >> PAGE_SHIFT, - unmapped >> PAGE_SHIFT, - false); + unmapped = iommu_unmap_fast(domain->domain, iova, len); + if (WARN_ON(!unmapped)) { + kfree(entry); + break; + } + + iommu_tlb_range_add(domain->domain, iova, unmapped); + entry->iova = iova; + entry->phys = phys; + entry->len = unmapped; + list_add_tail(&entry->list, &unmapped_regions); + cnt++; iova += unmapped; + if (cnt >= VFIO_IOMMU_TLB_SYNC_MAX) { + unlocked += vfio_sync_and_unpin(dma, domain, &unmapped_regions, + do_accounting); + cnt = 0; + } cond_resched(); } + if (cnt) + unlocked += vfio_sync_and_unpin(dma, domain, &unmapped_regions, + do_accounting); dma->iommu_mapped = false; - if (do_accounting) { - vfio_lock_acct(dma->task, -unlocked, NULL); - return 0; - } return unlocked; } @@ -878,6 +936,7 @@ static int map_try_harder(struct vfio_domain *domain, dma_addr_t iova, { long i; int ret = 0; + size_t unmapped = 0; for (i = 0; i < npage; i++, pfn++, iova += PAGE_SIZE) { ret = iommu_map(domain->domain, iova, @@ -887,8 +946,14 @@ static int map_try_harder(struct vfio_domain *domain, dma_addr_t iova, break; } - for (; i < npage && i > 0; i--, iova -= PAGE_SIZE) - iommu_unmap(domain->domain, iova, PAGE_SIZE); + for (; i < npage && i > 0; i--, iova -= PAGE_SIZE) { + unmapped = iommu_unmap_fast(domain->domain, iova, PAGE_SIZE); + if (WARN_ON(!unmapped)) + break; + iommu_tlb_range_add(domain->domain, iova, unmapped); + } + if (unmapped) + iommu_tlb_sync(domain->domain); return ret; } -- 1.8.3.1