From patchwork Wed Aug 3 18:28:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Fabio M. De Francesco" X-Patchwork-Id: 12935851 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 9C41BC19F28 for ; Wed, 3 Aug 2022 18:29:05 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id EC5748E0002; Wed, 3 Aug 2022 14:29:04 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id E747F8E0001; Wed, 3 Aug 2022 14:29:04 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id D63128E0002; Wed, 3 Aug 2022 14:29:04 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id C5EDE8E0001 for ; Wed, 3 Aug 2022 14:29:04 -0400 (EDT) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id 97EABA0189 for ; Wed, 3 Aug 2022 18:29:04 +0000 (UTC) X-FDA: 79759118208.26.F45274C Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) by imf06.hostedemail.com (Postfix) with ESMTP id 28605180004 for ; Wed, 3 Aug 2022 18:29:03 +0000 (UTC) Received: by mail-wm1-f45.google.com with SMTP id l19so2361180wms.1 for ; Wed, 03 Aug 2022 11:29:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=oJmOeTx06Lwu2fiuMzcG5dIKwqxwvQUWSEnoeJ++UWc=; b=JmYucQwk2UfoYXlb90FNHzTAHQvr9D2+kHxYT4XYngWqkCCo6RtGwUz21B785dhdnX HkOhgATfzaOWyr+haRcQpS3WeyVQuREVxWKzs6tbeX1P0XFo7iT1knUcUPeFeZXhxeIa dzjREPw6h/c4pQ8yu0R+vWm89jUE/h3QPVOFLzIzas+nhl+SzRRSRnhZq1Cqk9XUYXFK u1KWIqJ/t2fHBBHO07LINKBod4uH1YWiM2YxtS02l2hJb+lI69QBW9hbdDo/Pr1ZTrdK NKSg97XHPHVoSi7xj00wGu4sDNgaAFVS7KhVqm8IlwlM/paEm1YO3bDQjgXF3PgtecRl nmEQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=oJmOeTx06Lwu2fiuMzcG5dIKwqxwvQUWSEnoeJ++UWc=; b=hlPDDsf2yz01p3ksIifNEzpL1S6Xy5Gr4EsG6D97h9mogC+ZuJRuQ1fM/TsI9z3kbs DHdk2J9GygQwNNBp8sfNwCRDCF3cxrz5j5fKMPXewX2Fpy1mLlkgoDzR2DJ5+rhvV9WF 8xlM9+xlr8LgINj8pO9Ngbq4sCK+Qw0V2t6MrExMgnc9Lp+VIu6ihztI6EmS5Wzbetqf E6Jb2z+7gc3rLtvq7jQ1dU5C5xPkQeAlOma+qWKKf1puQB8dvFeNr5zEWtA+pPC8H0Xe 8j42fhvvDEc5F3B+A/vunmDGMOIG2kxcEA82ketBrZKdR1WErO7hyl6j6QE6QFx+juyr jJYw== X-Gm-Message-State: ACgBeo3qae7kUfGYWbAHIwW7pOkB00kAabXo+qWCFHDtZLpe8DN5am3j nVdAkL+okQo0Q+FVdBD53QY= X-Google-Smtp-Source: AA6agR5h2y2OSTJgWl3pVSJ+3Bg46IOFmOdhF2GtED5TKoijJMNG+N/aw/qjBuuNyHTQX2nQXHDtQA== X-Received: by 2002:a7b:ca48:0:b0:3a3:365d:1089 with SMTP id m8-20020a7bca48000000b003a3365d1089mr3853699wml.153.1659551342790; Wed, 03 Aug 2022 11:29:02 -0700 (PDT) Received: from localhost.localdomain (host-79-27-108-198.retail.telecomitalia.it. [79.27.108.198]) by smtp.gmail.com with ESMTPSA id m13-20020a05600c4f4d00b003a3200bc788sm3491904wmq.33.2022.08.03.11.28.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Aug 2022 11:29:01 -0700 (PDT) From: "Fabio M. De Francesco" To: Alexander Viro , Eric Biederman , Kees Cook , linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: "Fabio M. De Francesco" , Ira Weiny Subject: [PATCH v2] fs: Replace kmap{,_atomic}() with kmap_local_page() Date: Wed, 3 Aug 2022 20:28:56 +0200 Message-Id: <20220803182856.28246-1-fmdefrancesco@gmail.com> X-Mailer: git-send-email 2.37.1 MIME-Version: 1.0 ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1659551344; a=rsa-sha256; cv=none; b=F2FpL7S76c8GP4/EImE0JmH63uXELVIJWyabkY5bFZos0gVV+iu6DZ8uWK9HMMpLUIVyHO tBrcz/3tpvWqmpqavX039rTz7CbKoW8pR7ROlEbJ4HqRYmIbtSGo6NbnNOYfr2aFK3Issv /Ig0oSF6PGMUQlMtP6XuMbgzgIybvBo= ARC-Authentication-Results: i=1; imf06.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=JmYucQwk; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf06.hostedemail.com: domain of fmdefrancesco@gmail.com designates 209.85.128.45 as permitted sender) smtp.mailfrom=fmdefrancesco@gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1659551344; 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-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references:dkim-signature; bh=oJmOeTx06Lwu2fiuMzcG5dIKwqxwvQUWSEnoeJ++UWc=; b=BNBloOP8dgTOgYnsV4qOFBdRCpH9IefvdqzZI4B6jkggti3f1ef9Cm2kdCR9iwZl62LYkE mzq2il/1KvfslIXkMW0skZpim3gPJe2S0WbPMZZQy6IArz+UegzkwtsFPMCZEbZwtxIqr2 pzGzp4sfTKuEu7pzWnW6uqtBvKi/yRo= Authentication-Results: imf06.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=JmYucQwk; dmarc=pass (policy=none) header.from=gmail.com; spf=pass (imf06.hostedemail.com: domain of fmdefrancesco@gmail.com designates 209.85.128.45 as permitted sender) smtp.mailfrom=fmdefrancesco@gmail.com X-Rspamd-Server: rspam08 X-Rspamd-Queue-Id: 28605180004 X-Rspam-User: X-Stat-Signature: 13tcqoc9znr73hieii57grag4htwxmq9 X-HE-Tag: 1659551343-736639 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: The use of kmap() and kmap_atomic() are being deprecated in favor of kmap_local_page(). There are two main problems with kmap(): (1) It comes with an overhead as mapping space is restricted and protected by a global lock for synchronization and (2) it also requires global TLB invalidation when the kmap’s pool wraps and it might block when the mapping space is fully utilized until a slot becomes available. With kmap_local_page() the mappings are per thread, CPU local, can take page faults, and can be called from any context (including interrupts). It is faster than kmap() in kernels with HIGHMEM enabled. Furthermore, the tasks can be preempted and, when they are scheduled to run again, the kernel virtual addresses are restored and are still valid. Since the use of kmap_local_page() in exec.c is safe, it should be preferred everywhere in exec.c. As said, since kmap_local_page() can be also called from atomic context, and since remove_arg_zero() doesn't (and shouldn't ever) rely on an implicit preempt_disable(), this function can also safely replace kmap_atomic(). Therefore, replace kmap() and kmap_atomic() with kmap_local_page() in fs/exec.c. Tested with xfstests on a QEMU/KVM x86_32 VM, 6GB RAM, booting a kernel with HIGHMEM64GB enabled. Cc: Eric W. Biederman Suggested-by: Ira Weiny Reviewed-by: Ira Weiny Signed-off-by: Fabio M. De Francesco --- v1->v2: Added more information to the commit log to address some objections expressed by Eric W. Biederman[1] in reply to v1. No changes have been made to the code. Forwarded a tag from Ira Weiny (thanks!). [1] https://lore.kernel.org/lkml/8735fmqcfz.fsf@email.froward.int.ebiederm.org/ fs/exec.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 5fd73915c62c..b51dd14e7388 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -584,11 +584,11 @@ static int copy_strings(int argc, struct user_arg_ptr argv, if (kmapped_page) { flush_dcache_page(kmapped_page); - kunmap(kmapped_page); + kunmap_local(kaddr); put_arg_page(kmapped_page); } kmapped_page = page; - kaddr = kmap(kmapped_page); + kaddr = kmap_local_page(kmapped_page); kpos = pos & PAGE_MASK; flush_arg_page(bprm, kpos, kmapped_page); } @@ -602,7 +602,7 @@ static int copy_strings(int argc, struct user_arg_ptr argv, out: if (kmapped_page) { flush_dcache_page(kmapped_page); - kunmap(kmapped_page); + kunmap_local(kaddr); put_arg_page(kmapped_page); } return ret; @@ -880,11 +880,11 @@ int transfer_args_to_stack(struct linux_binprm *bprm, for (index = MAX_ARG_PAGES - 1; index >= stop; index--) { unsigned int offset = index == stop ? bprm->p & ~PAGE_MASK : 0; - char *src = kmap(bprm->page[index]) + offset; + char *src = kmap_local_page(bprm->page[index]) + offset; sp -= PAGE_SIZE - offset; if (copy_to_user((void *) sp, src, PAGE_SIZE - offset) != 0) ret = -EFAULT; - kunmap(bprm->page[index]); + kunmap_local(src); if (ret) goto out; } @@ -1683,13 +1683,13 @@ int remove_arg_zero(struct linux_binprm *bprm) ret = -EFAULT; goto out; } - kaddr = kmap_atomic(page); + kaddr = kmap_local_page(page); for (; offset < PAGE_SIZE && kaddr[offset]; offset++, bprm->p++) ; - kunmap_atomic(kaddr); + kunmap_local(kaddr); put_arg_page(page); } while (offset == PAGE_SIZE);