From patchwork Tue Aug 9 20:31:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fabio M. De Francesco" X-Patchwork-Id: 12939911 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 240B1C19F2D for ; Tue, 9 Aug 2022 20:31:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245497AbiHIUb2 (ORCPT ); Tue, 9 Aug 2022 16:31:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245467AbiHIUbS (ORCPT ); Tue, 9 Aug 2022 16:31:18 -0400 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AD7F3A47B; Tue, 9 Aug 2022 13:31:16 -0700 (PDT) Received: by mail-wm1-x332.google.com with SMTP id r1-20020a05600c35c100b003a326685e7cso953706wmq.1; Tue, 09 Aug 2022 13:31:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=C6jMsEHD+9BE7cLO107IUMZV7EzYBxJicgZ/uXZruiM=; b=XgDuAtfv8nBWmTgVXog7nsDRSVeu7p7fp3NgRdOFPutP8eWHd1OuydtngJTqqMaMRr aAyxF7uNGyLwI3Buymg8FKY0fPYc+X4bkq3P99yya2s/2E7uaebfIH6VuiSpRRkmqOWN +bHMxQFoBokh8og4st/uG2AfIXmEv2BPyMF0ahvPaO+fcuULgUgsL5QsUAg3P+fvjarb VFdzhUahrE7LtVKnRAHo/jz24wjsNsEVqxdY5aOjfHhIAaaVud5bvGhOal0FlCB9DA4T WbP14fdYcb2gXq2+KLGbp/q9anwSYAGC4fq90GYq6t50/X7JjjDbm81IeAugOWi6gajs XqKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=C6jMsEHD+9BE7cLO107IUMZV7EzYBxJicgZ/uXZruiM=; b=UcDSx58KU62OcVkK90u0LuIKUi7OvhA3Ay5xczXnvN4M7OTTAD0QDLHdObZDsKk+Xg INYO7pOUA3qNUcOUlVvWwAcEApHkG+JH5Agp7b+wFFDEmr9NzRg9oHYvia6s9cHDLZCu x56Rxm75VliBf9PKbwo4RGO/TUVTJEvTStZX6TfL9/xmXAHkQi2mqo8RTQRhf9wE2SVc PEDDBVPFC7rUO/VyrOhq25V3lDKEWgV3KdRkhwIaGtAk2qAhl42ftbk3U8eqM3VTa0MU JxmRGEKTmw7p0EYcNXjsV9TP5DKpIFVFL5N/0F1RSqTV55knlCbUzAdXx9KGLVTgehOF qDDg== X-Gm-Message-State: ACgBeo12GBYbT9nu4nf18tu0LtAM/vYYx8wFo8VD6GFwF8XOQfokgzPd 7gIieEGdHHPeh+9suTjyaVE= X-Google-Smtp-Source: AA6agR4j76MuyV0kEK/jsRIquQ+3LfBPUcjWL3AXkbc3CFMbxHrY2VGM0+iVNFypopBYZxB01BO0RQ== X-Received: by 2002:a05:600c:501e:b0:3a3:4a04:fdb5 with SMTP id n30-20020a05600c501e00b003a34a04fdb5mr133630wmr.168.1660077075174; Tue, 09 Aug 2022 13:31:15 -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 ck15-20020a5d5e8f000000b002205f0890eesm15085263wrb.77.2022.08.09.13.31.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:31:13 -0700 (PDT) From: "Fabio M. De Francesco" To: "Matthew Wilcox (Oracle)" , "Fabio M. De Francesco" , Ira Weiny , Jens Axboe , Andrew Morton , Bart Van Assche , Kees Cook , Muchun Song , Viacheslav Dubeyko , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/4] hfsplus: Unmap the page in the "fail_page" label Date: Tue, 9 Aug 2022 22:31:02 +0200 Message-Id: <20220809203105.26183-2-fmdefrancesco@gmail.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220809203105.26183-1-fmdefrancesco@gmail.com> References: <20220809203105.26183-1-fmdefrancesco@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Several paths within hfs_btree_open() jump to the "fail_page" label where put_page() is called while the page is still mapped. Call kunmap() to unmap the page soon before put_page(). Cc: Viacheslav Dubeyko Reviewed-by: Ira Weiny Signed-off-by: Fabio M. De Francesco Reviewed-by: Viacheslav Dubeyko --- fs/hfsplus/btree.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 66774f4cb4fd..3a917a9a4edd 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c @@ -245,6 +245,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) return tree; fail_page: + kunmap(page); put_page(page); free_inode: tree->inode->i_mapping->a_ops = &hfsplus_aops; From patchwork Tue Aug 9 20:31:03 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: 12939912 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B040C3F6B0 for ; Tue, 9 Aug 2022 20:31:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343700AbiHIUba (ORCPT ); Tue, 9 Aug 2022 16:31:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245683AbiHIUb1 (ORCPT ); Tue, 9 Aug 2022 16:31:27 -0400 Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6A61120A1; Tue, 9 Aug 2022 13:31:19 -0700 (PDT) Received: by mail-wr1-x434.google.com with SMTP id n4so13782179wrp.10; Tue, 09 Aug 2022 13:31:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=4RoVrzLiNKX6VDp/f62qoJyNcP2XJ4q15O/NDEL7778=; b=lkZhYyPgtFaS6YtKt5H5hYrG5AVbOFuIz95B5ht09D2GSg3hOj7wpSxlfBVtoJqwrn PYXcR/qNpFpGPM9+7uaFt7mgfECaEXvdvnfuqJ5yAKPb2ST1O2hIud7SWa7taZJM61P4 xO1EUwsF31uPwdpHVlKGV9VD+aZvRZEUe5yXtI786GkNtvF/O/mWP9lhN0RJd00B4wKd pz/51LJ69l3qSabGdfjzqu3IvHmikZOOSb9WB0AA+UXjFqR0bL1fAERZd6AWM05/s8ZA fE8+Ni1lw5zmmH6/PF0qecHOKeYECYDl8h3j8l85jZd8EP0PEZ48egdW11cVkFNvOiOX MOlw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4RoVrzLiNKX6VDp/f62qoJyNcP2XJ4q15O/NDEL7778=; b=teYoSNdaf8hIo5cumhESx+SWNYetTj2VCvd/IdzKbjRlwER1oZyaSoXC/VpGU4l8tS YttWZuJGhNb1c8u1gwVcZ41TlQm/n4Zy0ioKMbO1Xv9bideoQ4rzJ+w3S3hVKtcGCC9Q kmxsYiM6PXdtvdN7pjQLcNVqE7iNrmEAysNi04jTp+FsZsRu1R6o3MgE9bgiNQsh6u1N clqVPAbgAn2MDzhcZ3vqtoLxEwticgIleaoFqBhhJxNJTgOyPJlQEKB5K99e1rbkuLxc bh5lNmXduUTQ79BWBiHstfnKuvL0i1v+y7hIDVUtWDjn3jIJryFUDUWSoKpKEge1vLWO YPFw== X-Gm-Message-State: ACgBeo2ql8v6ulHuNEadBJ1XyMZ5zj+cPmF5MnfA8IRvvtnMLJZUA3nT 6vgdt7bE5H1UwcT6l/oIJxo= X-Google-Smtp-Source: AA6agR5jKgSMlbxVcnogE6rDdMjBvtHP7Haktd0R03K2SIj/vC8FhAmzTo4wVE+6lm5MHnLWrPNhFg== X-Received: by 2002:adf:fb86:0:b0:21e:3cc8:a917 with SMTP id a6-20020adffb86000000b0021e3cc8a917mr16005778wrr.538.1660077077874; Tue, 09 Aug 2022 13:31:17 -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 ck15-20020a5d5e8f000000b002205f0890eesm15085263wrb.77.2022.08.09.13.31.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:31:16 -0700 (PDT) From: "Fabio M. De Francesco" To: "Matthew Wilcox (Oracle)" , "Fabio M. De Francesco" , Ira Weiny , Jens Axboe , Andrew Morton , Bart Van Assche , Kees Cook , Muchun Song , Viacheslav Dubeyko , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/4] hfsplus: Convert kmap() to kmap_local_page() in bnode.c Date: Tue, 9 Aug 2022 22:31:03 +0200 Message-Id: <20220809203105.26183-3-fmdefrancesco@gmail.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220809203105.26183-1-fmdefrancesco@gmail.com> References: <20220809203105.26183-1-fmdefrancesco@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org kmap() is being deprecated in favor of kmap_local_page(). 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 still valid. Since its use in bnode.c is safe everywhere, it should be preferred. Therefore, replace kmap() with kmap_local_page() in bnode.c. Where possible, use the suited standard helpers (memzero_page(), memcpy_page()) instead of open coding kmap_local_page() plus memset() or memcpy(). Tested in a QEMU/KVM x86_32 VM, 6GB RAM, booting a kernel with HIGHMEM64GB enabled. Cc: Viacheslav Dubeyko Suggested-by: Ira Weiny Reviewed-by: Ira Weiny Signed-off-by: Fabio M. De Francesco Reviewed-by: Viacheslav Dubeyko --- fs/hfsplus/bnode.c | 105 +++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 57 deletions(-) diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c index a5ab00e54220..87974d5e6791 100644 --- a/fs/hfsplus/bnode.c +++ b/fs/hfsplus/bnode.c @@ -29,14 +29,12 @@ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len) off &= ~PAGE_MASK; l = min_t(int, len, PAGE_SIZE - off); - memcpy(buf, kmap(*pagep) + off, l); - kunmap(*pagep); + memcpy_from_page(buf, *pagep, off, l); while ((len -= l) != 0) { buf += l; l = min_t(int, len, PAGE_SIZE); - memcpy(buf, kmap(*++pagep), l); - kunmap(*pagep); + memcpy_from_page(buf, *++pagep, 0, l); } } @@ -82,16 +80,14 @@ void hfs_bnode_write(struct hfs_bnode *node, void *buf, int off, int len) off &= ~PAGE_MASK; l = min_t(int, len, PAGE_SIZE - off); - memcpy(kmap(*pagep) + off, buf, l); + memcpy_to_page(*pagep, off, buf, l); set_page_dirty(*pagep); - kunmap(*pagep); while ((len -= l) != 0) { buf += l; l = min_t(int, len, PAGE_SIZE); - memcpy(kmap(*++pagep), buf, l); + memcpy_to_page(*++pagep, 0, buf, l); set_page_dirty(*pagep); - kunmap(*pagep); } } @@ -112,15 +108,13 @@ void hfs_bnode_clear(struct hfs_bnode *node, int off, int len) off &= ~PAGE_MASK; l = min_t(int, len, PAGE_SIZE - off); - memset(kmap(*pagep) + off, 0, l); + memzero_page(*pagep, off, l); set_page_dirty(*pagep); - kunmap(*pagep); while ((len -= l) != 0) { l = min_t(int, len, PAGE_SIZE); - memset(kmap(*++pagep), 0, l); + memzero_page(*++pagep, 0, l); set_page_dirty(*pagep); - kunmap(*pagep); } } @@ -142,24 +136,20 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, if (src == dst) { l = min_t(int, len, PAGE_SIZE - src); - memcpy(kmap(*dst_page) + src, kmap(*src_page) + src, l); - kunmap(*src_page); + memcpy_page(*dst_page, src, *src_page, src, l); set_page_dirty(*dst_page); - kunmap(*dst_page); while ((len -= l) != 0) { l = min_t(int, len, PAGE_SIZE); - memcpy(kmap(*++dst_page), kmap(*++src_page), l); - kunmap(*src_page); + memcpy_page(*++dst_page, 0, *++src_page, 0, l); set_page_dirty(*dst_page); - kunmap(*dst_page); } } else { void *src_ptr, *dst_ptr; do { - src_ptr = kmap(*src_page) + src; - dst_ptr = kmap(*dst_page) + dst; + dst_ptr = kmap_local_page(*dst_page) + dst; + src_ptr = kmap_local_page(*src_page) + src; if (PAGE_SIZE - src < PAGE_SIZE - dst) { l = PAGE_SIZE - src; src = 0; @@ -171,9 +161,9 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, } l = min(len, l); memcpy(dst_ptr, src_ptr, l); - kunmap(*src_page); + kunmap_local(src_ptr); set_page_dirty(*dst_page); - kunmap(*dst_page); + kunmap_local(dst_ptr); if (!dst) dst_page++; else @@ -185,6 +175,7 @@ void hfs_bnode_copy(struct hfs_bnode *dst_node, int dst, void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) { struct page **src_page, **dst_page; + void *src_ptr, *dst_ptr; int l; hfs_dbg(BNODE_MOD, "movebytes: %u,%u,%u\n", dst, src, len); @@ -202,27 +193,28 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) if (src == dst) { while (src < len) { - memmove(kmap(*dst_page), kmap(*src_page), src); - kunmap(*src_page); + dst_ptr = kmap_local_page(*dst_page); + src_ptr = kmap_local_page(*src_page); + memmove(dst_ptr, src_ptr, src); + kunmap_local(src_ptr); set_page_dirty(*dst_page); - kunmap(*dst_page); + kunmap_local(dst_ptr); len -= src; src = PAGE_SIZE; src_page--; dst_page--; } src -= len; - memmove(kmap(*dst_page) + src, - kmap(*src_page) + src, len); - kunmap(*src_page); + dst_ptr = kmap_local_page(*dst_page); + src_ptr = kmap_local_page(*src_page); + memmove(dst_ptr + src, src_ptr + src, len); + kunmap_local(src_ptr); set_page_dirty(*dst_page); - kunmap(*dst_page); + kunmap_local(dst_ptr); } else { - void *src_ptr, *dst_ptr; - do { - src_ptr = kmap(*src_page) + src; - dst_ptr = kmap(*dst_page) + dst; + dst_ptr = kmap_local_page(*dst_page) + dst; + src_ptr = kmap_local_page(*src_page) + src; if (src < dst) { l = src; src = PAGE_SIZE; @@ -234,9 +226,9 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) } l = min(len, l); memmove(dst_ptr - l, src_ptr - l, l); - kunmap(*src_page); + kunmap_local(src_ptr); set_page_dirty(*dst_page); - kunmap(*dst_page); + kunmap_local(dst_ptr); if (dst == PAGE_SIZE) dst_page--; else @@ -251,26 +243,27 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) if (src == dst) { l = min_t(int, len, PAGE_SIZE - src); - memmove(kmap(*dst_page) + src, - kmap(*src_page) + src, l); - kunmap(*src_page); + + dst_ptr = kmap_local_page(*dst_page) + src; + src_ptr = kmap_local_page(*src_page) + src; + memmove(dst_ptr, src_ptr, l); + kunmap_local(src_ptr); set_page_dirty(*dst_page); - kunmap(*dst_page); + kunmap_local(dst_ptr); while ((len -= l) != 0) { l = min_t(int, len, PAGE_SIZE); - memmove(kmap(*++dst_page), - kmap(*++src_page), l); - kunmap(*src_page); + dst_ptr = kmap_local_page(*++dst_page); + src_ptr = kmap_local_page(*++src_page); + memmove(dst_ptr, src_ptr, l); + kunmap_local(src_ptr); set_page_dirty(*dst_page); - kunmap(*dst_page); + kunmap_local(dst_ptr); } } else { - void *src_ptr, *dst_ptr; - do { - src_ptr = kmap(*src_page) + src; - dst_ptr = kmap(*dst_page) + dst; + dst_ptr = kmap_local_page(*dst_page) + dst; + src_ptr = kmap_local_page(*src_page) + src; if (PAGE_SIZE - src < PAGE_SIZE - dst) { l = PAGE_SIZE - src; @@ -283,9 +276,9 @@ void hfs_bnode_move(struct hfs_bnode *node, int dst, int src, int len) } l = min(len, l); memmove(dst_ptr, src_ptr, l); - kunmap(*src_page); + kunmap_local(src_ptr); set_page_dirty(*dst_page); - kunmap(*dst_page); + kunmap_local(dst_ptr); if (!dst) dst_page++; else @@ -498,14 +491,14 @@ struct hfs_bnode *hfs_bnode_find(struct hfs_btree *tree, u32 num) if (!test_bit(HFS_BNODE_NEW, &node->flags)) return node; - desc = (struct hfs_bnode_desc *)(kmap(node->page[0]) + - node->page_offset); + desc = (struct hfs_bnode_desc *)(kmap_local_page(node->page[0]) + + node->page_offset); node->prev = be32_to_cpu(desc->prev); node->next = be32_to_cpu(desc->next); node->num_recs = be16_to_cpu(desc->num_recs); node->type = desc->type; node->height = desc->height; - kunmap(node->page[0]); + kunmap_local(desc); switch (node->type) { case HFS_NODE_HEADER: @@ -589,14 +582,12 @@ struct hfs_bnode *hfs_bnode_create(struct hfs_btree *tree, u32 num) } pagep = node->page; - memset(kmap(*pagep) + node->page_offset, 0, - min_t(int, PAGE_SIZE, tree->node_size)); + memzero_page(*pagep, node->page_offset, + min_t(int, PAGE_SIZE, tree->node_size)); set_page_dirty(*pagep); - kunmap(*pagep); for (i = 1; i < tree->pages_per_bnode; i++) { - memset(kmap(*++pagep), 0, PAGE_SIZE); + memzero_page(*++pagep, 0, PAGE_SIZE); set_page_dirty(*pagep); - kunmap(*pagep); } clear_bit(HFS_BNODE_NEW, &node->flags); wake_up(&node->lock_wq); From patchwork Tue Aug 9 20:31:04 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: 12939913 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4CC7CC19F2D for ; Tue, 9 Aug 2022 20:31:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343514AbiHIUbc (ORCPT ); Tue, 9 Aug 2022 16:31:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245734AbiHIUb2 (ORCPT ); Tue, 9 Aug 2022 16:31:28 -0400 Received: from mail-wr1-x431.google.com (mail-wr1-x431.google.com [IPv6:2a00:1450:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 48F4F14020; Tue, 9 Aug 2022 13:31:22 -0700 (PDT) Received: by mail-wr1-x431.google.com with SMTP id q30so15513827wra.11; Tue, 09 Aug 2022 13:31:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Gvs03Ga9APJZNi2iqAGpqdSPimA6hbWAcXkTH65C7Pk=; b=mO1mJxafny7G4BQ4u/+K/78a12MfApBzkNOx/Ba5BbkrQPesz1u8oShoxKWz6PEE/j UWsEUEQLxDvj70rZbH/IKOv8wGPvcAEwdQ4lkbQWYVK7ZMlwL+EpI7bnOmZBCaqA98lP H1ovlBEMwuyreNaVR4BUNtbaI9JAQfcLN+M9VGv/dif4vYGFhQO0E4tl7DsIYRIuMzzp lq3L23yLotKCvkw1GkrJiEqC6NlVrVqxKXUKtL31i6rH8XbheEqBkviXJK5V9zmKNk+n L6+xNeWnru+pSCpYEOfpv3QrW+FJk9f+fudrQHuXsV8SmgECObGolOHjbb5C15qFLFaW Wa8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Gvs03Ga9APJZNi2iqAGpqdSPimA6hbWAcXkTH65C7Pk=; b=4b+tzNpJrQjPoLqE3jkp54HjmfyY92JncUTwmFuXxdDWciyD54e1SEAK4uXaIJZX18 QviZNfyYROt9myFZvxvnIBVNFhSP0i0IoObsg+e3+cBv+aCKR8yE+Tin+AeUUt8Le7xe ua5FNZjJxI1RTWRvwvykkqBYdzi55byqtShIc7AtjXvVwd2kqEGH/OscODZzDibGwgXa wVoo2O+CpjCaA1OlyarZNWvWcbJNFmcljgYHMa4lfMR7sbaHFSFx5isuIFDDgFN0hpdk uICP9bQImKDlx2CmF15AlXATdw+qwNBdUTJpIyGqPQCyVsmXp4+K535cBeU/jYDD2Gen BOdQ== X-Gm-Message-State: ACgBeo0QmmVAgJE+dPJafQfBnI0FZaXeyq/crHhXwcpleGP+cO3joQUb 9wf4DSIN8ap+50nGJzXvY7c= X-Google-Smtp-Source: AA6agR5upLpWunB9poLDBZ8+EEnSNlIq7rwESwBmeLq+ePjuo/eRYRVTtaYIYUGePQbAEx6jyN9EuQ== X-Received: by 2002:a5d:60c5:0:b0:220:6780:2701 with SMTP id x5-20020a5d60c5000000b0022067802701mr16091672wrt.450.1660077080762; Tue, 09 Aug 2022 13:31:20 -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 ck15-20020a5d5e8f000000b002205f0890eesm15085263wrb.77.2022.08.09.13.31.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:31:19 -0700 (PDT) From: "Fabio M. De Francesco" To: "Matthew Wilcox (Oracle)" , "Fabio M. De Francesco" , Ira Weiny , Jens Axboe , Andrew Morton , Bart Van Assche , Kees Cook , Muchun Song , Viacheslav Dubeyko , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 3/4] hfsplus: Convert kmap() to kmap_local_page() in bitmap.c Date: Tue, 9 Aug 2022 22:31:04 +0200 Message-Id: <20220809203105.26183-4-fmdefrancesco@gmail.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220809203105.26183-1-fmdefrancesco@gmail.com> References: <20220809203105.26183-1-fmdefrancesco@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org kmap() is 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 its use in bitmap.c is safe everywhere, it should be preferred. Therefore, replace kmap() with kmap_local_page() in bitmap.c. Tested in a QEMU/KVM x86_32 VM, 6GB RAM, booting a kernel with HIGHMEM64GB enabled. Cc: Viacheslav Dubeyko Suggested-by: Ira Weiny Reviewed-by: Ira Weiny Signed-off-by: Fabio M. De Francesco Reviewed-by: Viacheslav Dubeyko --- fs/hfsplus/bitmap.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/hfsplus/bitmap.c b/fs/hfsplus/bitmap.c index cebce0cfe340..bd8dcea85588 100644 --- a/fs/hfsplus/bitmap.c +++ b/fs/hfsplus/bitmap.c @@ -39,7 +39,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, start = size; goto out; } - pptr = kmap(page); + pptr = kmap_local_page(page); curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; i = offset % 32; offset &= ~(PAGE_CACHE_BITS - 1); @@ -74,7 +74,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, } curr++; } - kunmap(page); + kunmap_local(pptr); offset += PAGE_CACHE_BITS; if (offset >= size) break; @@ -84,7 +84,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, start = size; goto out; } - curr = pptr = kmap(page); + curr = pptr = kmap_local_page(page); if ((size ^ offset) / PAGE_CACHE_BITS) end = pptr + PAGE_CACHE_BITS / 32; else @@ -127,7 +127,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, len -= 32; } set_page_dirty(page); - kunmap(page); + kunmap_local(pptr); offset += PAGE_CACHE_BITS; page = read_mapping_page(mapping, offset / PAGE_CACHE_BITS, NULL); @@ -135,7 +135,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, start = size; goto out; } - pptr = kmap(page); + pptr = kmap_local_page(page); curr = pptr; end = pptr + PAGE_CACHE_BITS / 32; } @@ -151,7 +151,7 @@ int hfsplus_block_allocate(struct super_block *sb, u32 size, done: *curr = cpu_to_be32(n); set_page_dirty(page); - kunmap(page); + kunmap_local(pptr); *max = offset + (curr - pptr) * 32 + i - start; sbi->free_blocks -= *max; hfsplus_mark_mdb_dirty(sb); @@ -185,7 +185,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) page = read_mapping_page(mapping, pnr, NULL); if (IS_ERR(page)) goto kaboom; - pptr = kmap(page); + pptr = kmap_local_page(page); curr = pptr + (offset & (PAGE_CACHE_BITS - 1)) / 32; end = pptr + PAGE_CACHE_BITS / 32; len = count; @@ -215,11 +215,11 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) if (!count) break; set_page_dirty(page); - kunmap(page); + kunmap_local(pptr); page = read_mapping_page(mapping, ++pnr, NULL); if (IS_ERR(page)) goto kaboom; - pptr = kmap(page); + pptr = kmap_local_page(page); curr = pptr; end = pptr + PAGE_CACHE_BITS / 32; } @@ -231,7 +231,7 @@ int hfsplus_block_free(struct super_block *sb, u32 offset, u32 count) } out: set_page_dirty(page); - kunmap(page); + kunmap_local(pptr); sbi->free_blocks += len; hfsplus_mark_mdb_dirty(sb); mutex_unlock(&sbi->alloc_mutex); From patchwork Tue Aug 9 20:31:05 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: 12939914 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 96A3FC25B08 for ; Tue, 9 Aug 2022 20:31:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343646AbiHIUbk (ORCPT ); Tue, 9 Aug 2022 16:31:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53398 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343592AbiHIUb2 (ORCPT ); Tue, 9 Aug 2022 16:31:28 -0400 Received: from mail-wr1-x434.google.com (mail-wr1-x434.google.com [IPv6:2a00:1450:4864:20::434]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BDECF13DD6; Tue, 9 Aug 2022 13:31:24 -0700 (PDT) Received: by mail-wr1-x434.google.com with SMTP id z12so15538130wrs.9; Tue, 09 Aug 2022 13:31:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=f3+n0Fr4Dmr0J8VHjNmeb+vPcJAaEfynrop3hOhGh8g=; b=QdEZ4HrX4KDml4KQBZ/oxM902Rc1z6+W9ZamXWr85PjuzWIhiqn8iOr+pBQkCXoZjJ UymUYqSj7bHXo43TViMugq8IaWLVBJ1ELpNHLTF1/CAXmRIvUZX7etWdBNAVia6mngLH 2pDtKDzxwGJ+16NZyTHMc5AbMN74AP42a8wVhIVjUY3lCD/um66HnBXOgpQW5kCzLRDo mnND5kNRpST5jdL1pHSzurdeBHx3ZhafdwsjKQciLEbO9dQDZv+2SFcZjhhrYt1w2Gs5 idLjJhgKUdAaWqGI/JG0g47ILSqqkFQtxGqVrW1XxUc6J7ojNp0AheMeHMJk4ThgYhzD f2RQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=f3+n0Fr4Dmr0J8VHjNmeb+vPcJAaEfynrop3hOhGh8g=; b=nNziE377GqdMtTenQiur4pXZYhGYKr6xFh7dXK+5Z30YwgJqghoCnK41B0vUZD3PG2 XrxHy6r430j8J5yGezzlT55uF0TVKs56Iu9z6SJWNXYD1hu6LSx49KUVpLYJoWUqTzN+ OQSDQ+6WZYdrrU7xMMaxRik6RJGXJIf8kIobDdXL5p+cK3jrKnPbZtaAGo472vhRZli9 jUfzYIi+ptMIGrHhq1REXXzAm8R4iOebBGhORfkaYBQjW88q51ONXZfAskll78hb9MMv 3WDrOvuoHfC3ecEACk8nw65tp9nUC1ObOr7+RD5+KROF0FXq8zA1+s30T2tYtabBDXye HMVQ== X-Gm-Message-State: ACgBeo3yEGV5vEZG9gMEy9IQVmKDQ5qCxEdeXglwguAFQ4soHTCTd26k d1+PQCYspccVpD5xXA0WhW8= X-Google-Smtp-Source: AA6agR6AkcBeH5RcZED8BkmM34nQ5n0eFMEQVEtsjzoODsgzyOYZDjkkbylWyD1nmrASXPHroZhLyA== X-Received: by 2002:a05:6000:78d:b0:220:6259:2874 with SMTP id bu13-20020a056000078d00b0022062592874mr15613809wrb.678.1660077083332; Tue, 09 Aug 2022 13:31:23 -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 ck15-20020a5d5e8f000000b002205f0890eesm15085263wrb.77.2022.08.09.13.31.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:31:22 -0700 (PDT) From: "Fabio M. De Francesco" To: "Matthew Wilcox (Oracle)" , "Fabio M. De Francesco" , Ira Weiny , Jens Axboe , Andrew Morton , Bart Van Assche , Kees Cook , Muchun Song , Viacheslav Dubeyko , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 4/4] hfsplus: Convert kmap() to kmap_local_page() in btree.c Date: Tue, 9 Aug 2022 22:31:05 +0200 Message-Id: <20220809203105.26183-5-fmdefrancesco@gmail.com> X-Mailer: git-send-email 2.37.1 In-Reply-To: <20220809203105.26183-1-fmdefrancesco@gmail.com> References: <20220809203105.26183-1-fmdefrancesco@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org kmap() is 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 its use in btree.c is safe everywhere, it should be preferred. Therefore, replace kmap() with kmap_local_page() in btree.c. Tested in a QEMU/KVM x86_32 VM, 6GB RAM, booting a kernel with HIGHMEM64GB enabled. Cc: Viacheslav Dubeyko Suggested-by: Ira Weiny Reviewed-by: Ira Weiny Signed-off-by: Fabio M. De Francesco Reviewed-by: Viacheslav Dubeyko --- fs/hfsplus/btree.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 3a917a9a4edd..9e1732a2b92a 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c @@ -163,7 +163,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) goto free_inode; /* Load the header */ - head = (struct hfs_btree_header_rec *)(kmap(page) + + head = (struct hfs_btree_header_rec *)(kmap_local_page(page) + sizeof(struct hfs_bnode_desc)); tree->root = be32_to_cpu(head->root); tree->leaf_count = be32_to_cpu(head->leaf_count); @@ -240,12 +240,12 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) (tree->node_size + PAGE_SIZE - 1) >> PAGE_SHIFT; - kunmap(page); + kunmap_local(head); put_page(page); return tree; fail_page: - kunmap(page); + kunmap_local(head); put_page(page); free_inode: tree->inode->i_mapping->a_ops = &hfsplus_aops; @@ -292,7 +292,7 @@ int hfs_btree_write(struct hfs_btree *tree) return -EIO; /* Load the header */ page = node->page[0]; - head = (struct hfs_btree_header_rec *)(kmap(page) + + head = (struct hfs_btree_header_rec *)(kmap_local_page(page) + sizeof(struct hfs_bnode_desc)); head->root = cpu_to_be32(tree->root); @@ -304,7 +304,7 @@ int hfs_btree_write(struct hfs_btree *tree) head->attributes = cpu_to_be32(tree->attributes); head->depth = cpu_to_be16(tree->depth); - kunmap(page); + kunmap_local(head); set_page_dirty(page); hfs_bnode_put(node); return 0; @@ -395,7 +395,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) off += node->page_offset; pagep = node->page + (off >> PAGE_SHIFT); - data = kmap(*pagep); + data = kmap_local_page(*pagep); off &= ~PAGE_MASK; idx = 0; @@ -408,7 +408,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) idx += i; data[off] |= m; set_page_dirty(*pagep); - kunmap(*pagep); + kunmap_local(data); tree->free_nodes--; mark_inode_dirty(tree->inode); hfs_bnode_put(node); @@ -418,14 +418,14 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) } } if (++off >= PAGE_SIZE) { - kunmap(*pagep); - data = kmap(*++pagep); + kunmap_local(data); + data = kmap_local_page(*++pagep); off = 0; } idx += 8; len--; } - kunmap(*pagep); + kunmap_local(data); nidx = node->next; if (!nidx) { hfs_dbg(BNODE_MOD, "create new bmap node\n"); @@ -441,7 +441,7 @@ struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree) off = off16; off += node->page_offset; pagep = node->page + (off >> PAGE_SHIFT); - data = kmap(*pagep); + data = kmap_local_page(*pagep); off &= ~PAGE_MASK; } } @@ -491,7 +491,7 @@ void hfs_bmap_free(struct hfs_bnode *node) } off += node->page_offset + nidx / 8; page = node->page[off >> PAGE_SHIFT]; - data = kmap(page); + data = kmap_local_page(page); off &= ~PAGE_MASK; m = 1 << (~nidx & 7); byte = data[off]; @@ -499,13 +499,13 @@ void hfs_bmap_free(struct hfs_bnode *node) pr_crit("trying to free free bnode " "%u(%d)\n", node->this, node->type); - kunmap(page); + kunmap_local(data); hfs_bnode_put(node); return; } data[off] = byte & ~m; set_page_dirty(page); - kunmap(page); + kunmap_local(data); hfs_bnode_put(node); tree->free_nodes++; mark_inode_dirty(tree->inode);