From patchwork Wed Jul 5 18:12:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Schneider X-Patchwork-Id: 13302580 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D1DDC001DD for ; Wed, 5 Jul 2023 18:17:27 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C73B38D0001; Wed, 5 Jul 2023 14:17:26 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C248D8E0005; Wed, 5 Jul 2023 14:17:26 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A75DC8D0008; Wed, 5 Jul 2023 14:17:26 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 982DF8D0001 for ; Wed, 5 Jul 2023 14:17:26 -0400 (EDT) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 53F25805E0 for ; Wed, 5 Jul 2023 18:17:26 +0000 (UTC) X-FDA: 80978365692.05.309E72B Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by imf30.hostedemail.com (Postfix) with ESMTP id 657688000D for ; Wed, 5 Jul 2023 18:17:24 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=ae9gCaxE; dmarc=pass (policy=none) header.from=redhat.com; spf=pass (imf30.hostedemail.com: domain of vschneid@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=vschneid@redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1688581044; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=4KAtt5Wg9gvWlallwwTPlSO2JwaIw83isELp5cjnhmg=; b=ZSdhiXwLoSe/E9nbrKnYQfC+/JuyUThr5iX4Y1k8OMxQtrbg7fxe7vwLm9847GR5wpJm4r 8o8JhucNLmQB61oCFOa3mvUYSgr0n8MuPRn5MhLDaSp+umfsqeTiQdFUu8MSmnaAa8fw0c uV4Yna+5MLx+QCvKswkK8I+JJg4YROI= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=ae9gCaxE; dmarc=pass (policy=none) header.from=redhat.com; spf=pass (imf30.hostedemail.com: domain of vschneid@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=vschneid@redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1688581044; a=rsa-sha256; cv=none; b=zrNmT6dZU+yqSkDh02mVWbNdeE7ngLBFtLC1/VXA+RRbrnpiB8m1lmBbV9Q+HTCaV0w5Tk +sr8VHsiP2fQ8Xhz8AM4HJ/SXi5db8dhPHNj4D7BvCzI5HdFCVdecKLoQiO+7dOhxwKkS7 tFNQ962BMi/h2Li+nXErA56ZhQUG8hE= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1688581043; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4KAtt5Wg9gvWlallwwTPlSO2JwaIw83isELp5cjnhmg=; b=ae9gCaxEYhRAv9XSoYw/N4dRcCwBAggHbxEZ4QoJQCW//SNUFeoQum8l+0eHXutZK6xVTp y32yP0KSHIPihyeysaHcb+PzunD6XFGc8pPqyUPs7mcBcze7YstlgQgb+K+3jlN4KLU7pj z0OjK7V28el2zUAramA93Qw7mBkStY8= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-376-XnGbn6mUOsqBjFOroOxxLg-1; Wed, 05 Jul 2023 14:17:22 -0400 X-MC-Unique: XnGbn6mUOsqBjFOroOxxLg-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 48B262808E60; Wed, 5 Jul 2023 18:17:20 +0000 (UTC) Received: from vschneid.remote.csb (unknown [10.42.28.164]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7229918EB4; Wed, 5 Jul 2023 18:17:15 +0000 (UTC) From: Valentin Schneider To: linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org, linux-doc@vger.kernel.org, kvm@vger.kernel.org, linux-mm@kvack.org, bpf@vger.kernel.org, x86@kernel.org Cc: Steven Rostedt , Masami Hiramatsu , Jonathan Corbet , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , "H. Peter Anvin" , Paolo Bonzini , Wanpeng Li , Vitaly Kuznetsov , Andy Lutomirski , Peter Zijlstra , Frederic Weisbecker , "Paul E. McKenney" , Andrew Morton , Uladzislau Rezki , Christoph Hellwig , Lorenzo Stoakes , Josh Poimboeuf , Kees Cook , Sami Tolvanen , Ard Biesheuvel , Nicholas Piggin , Juerg Haefliger , Nicolas Saenz Julienne , "Kirill A. Shutemov" , Nadav Amit , Dan Carpenter , Chuang Wang , Yang Jihong , Petr Mladek , "Jason A. Donenfeld" , Song Liu , Julian Pidancet , Tom Lendacky , Dionna Glaze , =?utf-8?q?Thomas_Wei=C3=9Fschuh?= , Juri Lelli , Daniel Bristot de Oliveira , Marcelo Tosatti , Yair Podemsky Subject: [RFC PATCH 14/14] x86/mm, mm/vmalloc: Defer flush_tlb_kernel_range() targeting NOHZ_FULL CPUs Date: Wed, 5 Jul 2023 19:12:56 +0100 Message-Id: <20230705181256.3539027-15-vschneid@redhat.com> In-Reply-To: <20230705181256.3539027-1-vschneid@redhat.com> References: <20230705181256.3539027-1-vschneid@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 X-Rspam-User: X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: 657688000D X-Stat-Signature: ktdcb4qx14gzeg5rosqogob4nm56easo X-HE-Tag: 1688581044-471107 X-HE-Meta: U2FsdGVkX189mmulR6Pm1dKrCEiUZwoGyEisfWV3M0PwOIbpBWkyLiMsGXrDkJ/H5vnsSoZhU3hZqXBJ2aNtad0NZjPw//bzf3hGb44m186/szDRN3mZAWqqpfkEdDEwpxAftXyOYkPQv/PfvS6WIdc+Ajrv1EBnxEHFNEGAVRTA02zp6jYqxwgL8eqOTYLN1xQSKf7qsYKNpr6gBbBrrS7mh2DRwU/b0OYJUZ6fBxmgMO0ByxkWHMnvtS/ZRTKAUYjb+36gqQHDNACJjkMCb3e39or/pPG5gIb35eVBQ2ABIss/6IB9kMhQ+t4Dk/XefdxrvzJS3UCqlJWq69LECM/zSeQwAoWdMHgMbLTRPYLeHfTa5uFcO1dbgoPmV+7qNdtwanfRNCu//7XTOkUCmvnesNIGQiJYcrfkGmZbHi5Zv3ldSTWPrVU+Zt5hPM4GiQRx2sb0Sy9lxhihRTJRtEt6CB6UQHXzpclZSzLxayzgmd0PzvRmZUFfZxcenpTVLlWFc7LTLgdvCHBDZh4kbiA8APfd+Zi6Xx+7u/UEV/rGevQvmGpRUx0D5m2p/WmLw8EN9KrHjA68YytjK89r5FZE92nxlD+O3JwUoYl2Xth+tJNBbM8+WLSiHfIsplAKkVeQKPvIgStr7P49Gk7T+2NpKTIXs3N+eTRitpRwZx3mIuk5MvHx3RbDKaRGarL5psBV8+VHboB5szl6ZxwQppMDr2MB+fzUH3C+f7QUQFRrG4KJUoyBXm2bMI36VRmnltOk2Jf8Yq+5r4A9Z2UWFxMsfQW7vc4rjh5inEyS+r2wxllQxo0VEvLuHPa+wnBb/QtDmNGLbIh6xzKv3owcajmhp5RTpphvFF69E49XQGIy5hu/sRblKSlCv+0UZVaAHtj0HtogiL851FWvd46XEg8k76DndpLC4Yg9pgHW7FqCgwgFwhpcVLgV7yx92ZEvuB2F7yqmsj3IcC1gfZl VxeeX+TL NSRd8we8yR+8x8nozb+7rRUo7qVAzk2PIV7ZDyRYGpnR55Z0yPa36SfLt0CWA4wqkLqbaGGvVCJBMOm7d2GrK/8DeV1jwuUOGKWFmBK7IatXEFEg0oeaa6lic+JxBPxdiLAQqAfeyJCMkr3BMKLiMOeTeRrSMLkZc2p69ORtO0t5IW9OGua0uqM/Ri42yeL6lMsAflxBhw9/Av3y7dKutjdoXnR0BYkjf8wgm X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: vunmap()'s issued from housekeeping CPUs are a relatively common source of interference for isolated NOHZ_FULL CPUs, as they are hit by the flush_tlb_kernel_range() IPIs. Given that CPUs executing in userspace do not access data in the vmalloc range, these IPIs could be deferred until their next kernel entry. This does require a guarantee that nothing in the vmalloc range can be accessed in early entry code. vmalloc'd kernel stacks (VMAP_STACK) are AFAICT a safe exception, as a task running in userspace needs to enter kernelspace to execute do_exit() before its stack can be vfree'd. XXX: Validation that nothing in the vmalloc range is accessed in .noinstr or somesuch? Blindly deferring any and all flush of the kernel mappings is a risky move, so introduce a variant of flush_tlb_kernel_range() that explicitly allows deferral. Use it for vunmap flushes. Note that while flush_tlb_kernel_range() may end up issuing a full flush (including user mappings), this only happens when reaching a invalidation range threshold where it is cheaper to do a full flush than to individually invalidate each page in the range via INVLPG. IOW, it doesn't *require* invalidating user mappings, and thus remains safe to defer until a later kernel entry. Signed-off-by: Valentin Schneider --- arch/x86/include/asm/tlbflush.h | 1 + arch/x86/mm/tlb.c | 23 ++++++++++++++++++++--- mm/vmalloc.c | 15 ++++++++++----- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index 9064aa0027d05..2b3605c09649c 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h @@ -255,6 +255,7 @@ extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start, unsigned long end, unsigned int stride_shift, bool freed_tables); extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); +extern void flush_tlb_kernel_range_deferrable(unsigned long start, unsigned long end); static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long a) { diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 631df9189ded4..bb18b35e61b4a 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -1045,6 +1046,11 @@ static void do_flush_tlb_all(void *info) __flush_tlb_all(); } +static bool do_kernel_flush_defer_cond(int cpu, void *info) +{ + return !ct_set_cpu_work(cpu, CONTEXT_WORK_TLBI); +} + void flush_tlb_all(void) { count_vm_tlb_event(NR_TLB_REMOTE_FLUSH); @@ -1061,12 +1067,13 @@ static void do_kernel_range_flush(void *info) flush_tlb_one_kernel(addr); } -void flush_tlb_kernel_range(unsigned long start, unsigned long end) +static inline void +__flush_tlb_kernel_range(smp_cond_func_t cond_func, unsigned long start, unsigned long end) { /* Balance as user space task's flush, a bit conservative */ if (end == TLB_FLUSH_ALL || (end - start) > tlb_single_page_flush_ceiling << PAGE_SHIFT) { - on_each_cpu(do_flush_tlb_all, NULL, 1); + on_each_cpu_cond(cond_func, do_flush_tlb_all, NULL, 1); } else { struct flush_tlb_info *info; @@ -1074,13 +1081,23 @@ void flush_tlb_kernel_range(unsigned long start, unsigned long end) info = get_flush_tlb_info(NULL, start, end, 0, false, TLB_GENERATION_INVALID); - on_each_cpu(do_kernel_range_flush, info, 1); + on_each_cpu_cond(cond_func, do_kernel_range_flush, info, 1); put_flush_tlb_info(); preempt_enable(); } } +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + __flush_tlb_kernel_range(NULL, start, end); +} + +void flush_tlb_kernel_range_deferrable(unsigned long start, unsigned long end) +{ + __flush_tlb_kernel_range(do_kernel_flush_defer_cond, start, end); +} + /* * This can be used from process context to figure out what the value of * CR3 is without needing to do a (slow) __read_cr3(). diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 1d13d71687d73..10f99224e12e0 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -439,6 +439,11 @@ void vunmap_range_noflush(unsigned long start, unsigned long end) __vunmap_range_noflush(start, end); } +#ifndef flush_tlb_kernel_range_deferrable +#define flush_tlb_kernel_range_deferrable(start, end) \ + flush_tlb_kernel_range(start, end) +#endif + /** * vunmap_range - unmap kernel virtual addresses * @addr: start of the VM area to unmap @@ -452,7 +457,7 @@ void vunmap_range(unsigned long addr, unsigned long end) { flush_cache_vunmap(addr, end); vunmap_range_noflush(addr, end); - flush_tlb_kernel_range(addr, end); + flush_tlb_kernel_range_deferrable(addr, end); } static int vmap_pages_pte_range(pmd_t *pmd, unsigned long addr, @@ -1747,7 +1752,7 @@ static bool __purge_vmap_area_lazy(unsigned long start, unsigned long end) list_last_entry(&local_purge_list, struct vmap_area, list)->va_end); - flush_tlb_kernel_range(start, end); + flush_tlb_kernel_range_deferrable(start, end); resched_threshold = lazy_max_pages() << 1; spin_lock(&free_vmap_area_lock); @@ -1849,7 +1854,7 @@ static void free_unmap_vmap_area(struct vmap_area *va) flush_cache_vunmap(va->va_start, va->va_end); vunmap_range_noflush(va->va_start, va->va_end); if (debug_pagealloc_enabled_static()) - flush_tlb_kernel_range(va->va_start, va->va_end); + flush_tlb_kernel_range_deferrable(va->va_start, va->va_end); free_vmap_area_noflush(va); } @@ -2207,7 +2212,7 @@ static void vb_free(unsigned long addr, unsigned long size) vunmap_range_noflush(addr, addr + size); if (debug_pagealloc_enabled_static()) - flush_tlb_kernel_range(addr, addr + size); + flush_tlb_kernel_range_deferrable(addr, addr + size); spin_lock(&vb->lock); @@ -2260,7 +2265,7 @@ static void _vm_unmap_aliases(unsigned long start, unsigned long end, int flush) mutex_lock(&vmap_purge_lock); purge_fragmented_blocks_allcpus(); if (!__purge_vmap_area_lazy(start, end) && flush) - flush_tlb_kernel_range(start, end); + flush_tlb_kernel_range_deferrable(start, end); mutex_unlock(&vmap_purge_lock); }