From nobody Fri Jan 2 04:05:48 2026 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 178C6CDB474 for ; Mon, 16 Oct 2023 03:23:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231559AbjJPDXV (ORCPT ); Sun, 15 Oct 2023 23:23:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52824 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231490AbjJPDXM (ORCPT ); Sun, 15 Oct 2023 23:23:12 -0400 Received: from mail-pj1-x1029.google.com (mail-pj1-x1029.google.com [IPv6:2607:f8b0:4864:20::1029]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B1EFDE for ; Sun, 15 Oct 2023 20:22:49 -0700 (PDT) Received: by mail-pj1-x1029.google.com with SMTP id 98e67ed59e1d1-27d0acd0903so2387917a91.1 for ; Sun, 15 Oct 2023 20:22:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426568; x=1698031368; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7MLK4HxQMsxrLAQzNmdHMtQCN++SQMztyyHR1MHkRQQ=; b=f2wN4xQOCM0f+nThGjAETD6mMdWTSPkmkKiG8kleQKCm6Mll6niSRKq+BeaUigBJ/b aHVu5V76nZcV2/e6sTGU4U7daNWFPyiocKph/7hXn+0NiTxcLYc8MJqR2D6bFtWlvBvp K4znW/+Hoq28Wd7FoS7jY5snH2FrXpnufdpyiMncHr00t5Z48MTUsREn/1/wuCJM3w8P KYqHGugQs10QIq1bYted9mGeoou4HVoQVP8FyZEOrzCxd3pH7fgryHypxedWpgJhILmR l8/fFQVTb0vFE6R9WL/1jOTP6flLTMFFm7OXzKXgVFUjK8OZc0z9yQfNjGTphnADtj60 CB9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426568; x=1698031368; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=7MLK4HxQMsxrLAQzNmdHMtQCN++SQMztyyHR1MHkRQQ=; b=Mc1UeLVoGPfzPky8MHkDPt5DvSkgCr762NZfqCczS1cElELmFYSmPnxYxNgtVFbKdU TXAZC5c8NxnYfBEdAWn312X0NYfVfjuCwtSw8Qbh/fsE0dN3qjiTQcW3wL5mM2Af3vLR +pPqitPE33GewHFzO4fnxVFSFHxY943UgvGo5zrL+fFQBkJHrICkNb+QdnBMea1DPfN1 zgYTiiCMnIdLpG2Dk9Z3z5d3VGI6FzaLm8OMOnDzjDEyofG7OUDN3JKAATh9oqs1Xk6D K+3FgU4BkOFuUbwYlxboatfwsileuDquj8Ex4SSyS9Qm1FJDFHj3qQ339gFIUPiVR9yA sdKQ== X-Gm-Message-State: AOJu0YxdEJJxsOahK46a86BUPdZ8dAwqBMf+W1OJ0foD8Qx50fUxpW2S 5TY2K//N8YvIez2LoR0qCZLHzg== X-Google-Smtp-Source: AGHT+IGUNON6/iy5nHhowUF+lwNS0aMjdLqxBBty2ZXDevKfnR4hUvescHuITP1+A0eJuZZ+fdkYww== X-Received: by 2002:a17:90b:4b4a:b0:27d:54b9:c3c5 with SMTP id mi10-20020a17090b4b4a00b0027d54b9c3c5mr3463142pjb.17.1697426568534; Sun, 15 Oct 2023 20:22:48 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.22.42 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:22:48 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 01/10] maple_tree: Add mt_free_one() and mt_attr() helpers Date: Mon, 16 Oct 2023 11:22:17 +0800 Message-Id: <20231016032226.59199-2-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add two helpers: 1. mt_free_one(), used to free a maple node. 2. mt_attr(), used to obtain the attributes of maple tree. Signed-off-by: Peng Zhang --- lib/maple_tree.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/maple_tree.c b/lib/maple_tree.c index bb24d84a4922..ca7039633844 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -165,6 +165,11 @@ static inline int mt_alloc_bulk(gfp_t gfp, size_t size= , void **nodes) return kmem_cache_alloc_bulk(maple_node_cache, gfp, size, nodes); } =20 +static inline void mt_free_one(struct maple_node *node) +{ + kmem_cache_free(maple_node_cache, node); +} + static inline void mt_free_bulk(size_t size, void __rcu **nodes) { kmem_cache_free_bulk(maple_node_cache, size, (void **)nodes); @@ -205,6 +210,11 @@ static unsigned int mas_mt_height(struct ma_state *mas) return mt_height(mas->tree); } =20 +static inline unsigned int mt_attr(struct maple_tree *mt) +{ + return mt->ma_flags & ~MT_FLAGS_HEIGHT_MASK; +} + static inline enum maple_type mte_node_type(const struct maple_enode *entr= y) { return ((unsigned long)entry >> MAPLE_NODE_TYPE_SHIFT) & @@ -5573,7 +5583,7 @@ void mas_destroy(struct ma_state *mas) mt_free_bulk(count, (void __rcu **)&node->slot[1]); total -=3D count; } - kmem_cache_free(maple_node_cache, node); + mt_free_one(ma_mnode_ptr(node)); total--; } =20 --=20 2.20.1 From nobody Fri Jan 2 04:05:48 2026 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 08C9ACDB482 for ; Mon, 16 Oct 2023 03:23:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231464AbjJPDXA (ORCPT ); Sun, 15 Oct 2023 23:23:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229600AbjJPDW5 (ORCPT ); Sun, 15 Oct 2023 23:22:57 -0400 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80045DA for ; Sun, 15 Oct 2023 20:22:55 -0700 (PDT) Received: by mail-pf1-x436.google.com with SMTP id d2e1a72fcca58-6bd96cfb99cso500374b3a.2 for ; Sun, 15 Oct 2023 20:22:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426575; x=1698031375; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=r3L72Q2C0A6XyhsC7UMGOLSZK5Azm/i+GpPRU3MZq4Q=; b=abKwRmNnzlGZCY3tRMgEIeqabVUqnrsc73kFTdzliIaUuGYlhaNGFPSBwpUdMKBZI0 nAZ/zX/RT2dcOPTOzY80G3FmbYSCtTUEOhkqOeUi2Z9w/Fv7GvPz9At3CaZ0OeoPNHdI ExT7GHm6YipgEFfgIjRgLptN519oO2XosJj+hOg2LqcXaN6vK9u8fIHc9jCfanV/Ws2h D1tvDrsBv4NHs4IU+UDdddoqueVIfdnVeZVX3E7V0X7dDPulw3WfvC30rlLhNjo51jxw ObHoaRU2hMg9yZzrjKNUENfzlUqNOMGUFLAg8U1EnbM/Rk1YNG6Vksxyb3Dxu99T6P+5 TcQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426575; x=1698031375; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=r3L72Q2C0A6XyhsC7UMGOLSZK5Azm/i+GpPRU3MZq4Q=; b=guaPBmsJEiYvmxLw9HwOKCyvcu0fM0GckbpAGwfVEeU47aedf4SzOIszOhZrLd1SV+ +MDSa5Cgry1AA+DCl72DsNjKuYYxO+vbdZ3i1FZbzkZKWU3MhoiBDgWS7nz+l9IiLiXA 3vuzLdFBRlvyunMyEd6uR7ZwbEItsf8o8rYCJC68GBGqwmqWcSUQR7B0hrFrH4brOrMM dsqZLupxisJkaEpvg7RaYbPQ1GDtoPDpDRAL7+zU462hjMUz+bpVGcndgl1JF9NxVH1q V35QWNDtvekjDMQfiZpgQtVVljugaTFNgn8miMuNWP3KeDNoQEjjQG+uV7FKGZamBL2O StSg== X-Gm-Message-State: AOJu0Yz1FF+ytTUf/uTDxEDlnyIElCmnBax0o792WYOiSQEUyrxx6FAx KQ+FSKn+2p68pXYUOksi1H0wrA== X-Google-Smtp-Source: AGHT+IF6N8e9Loe20mQNUBXUIhiXmTkb8m7FtzL5gkme8mgEaofINIog9sVAbKEQ8545hYi479/lHg== X-Received: by 2002:a05:6a20:1613:b0:15d:9ee7:180a with SMTP id l19-20020a056a20161300b0015d9ee7180amr33444332pzj.4.1697426575048; Sun, 15 Oct 2023 20:22:55 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.22.49 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:22:54 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 02/10] maple_tree: Introduce {mtree,mas}_lock_nested() Date: Mon, 16 Oct 2023 11:22:18 +0800 Message-Id: <20231016032226.59199-3-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In some cases, nested locks may be needed, so {mtree,mas}_lock_nested is introduced. For example, when duplicating maple tree, we need to hold the locks of two trees, in which case nested locks are needed. At the same time, add the definition of spin_lock_nested() in tools for testing. Signed-off-by: Peng Zhang --- include/linux/maple_tree.h | 4 ++++ tools/include/linux/spinlock.h | 1 + 2 files changed, 5 insertions(+) diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h index d01e850b570f..f91dbc7fe091 100644 --- a/include/linux/maple_tree.h +++ b/include/linux/maple_tree.h @@ -256,6 +256,8 @@ struct maple_tree { struct maple_tree name =3D MTREE_INIT(name, 0) =20 #define mtree_lock(mt) spin_lock((&(mt)->ma_lock)) +#define mtree_lock_nested(mas, subclass) \ + spin_lock_nested((&(mt)->ma_lock), subclass) #define mtree_unlock(mt) spin_unlock((&(mt)->ma_lock)) =20 /* @@ -406,6 +408,8 @@ struct ma_wr_state { }; =20 #define mas_lock(mas) spin_lock(&((mas)->tree->ma_lock)) +#define mas_lock_nested(mas, subclass) \ + spin_lock_nested(&((mas)->tree->ma_lock), subclass) #define mas_unlock(mas) spin_unlock(&((mas)->tree->ma_lock)) =20 =20 diff --git a/tools/include/linux/spinlock.h b/tools/include/linux/spinlock.h index 622266b197d0..a6cdf25b6b9d 100644 --- a/tools/include/linux/spinlock.h +++ b/tools/include/linux/spinlock.h @@ -11,6 +11,7 @@ #define spin_lock_init(x) pthread_mutex_init(x, NULL) =20 #define spin_lock(x) pthread_mutex_lock(x) +#define spin_lock_nested(x, subclass) pthread_mutex_lock(x) #define spin_unlock(x) pthread_mutex_unlock(x) #define spin_lock_bh(x) pthread_mutex_lock(x) #define spin_unlock_bh(x) pthread_mutex_unlock(x) --=20 2.20.1 From nobody Fri Jan 2 04:05:48 2026 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 5E333CDB482 for ; Mon, 16 Oct 2023 03:23:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231529AbjJPDXd (ORCPT ); Sun, 15 Oct 2023 23:23:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55644 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231490AbjJPDXY (ORCPT ); Sun, 15 Oct 2023 23:23:24 -0400 Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D084DA for ; Sun, 15 Oct 2023 20:23:02 -0700 (PDT) Received: by mail-pf1-x432.google.com with SMTP id d2e1a72fcca58-6b201a93c9cso1941765b3a.0 for ; Sun, 15 Oct 2023 20:23:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426582; x=1698031382; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=e/sF1y4M8+5TE0GCNNK3GGgEnktBWwP9VwP8zP44L9Y=; b=Wjvmw20A0vzoI9yy3cXL1/qhTvtoyXEg8kP58mGYKExPejxPwqPtE+22xC0kc66kre koYDfV71yjtc37b/XaAy7QXbQ2sJAiKx9/vkzf6zcRuxT3R6Tsas55XYHEHsk/BirbA/ Hd8CSp24le7lAgBZBmNuGcuBA5jPhrsEZkWJjDj/YQo0T1BQ+rz7iAEVaSvZYAVBynaQ 7uLKLMBXJ1phjCXKrEJYdyti8GsFjwKjEEexxIm5UMycxMYStd8xKqgZrsh6BIXzNauZ ZaECUHPyUprV/IN175cHee4mMu6YZ0ynigkuzVpfmT3GyjOISDHL1ySURf1K0h1gf3Ak Rwqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426582; x=1698031382; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=e/sF1y4M8+5TE0GCNNK3GGgEnktBWwP9VwP8zP44L9Y=; b=wQt6HpY5H4Eec/6vjtNn02qwyAy2BV0THfWPsNRUpkF02xUp6mnZGyQNFt9lEh4FV6 x0T3dxW2TrsPeZarLXWSYexN7Ad14dRMJDIkiivZLVsQ6ZfSSTT63lWeTmC6d1aXqUNO JW29HtWZRNnYgKYD8s0pe7X9BCXXra4Mkv77caufuiCZO9XpqArRQ8VG5+k4y89ycjuU MzcZA5nROgsh5sN0u/w67Z5B0jawBkSHeW7IJEglPSNaku7Q42Tuld53yYTX5d9wrS3j F1p/j78F8G+itBUBT5fmlnGUX3RIC2v2x2QxFaC/mnTSIxq0vkW11X82YuEr++n/wsq9 rnpw== X-Gm-Message-State: AOJu0Ywj/R/QE/xwzBTAr+OeQUbeiF0Mk5uqKWuBfXLPQs7ANmN1+EHl 6Hp8XTjz5OoopUWuf1J1MfRc3g== X-Google-Smtp-Source: AGHT+IGNszmmv6OXzfGiuGTzwsi3NCAXv1mbwF37K+8hIyYvm0XADpPiEGL9AP+98FGCJGisbDNSWQ== X-Received: by 2002:a05:6a20:7f9a:b0:140:a25:1c1d with SMTP id d26-20020a056a207f9a00b001400a251c1dmr36624545pzj.51.1697426581541; Sun, 15 Oct 2023 20:23:01 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.22.55 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:23:01 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 03/10] maple_tree: Introduce interfaces __mt_dup() and mtree_dup() Date: Mon, 16 Oct 2023 11:22:19 +0800 Message-Id: <20231016032226.59199-4-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Introduce interfaces __mt_dup() and mtree_dup(), which are used to duplicate a maple tree. They duplicate a maple tree in Depth-First Search (DFS) pre-order traversal. It uses memcopy() to copy nodes in the source tree and allocate new child nodes in non-leaf nodes. The new node is exactly the same as the source node except for all the addresses stored in it. It will be faster than traversing all elements in the source tree and inserting them one by one into the new tree. The time complexity of these two functions is O(n). The difference between __mt_dup() and mtree_dup() is that mtree_dup() handles locks internally. Analysis of the average time complexity of this algorithm: For simplicity, let's assume that the maximum branching factor of all non-leaf nodes is 16 (in allocation mode, it is 10), and the tree is a full tree. Under the given conditions, if there is a maple tree with n elements, the number of its leaves is n/16. From bottom to top, the number of nodes in each level is 1/16 of the number of nodes in the level below. So the total number of nodes in the entire tree is given by the sum of n/16 + n/16^2 + n/16^3 + ... + 1. This is a geometric series, and it has log(n) terms with base 16. According to the formula for the sum of a geometric series, the sum of this series can be calculated as (n-1)/15. Each node has only one parent node pointer, which can be considered as an edge. In total, there are (n-1)/15-1 edges. This algorithm consists of two operations: 1. Traversing all nodes in DFS order. 2. For each node, making a copy and performing necessary modifications to create a new node. For the first part, DFS traversal will visit each edge twice. Let T(ascend) represent the cost of taking one step downwards, and T(descend) represent the cost of taking one step upwards. And both of them are constants (although mas_ascend() may not be, as it contains a loop, but here we ignore it and treat it as a constant). So the time spent on the first part can be represented as ((n-1)/15-1) * (T(ascend) + T(descend)). For the second part, each node will be copied, and the cost of copying a node is denoted as T(copy_node). For each non-leaf node, it is necessary to reallocate all child nodes, and the cost of this operation is denoted as T(dup_alloc). The behavior behind memory allocation is complex and not specific to the maple tree operation. Here, we assume that the time required for a single allocation is constant. Since the size of a node is fixed, both of these symbols are also constants. We can calculate that the time spent on the second part is ((n-1)/15) * T(copy_node) + ((n-1)/15 - n/16) * T(dup_alloc). Adding both parts together, the total time spent by the algorithm can be represented as: ((n-1)/15) * (T(ascend) + T(descend) + T(copy_node) + T(dup_alloc)) - n/16 * T(dup_alloc) - (T(ascend) + T(descend)) Let C1 =3D T(ascend) + T(descend) + T(copy_node) + T(dup_alloc) Let C2 =3D T(dup_alloc) Let C3 =3D T(ascend) + T(descend) Finally, the expression can be simplified as: ((16 * C1 - 15 * C2) / (15 * 16)) * n - (C1 / 15 + C3). This is a linear function, so the average time complexity is O(n). Signed-off-by: Peng Zhang --- include/linux/maple_tree.h | 3 + lib/maple_tree.c | 290 +++++++++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+) diff --git a/include/linux/maple_tree.h b/include/linux/maple_tree.h index f91dbc7fe091..a452dd8a1e5c 100644 --- a/include/linux/maple_tree.h +++ b/include/linux/maple_tree.h @@ -329,6 +329,9 @@ int mtree_store(struct maple_tree *mt, unsigned long in= dex, void *entry, gfp_t gfp); void *mtree_erase(struct maple_tree *mt, unsigned long index); =20 +int mtree_dup(struct maple_tree *mt, struct maple_tree *new, gfp_t gfp); +int __mt_dup(struct maple_tree *mt, struct maple_tree *new, gfp_t gfp); + void mtree_destroy(struct maple_tree *mt); void __mt_destroy(struct maple_tree *mt); =20 diff --git a/lib/maple_tree.c b/lib/maple_tree.c index ca7039633844..6e0ad83f14e3 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -4,6 +4,10 @@ * Copyright (c) 2018-2022 Oracle Corporation * Authors: Liam R. Howlett * Matthew Wilcox + * + * Algorithm for duplicating Maple Tree + * Copyright (c) 2023 ByteDance + * Author: Peng Zhang */ =20 /* @@ -6475,6 +6479,292 @@ void *mtree_erase(struct maple_tree *mt, unsigned l= ong index) } EXPORT_SYMBOL(mtree_erase); =20 +/* + * mas_dup_free() - Free an incomplete duplication of a tree. + * @mas: The maple state of a incomplete tree. + * + * The parameter @mas->node passed in indicates that the allocation failed= on + * this node. This function frees all nodes starting from @mas->node in the + * reverse order of mas_dup_build(). There is no need to hold the source t= ree + * lock at this time. + */ +static void mas_dup_free(struct ma_state *mas) +{ + struct maple_node *node; + enum maple_type type; + void __rcu **slots; + unsigned char count, i; + + /* Maybe the first node allocation failed. */ + if (mas_is_none(mas)) + return; + + while (!mte_is_root(mas->node)) { + mas_ascend(mas); + + if (mas->offset) { + mas->offset--; + do { + mas_descend(mas); + mas->offset =3D mas_data_end(mas); + } while (!mte_is_leaf(mas->node)); + + mas_ascend(mas); + } + + node =3D mte_to_node(mas->node); + type =3D mte_node_type(mas->node); + slots =3D ma_slots(node, type); + count =3D mas_data_end(mas) + 1; + for (i =3D 0; i < count; i++) + ((unsigned long *)slots)[i] &=3D ~MAPLE_NODE_MASK; + + mt_free_bulk(count, slots); + } + + node =3D mte_to_node(mas->node); + mt_free_one(node); +} + +/* + * mas_copy_node() - Copy a maple node and replace the parent. + * @mas: The maple state of source tree. + * @new_mas: The maple state of new tree. + * @parent: The parent of the new node. + * + * Copy @mas->node to @new_mas->node, set @parent to be the parent of + * @new_mas->node. If memory allocation fails, @mas is set to -ENOMEM. + */ +static inline void mas_copy_node(struct ma_state *mas, struct ma_state *ne= w_mas, + struct maple_pnode *parent) +{ + struct maple_node *node =3D mte_to_node(mas->node); + struct maple_node *new_node =3D mte_to_node(new_mas->node); + unsigned long val; + + /* Copy the node completely. */ + memcpy(new_node, node, sizeof(struct maple_node)); + + /* Update the parent node pointer. */ + val =3D (unsigned long)node->parent & MAPLE_NODE_MASK; + new_node->parent =3D ma_parent_ptr(val | (unsigned long)parent); +} + +/* + * mas_dup_alloc() - Allocate child nodes for a maple node. + * @mas: The maple state of source tree. + * @new_mas: The maple state of new tree. + * @gfp: The GFP_FLAGS to use for allocations. + * + * This function allocates child nodes for @new_mas->node during the dupli= cation + * process. If memory allocation fails, @mas is set to -ENOMEM. + */ +static inline void mas_dup_alloc(struct ma_state *mas, struct ma_state *ne= w_mas, + gfp_t gfp) +{ + struct maple_node *node =3D mte_to_node(mas->node); + struct maple_node *new_node =3D mte_to_node(new_mas->node); + enum maple_type type; + unsigned char request, count, i; + void __rcu **slots; + void __rcu **new_slots; + unsigned long val; + + /* Allocate memory for child nodes. */ + type =3D mte_node_type(mas->node); + new_slots =3D ma_slots(new_node, type); + request =3D mas_data_end(mas) + 1; + count =3D mt_alloc_bulk(gfp, request, (void **)new_slots); + if (unlikely(count < request)) { + if (count) + mt_free_bulk(count, new_slots); + + memset(new_slots, 0, request * sizeof(void *)); + mas_set_err(mas, -ENOMEM); + return; + } + + /* Restore node type information in slots. */ + slots =3D ma_slots(node, type); + for (i =3D 0; i < count; i++) { + val =3D (unsigned long)mt_slot_locked(mas->tree, slots, i); + val &=3D MAPLE_NODE_MASK; + ((unsigned long *)new_slots)[i] |=3D val; + } +} + +/* + * mas_dup_build() - Build a new maple tree from a source tree + * @mas: The maple state of source tree, need to be in MAS_START state. + * @new_mas: The maple state of new tree, need to be in MAS_START state. + * @gfp: The GFP_FLAGS to use for allocations. + * + * This function builds a new tree in DFS preorder. If the memory allocati= on + * fails, the error code -ENOMEM will be set in @mas, and @new_mas points = to the + * last node. mas_dup_free() will free the incomplete duplication of a tre= e. + * + * Note that the attributes of the two trees need to be exactly the same, = and the + * new tree needs to be empty, otherwise -EINVAL will be set in @mas. + */ +static inline void mas_dup_build(struct ma_state *mas, struct ma_state *ne= w_mas, + gfp_t gfp) +{ + struct maple_node *node; + struct maple_pnode *parent =3D NULL; + struct maple_enode *root; + enum maple_type type; + + if (unlikely(mt_attr(mas->tree) !=3D mt_attr(new_mas->tree)) || + unlikely(!mtree_empty(new_mas->tree))) { + mas_set_err(mas, -EINVAL); + return; + } + + mas_start(mas); + if (mas_is_ptr(mas) || mas_is_none(mas)) { + root =3D mt_root_locked(mas->tree); + goto set_new_tree; + } + + node =3D mt_alloc_one(gfp); + if (!node) { + new_mas->node =3D MAS_NONE; + mas_set_err(mas, -ENOMEM); + return; + } + + type =3D mte_node_type(mas->node); + root =3D mt_mk_node(node, type); + new_mas->node =3D root; + new_mas->min =3D 0; + new_mas->max =3D ULONG_MAX; + root =3D mte_mk_root(root); + + while (1) { + mas_copy_node(mas, new_mas, parent); + + if (!mte_is_leaf(mas->node)) { + /* Only allocate child nodes for non-leaf nodes. */ + mas_dup_alloc(mas, new_mas, gfp); + if (unlikely(mas_is_err(mas))) + return; + } else { + /* + * This is the last leaf node and duplication is + * completed. + */ + if (mas->max =3D=3D ULONG_MAX) + goto done; + + /* This is not the last leaf node and needs to go up. */ + do { + mas_ascend(mas); + mas_ascend(new_mas); + } while (mas->offset =3D=3D mas_data_end(mas)); + + /* Move to the next subtree. */ + mas->offset++; + new_mas->offset++; + } + + mas_descend(mas); + parent =3D ma_parent_ptr(mte_to_node(new_mas->node)); + mas_descend(new_mas); + mas->offset =3D 0; + new_mas->offset =3D 0; + } +done: + /* Specially handle the parent of the root node. */ + mte_to_node(root)->parent =3D ma_parent_ptr(mas_tree_parent(new_mas)); +set_new_tree: + /* Make them the same height */ + new_mas->tree->ma_flags =3D mas->tree->ma_flags; + rcu_assign_pointer(new_mas->tree->ma_root, root); +} + +/** + * __mt_dup(): Duplicate an entire maple tree + * @mt: The source maple tree + * @new: The new maple tree + * @gfp: The GFP_FLAGS to use for allocations + * + * This function duplicates a maple tree in Depth-First Search (DFS) pre-o= rder + * traversal. It uses memcopy() to copy nodes in the source tree and alloc= ate + * new child nodes in non-leaf nodes. The new node is exactly the same as = the + * source node except for all the addresses stored in it. It will be faste= r than + * traversing all elements in the source tree and inserting them one by on= e into + * the new tree. + * The user needs to ensure that the attributes of the source tree and the= new + * tree are the same, and the new tree needs to be an empty tree, otherwise + * -EINVAL will be returned. + * Note that the user needs to manually lock the source tree and the new t= ree. + * + * Return: 0 on success, -ENOMEM if memory could not be allocated, -EINVAL= If + * the attributes of the two trees are different or the new tree is not an= empty + * tree. + */ +int __mt_dup(struct maple_tree *mt, struct maple_tree *new, gfp_t gfp) +{ + int ret =3D 0; + MA_STATE(mas, mt, 0, 0); + MA_STATE(new_mas, new, 0, 0); + + mas_dup_build(&mas, &new_mas, gfp); + + if (unlikely(mas_is_err(&mas))) { + ret =3D xa_err(mas.node); + if (ret =3D=3D -ENOMEM) + mas_dup_free(&new_mas); + } + + return ret; +} +EXPORT_SYMBOL(__mt_dup); + +/** + * mtree_dup(): Duplicate an entire maple tree + * @mt: The source maple tree + * @new: The new maple tree + * @gfp: The GFP_FLAGS to use for allocations + * + * This function duplicates a maple tree in Depth-First Search (DFS) pre-o= rder + * traversal. It uses memcopy() to copy nodes in the source tree and alloc= ate + * new child nodes in non-leaf nodes. The new node is exactly the same as = the + * source node except for all the addresses stored in it. It will be faste= r than + * traversing all elements in the source tree and inserting them one by on= e into + * the new tree. + * The user needs to ensure that the attributes of the source tree and the= new + * tree are the same, and the new tree needs to be an empty tree, otherwise + * -EINVAL will be returned. + * + * Return: 0 on success, -ENOMEM if memory could not be allocated, -EINVAL= If + * the attributes of the two trees are different or the new tree is not an= empty + * tree. + */ +int mtree_dup(struct maple_tree *mt, struct maple_tree *new, gfp_t gfp) +{ + int ret =3D 0; + MA_STATE(mas, mt, 0, 0); + MA_STATE(new_mas, new, 0, 0); + + mas_lock(&new_mas); + mas_lock_nested(&mas, SINGLE_DEPTH_NESTING); + + mas_dup_build(&mas, &new_mas, gfp); + mas_unlock(&mas); + + if (unlikely(mas_is_err(&mas))) { + ret =3D xa_err(mas.node); + if (ret =3D=3D -ENOMEM) + mas_dup_free(&new_mas); + } + + mas_unlock(&new_mas); + + return ret; +} +EXPORT_SYMBOL(mtree_dup); + /** * __mt_destroy() - Walk and free all nodes of a locked maple tree. * @mt: The maple tree --=20 2.20.1 From nobody Fri Jan 2 04:05:48 2026 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 8B1AFCDB465 for ; Mon, 16 Oct 2023 03:23:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231528AbjJPDXS (ORCPT ); Sun, 15 Oct 2023 23:23:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229600AbjJPDXK (ORCPT ); Sun, 15 Oct 2023 23:23:10 -0400 Received: from mail-pf1-x436.google.com (mail-pf1-x436.google.com [IPv6:2607:f8b0:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BBC27E6 for ; Sun, 15 Oct 2023 20:23:08 -0700 (PDT) Received: by mail-pf1-x436.google.com with SMTP id d2e1a72fcca58-68fb85afef4so3086318b3a.1 for ; Sun, 15 Oct 2023 20:23:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426588; x=1698031388; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XXZWHgZHrQ6fRhi1dWH8Hwu+H4KBhNEo2ODkb4cUdHA=; b=i7jsGdw0ITgbB+sXok0kbvMVrmxqxWdLOsPKKGXRS7ZV+Ib32o4zDlQNIYOlzoCgF1 yE2Ajf9i0s+IDxGRVfs4J/vlG95B3IvV0ZCBvsUOIGdG+YKLo3SVkcMrESaxUZE/FbeT 4T8s04fybllvgRqqMnojQbfs/gEM0PY6ku0LwMpCrMXt2StGilC1J+qJxapzyt5/99kl EVmVLty5j4Bz/BH8HIwj60ApI0i6bJrsIy2ysfh7mOgMO7Lb1HmbBjcn+PyrYhTfoo+d DG/8RbemO3WNH+ectz5QHapeEy8QplLnpv331f0XaHl7CvQvAbgBsOoJwiabiFdNwA7q A0LQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426588; x=1698031388; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XXZWHgZHrQ6fRhi1dWH8Hwu+H4KBhNEo2ODkb4cUdHA=; b=VqTmEW8s4YEq8B21R240oNeIxcTKoDqNONVCpnu9BF2Iv82+NGUX2MtSbUXbWdxunD z3ZtcqxDghBX9Uwk+hP6DX9+FCBjK91kZSo1/i9yjWtQ+EpebW7UH20OVzYS8nzKvTpa eFeQ+uilDsubID70PciJyNyfGYTBSX5sWC2Oh/N3Uw1DbvADT2gPH1vb40RmnEZuzIWa gAHGZbwF28Nj8w927tscSOA+wgUnNnkS/YuGH5VA2LF39x5deJGYbSzoaVIZekUm1UD+ 2Uk/iNqvc8KxVH+PXFsvTYlCHwjUQ2/17ELtb9RhZ7ZZ7JFF34HtQSIzdkigMTpySyIE ZUUg== X-Gm-Message-State: AOJu0YwBA5dVGNvcAsb+71B0PBqZKLCTXL4JTtqIx/i3kFEwn6w4RgpM d8lIkbmNS60kmLppSkfkwffwww== X-Google-Smtp-Source: AGHT+IHJ/d4Imcp6odYT1h7aWQHUYbM1ac42oVm99u/t154/4XdiI3P2y5GHneaRUB847sqBMYQ7vA== X-Received: by 2002:a05:6a21:7784:b0:173:318:b1ec with SMTP id bd4-20020a056a21778400b001730318b1ecmr12877225pzc.35.1697426588170; Sun, 15 Oct 2023 20:23:08 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.23.02 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:23:08 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 04/10] radix tree test suite: Align kmem_cache_alloc_bulk() with kernel behavior. Date: Mon, 16 Oct 2023 11:22:20 +0800 Message-Id: <20231016032226.59199-5-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" When kmem_cache_alloc_bulk() fails to allocate, leave the freed pointers in the array. This enables a more accurate simulation of the kernel's behavior and allows for testing potential double-free scenarios. Signed-off-by: Peng Zhang --- tools/testing/radix-tree/linux.c | 45 +++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/tools/testing/radix-tree/linux.c b/tools/testing/radix-tree/li= nux.c index 61fe2601cb3a..4eb442206d01 100644 --- a/tools/testing/radix-tree/linux.c +++ b/tools/testing/radix-tree/linux.c @@ -93,13 +93,9 @@ void *kmem_cache_alloc_lru(struct kmem_cache *cachep, st= ruct list_lru *lru, return p; } =20 -void kmem_cache_free_locked(struct kmem_cache *cachep, void *objp) +void __kmem_cache_free_locked(struct kmem_cache *cachep, void *objp) { assert(objp); - uatomic_dec(&nr_allocated); - uatomic_dec(&cachep->nr_allocated); - if (kmalloc_verbose) - printf("Freeing %p to slab\n", objp); if (cachep->nr_objs > 10 || cachep->align) { memset(objp, POISON_FREE, cachep->size); free(objp); @@ -111,6 +107,15 @@ void kmem_cache_free_locked(struct kmem_cache *cachep,= void *objp) } } =20 +void kmem_cache_free_locked(struct kmem_cache *cachep, void *objp) +{ + uatomic_dec(&nr_allocated); + uatomic_dec(&cachep->nr_allocated); + if (kmalloc_verbose) + printf("Freeing %p to slab\n", objp); + __kmem_cache_free_locked(cachep, objp); +} + void kmem_cache_free(struct kmem_cache *cachep, void *objp) { pthread_mutex_lock(&cachep->lock); @@ -141,18 +146,17 @@ int kmem_cache_alloc_bulk(struct kmem_cache *cachep, = gfp_t gfp, size_t size, if (kmalloc_verbose) pr_debug("Bulk alloc %lu\n", size); =20 - if (!(gfp & __GFP_DIRECT_RECLAIM)) { - if (cachep->non_kernel < size) - return 0; - - cachep->non_kernel -=3D size; - } - pthread_mutex_lock(&cachep->lock); if (cachep->nr_objs >=3D size) { struct radix_tree_node *node; =20 for (i =3D 0; i < size; i++) { + if (!(gfp & __GFP_DIRECT_RECLAIM)) { + if (!cachep->non_kernel) + break; + cachep->non_kernel--; + } + node =3D cachep->objs; cachep->nr_objs--; cachep->objs =3D node->parent; @@ -163,11 +167,19 @@ int kmem_cache_alloc_bulk(struct kmem_cache *cachep, = gfp_t gfp, size_t size, } else { pthread_mutex_unlock(&cachep->lock); for (i =3D 0; i < size; i++) { + if (!(gfp & __GFP_DIRECT_RECLAIM)) { + if (!cachep->non_kernel) + break; + cachep->non_kernel--; + } + if (cachep->align) { posix_memalign(&p[i], cachep->align, cachep->size); } else { p[i] =3D malloc(cachep->size); + if (!p[i]) + break; } if (cachep->ctor) cachep->ctor(p[i]); @@ -176,6 +188,15 @@ int kmem_cache_alloc_bulk(struct kmem_cache *cachep, g= fp_t gfp, size_t size, } } =20 + if (i < size) { + size =3D i; + pthread_mutex_lock(&cachep->lock); + for (i =3D 0; i < size; i++) + __kmem_cache_free_locked(cachep, p[i]); + pthread_mutex_unlock(&cachep->lock); + return 0; + } + for (i =3D 0; i < size; i++) { uatomic_inc(&nr_allocated); uatomic_inc(&cachep->nr_allocated); --=20 2.20.1 From nobody Fri Jan 2 04:05:48 2026 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 11B41CDB465 for ; Mon, 16 Oct 2023 03:24:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231602AbjJPDX6 (ORCPT ); Sun, 15 Oct 2023 23:23:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231496AbjJPDXk (ORCPT ); Sun, 15 Oct 2023 23:23:40 -0400 Received: from mail-pf1-x431.google.com (mail-pf1-x431.google.com [IPv6:2607:f8b0:4864:20::431]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0CF02EB for ; Sun, 15 Oct 2023 20:23:16 -0700 (PDT) Received: by mail-pf1-x431.google.com with SMTP id d2e1a72fcca58-6b9af7d41d2so996372b3a.0 for ; Sun, 15 Oct 2023 20:23:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426595; x=1698031395; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=F9a2wn71CT7l6jmeDgx5GiWCiAo5KcsAe/ofRJgEyKw=; b=OyCMh/Rp5t2V0Ou65Sr42EMkWYdXapQEDwkaAZM2P7w6PGJKvrAlMwjlV9rWwIG//K KGzauD37ELh+veWt0VaHURByAvUYUs9If4omNmlGYUMc36YV7yA3LwFiJ8zdysoTIxJ3 5w0bY6K5AItR1M/QDqYMTeJCkWUgfpapULxUFnh/iRDkWUEYhbnqdxPjc45qsnLlHV6E U2aJ5viq+C5ael90kXXBqPtAIsSdCsgAWtj8ievciNNRTU93vDqnNV0j+ONDIEj+PgZt JRxjoUgYsYP5ukPxOQnER1GZ2YoqLYrbjsEuAilTBaOlTcScLl5HovbCeOOOYgnL1ISM B2ng== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426595; x=1698031395; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=F9a2wn71CT7l6jmeDgx5GiWCiAo5KcsAe/ofRJgEyKw=; b=fy6qsW64CKDmLrxmXKnlfFf93KBAVMI8p/+nD64QbTgym+fenzgTzy3Kpn0gMUbTML lVMjeiP9qW7Y+ho1Hy7qHDGlrxMnKHuEfZ1dWTQfawS1yl7rQ4FuiqXF4+5us7mNseAG ETOXVGZdc31wJPi2FS8hsNgvQS8PGRpHMsBWKQSEqutWphO+FNTBBAezuDSoWFFsQNws c7GReGMERLwY72w/bh6AM1s38A5anr1yNKfq8F4QKOMvK0ZsndM6Ibq4aMMpfhp3ljrv +o9lErM3amSALKTxTCB8R9Llrr2vNreoCb8QPplEeuUrq87KsEHiZEdh4D23m3XQ4UJL r30A== X-Gm-Message-State: AOJu0YwY1XbbKqkPvX0OEHSCmuvAl4li3sIvHEDAqVXKlEZcc6MGaaww +Ka0/JlPA11jitItCmpnonS99A== X-Google-Smtp-Source: AGHT+IGfkGw9y388wqErZbGuxg5O4sRO6G1a56lBOIRT0nXItmG3Y4vPWvZ0dvag+P/jrPSrL3fIAQ== X-Received: by 2002:a05:6a20:842a:b0:154:6480:83b4 with SMTP id c42-20020a056a20842a00b00154648083b4mr35089804pzd.14.1697426595460; Sun, 15 Oct 2023 20:23:15 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.23.08 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:23:15 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 05/10] maple_tree: Add test for mtree_dup() Date: Mon, 16 Oct 2023 11:22:21 +0800 Message-Id: <20231016032226.59199-6-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add test for mtree_dup(). Test by duplicating different maple trees and then comparing the two trees. Includes tests for duplicating full trees and memory allocation failures on different nodes. Signed-off-by: Peng Zhang --- tools/testing/radix-tree/maple.c | 361 +++++++++++++++++++++++++++++++ 1 file changed, 361 insertions(+) diff --git a/tools/testing/radix-tree/maple.c b/tools/testing/radix-tree/ma= ple.c index e5da1cad70ba..12b3390e9591 100644 --- a/tools/testing/radix-tree/maple.c +++ b/tools/testing/radix-tree/maple.c @@ -35857,6 +35857,363 @@ static noinline void __init check_locky(struct ma= ple_tree *mt) mt_clear_in_rcu(mt); } =20 +/* + * Compares two nodes except for the addresses stored in the nodes. + * Returns zero if they are the same, otherwise returns non-zero. + */ +static int __init compare_node(struct maple_enode *enode_a, + struct maple_enode *enode_b) +{ + struct maple_node *node_a, *node_b; + struct maple_node a, b; + void **slots_a, **slots_b; /* Do not use the rcu tag. */ + enum maple_type type; + int i; + + if (((unsigned long)enode_a & MAPLE_NODE_MASK) !=3D + ((unsigned long)enode_b & MAPLE_NODE_MASK)) { + pr_err("The lower 8 bits of enode are different.\n"); + return -1; + } + + type =3D mte_node_type(enode_a); + node_a =3D mte_to_node(enode_a); + node_b =3D mte_to_node(enode_b); + a =3D *node_a; + b =3D *node_b; + + /* Do not compare addresses. */ + if (ma_is_root(node_a) || ma_is_root(node_b)) { + a.parent =3D (struct maple_pnode *)((unsigned long)a.parent & + MA_ROOT_PARENT); + b.parent =3D (struct maple_pnode *)((unsigned long)b.parent & + MA_ROOT_PARENT); + } else { + a.parent =3D (struct maple_pnode *)((unsigned long)a.parent & + MAPLE_NODE_MASK); + b.parent =3D (struct maple_pnode *)((unsigned long)b.parent & + MAPLE_NODE_MASK); + } + + if (a.parent !=3D b.parent) { + pr_err("The lower 8 bits of parents are different. %p %p\n", + a.parent, b.parent); + return -1; + } + + /* + * If it is a leaf node, the slots do not contain the node address, and + * no special processing of slots is required. + */ + if (ma_is_leaf(type)) + goto cmp; + + slots_a =3D ma_slots(&a, type); + slots_b =3D ma_slots(&b, type); + + for (i =3D 0; i < mt_slots[type]; i++) { + if (!slots_a[i] && !slots_b[i]) + break; + + if (!slots_a[i] || !slots_b[i]) { + pr_err("The number of slots is different.\n"); + return -1; + } + + /* Do not compare addresses in slots. */ + ((unsigned long *)slots_a)[i] &=3D MAPLE_NODE_MASK; + ((unsigned long *)slots_b)[i] &=3D MAPLE_NODE_MASK; + } + +cmp: + /* + * Compare all contents of two nodes, including parent (except address), + * slots (except address), pivots, gaps and metadata. + */ + return memcmp(&a, &b, sizeof(struct maple_node)); +} + +/* + * Compare two trees and return 0 if they are the same, non-zero otherwise. + */ +static int __init compare_tree(struct maple_tree *mt_a, struct maple_tree = *mt_b) +{ + MA_STATE(mas_a, mt_a, 0, 0); + MA_STATE(mas_b, mt_b, 0, 0); + + if (mt_a->ma_flags !=3D mt_b->ma_flags) { + pr_err("The flags of the two trees are different.\n"); + return -1; + } + + mas_dfs_preorder(&mas_a); + mas_dfs_preorder(&mas_b); + + if (mas_is_ptr(&mas_a) || mas_is_ptr(&mas_b)) { + if (!(mas_is_ptr(&mas_a) && mas_is_ptr(&mas_b))) { + pr_err("One is MAS_ROOT and the other is not.\n"); + return -1; + } + return 0; + } + + while (!mas_is_none(&mas_a) || !mas_is_none(&mas_b)) { + + if (mas_is_none(&mas_a) || mas_is_none(&mas_b)) { + pr_err("One is MAS_NONE and the other is not.\n"); + return -1; + } + + if (mas_a.min !=3D mas_b.min || + mas_a.max !=3D mas_b.max) { + pr_err("mas->min, mas->max do not match.\n"); + return -1; + } + + if (compare_node(mas_a.node, mas_b.node)) { + pr_err("The contents of nodes %p and %p are different.\n", + mas_a.node, mas_b.node); + mt_dump(mt_a, mt_dump_dec); + mt_dump(mt_b, mt_dump_dec); + return -1; + } + + mas_dfs_preorder(&mas_a); + mas_dfs_preorder(&mas_b); + } + + return 0; +} + +static __init void mas_subtree_max_range(struct ma_state *mas) +{ + unsigned long limit =3D mas->max; + MA_STATE(newmas, mas->tree, 0, 0); + void *entry; + + mas_for_each(mas, entry, limit) { + if (mas->last - mas->index >=3D + newmas.last - newmas.index) { + newmas =3D *mas; + } + } + + *mas =3D newmas; +} + +/* + * build_full_tree() - Build a full tree. + * @mt: The tree to build. + * @flags: Use @flags to build the tree. + * @height: The height of the tree to build. + * + * Build a tree with full leaf nodes and internal nodes. Note that the hei= ght + * should not exceed 3, otherwise it will take a long time to build. + * Return: zero if the build is successful, non-zero if it fails. + */ +static __init int build_full_tree(struct maple_tree *mt, unsigned int flag= s, + int height) +{ + MA_STATE(mas, mt, 0, 0); + unsigned long step; + int ret =3D 0, cnt =3D 1; + enum maple_type type; + + mt_init_flags(mt, flags); + mtree_insert_range(mt, 0, ULONG_MAX, xa_mk_value(5), GFP_KERNEL); + + mtree_lock(mt); + + while (1) { + mas_set(&mas, 0); + if (mt_height(mt) < height) { + mas.max =3D ULONG_MAX; + goto store; + } + + while (1) { + mas_dfs_preorder(&mas); + if (mas_is_none(&mas)) + goto unlock; + + type =3D mte_node_type(mas.node); + if (mas_data_end(&mas) + 1 < mt_slots[type]) { + mas_set(&mas, mas.min); + goto store; + } + } +store: + mas_subtree_max_range(&mas); + step =3D mas.last - mas.index; + if (step < 1) { + ret =3D -1; + goto unlock; + } + + step /=3D 2; + mas.last =3D mas.index + step; + mas_store_gfp(&mas, xa_mk_value(5), + GFP_KERNEL); + ++cnt; + } +unlock: + mtree_unlock(mt); + + MT_BUG_ON(mt, mt_height(mt) !=3D height); + /* pr_info("height:%u number of elements:%d\n", mt_height(mt), cnt); */ + return ret; +} + +static noinline void __init check_mtree_dup(struct maple_tree *mt) +{ + DEFINE_MTREE(new); + int i, j, ret, count =3D 0; + unsigned int rand_seed =3D 17, rand; + + /* store a value at [0, 0] */ + mt_init_flags(mt, 0); + mtree_store_range(mt, 0, 0, xa_mk_value(0), GFP_KERNEL); + ret =3D mtree_dup(mt, &new, GFP_KERNEL); + MT_BUG_ON(&new, ret); + mt_validate(&new); + if (compare_tree(mt, &new)) + MT_BUG_ON(&new, 1); + + mtree_destroy(mt); + mtree_destroy(&new); + + /* The two trees have different attributes. */ + mt_init_flags(mt, 0); + mt_init_flags(&new, MT_FLAGS_ALLOC_RANGE); + ret =3D mtree_dup(mt, &new, GFP_KERNEL); + MT_BUG_ON(&new, ret !=3D -EINVAL); + mtree_destroy(mt); + mtree_destroy(&new); + + /* The new tree is not empty */ + mt_init_flags(mt, 0); + mt_init_flags(&new, 0); + mtree_store(&new, 5, xa_mk_value(5), GFP_KERNEL); + ret =3D mtree_dup(mt, &new, GFP_KERNEL); + MT_BUG_ON(&new, ret !=3D -EINVAL); + mtree_destroy(mt); + mtree_destroy(&new); + + /* Test for duplicating full trees. */ + for (i =3D 1; i <=3D 3; i++) { + ret =3D build_full_tree(mt, 0, i); + MT_BUG_ON(mt, ret); + mt_init_flags(&new, 0); + + ret =3D mtree_dup(mt, &new, GFP_KERNEL); + MT_BUG_ON(&new, ret); + mt_validate(&new); + if (compare_tree(mt, &new)) + MT_BUG_ON(&new, 1); + + mtree_destroy(mt); + mtree_destroy(&new); + } + + for (i =3D 1; i <=3D 3; i++) { + ret =3D build_full_tree(mt, MT_FLAGS_ALLOC_RANGE, i); + MT_BUG_ON(mt, ret); + mt_init_flags(&new, MT_FLAGS_ALLOC_RANGE); + + ret =3D mtree_dup(mt, &new, GFP_KERNEL); + MT_BUG_ON(&new, ret); + mt_validate(&new); + if (compare_tree(mt, &new)) + MT_BUG_ON(&new, 1); + + mtree_destroy(mt); + mtree_destroy(&new); + } + + /* Test for normal duplicating. */ + for (i =3D 0; i < 1000; i +=3D 3) { + if (i & 1) { + mt_init_flags(mt, 0); + mt_init_flags(&new, 0); + } else { + mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE); + mt_init_flags(&new, MT_FLAGS_ALLOC_RANGE); + } + + for (j =3D 0; j < i; j++) { + mtree_store_range(mt, j * 10, j * 10 + 5, + xa_mk_value(j), GFP_KERNEL); + } + + ret =3D mtree_dup(mt, &new, GFP_KERNEL); + MT_BUG_ON(&new, ret); + mt_validate(&new); + if (compare_tree(mt, &new)) + MT_BUG_ON(&new, 1); + + mtree_destroy(mt); + mtree_destroy(&new); + } + + /* Test memory allocation failed. */ + mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE); + for (i =3D 0; i < 30; i +=3D 3) { + mtree_store_range(mt, j * 10, j * 10 + 5, + xa_mk_value(j), GFP_KERNEL); + } + + /* Failed at the first node. */ + mt_init_flags(&new, MT_FLAGS_ALLOC_RANGE); + mt_set_non_kernel(0); + ret =3D mtree_dup(mt, &new, GFP_NOWAIT); + mt_set_non_kernel(0); + MT_BUG_ON(&new, ret !=3D -ENOMEM); + mtree_destroy(mt); + mtree_destroy(&new); + + /* Random maple tree fails at a random node. */ + for (i =3D 0; i < 1000; i +=3D 3) { + if (i & 1) { + mt_init_flags(mt, 0); + mt_init_flags(&new, 0); + } else { + mt_init_flags(mt, MT_FLAGS_ALLOC_RANGE); + mt_init_flags(&new, MT_FLAGS_ALLOC_RANGE); + } + + for (j =3D 0; j < i; j++) { + mtree_store_range(mt, j * 10, j * 10 + 5, + xa_mk_value(j), GFP_KERNEL); + } + /* + * The rand() library function is not used, so we can generate + * the same random numbers on any platform. + */ + rand_seed =3D rand_seed * 1103515245 + 12345; + rand =3D rand_seed / 65536 % 128; + mt_set_non_kernel(rand); + + ret =3D mtree_dup(mt, &new, GFP_NOWAIT); + mt_set_non_kernel(0); + if (ret !=3D 0) { + MT_BUG_ON(&new, ret !=3D -ENOMEM); + count++; + mtree_destroy(mt); + continue; + } + + mt_validate(&new); + if (compare_tree(mt, &new)) + MT_BUG_ON(&new, 1); + + mtree_destroy(mt); + mtree_destroy(&new); + } + + /* pr_info("mtree_dup() fail %d times\n", count); */ + BUG_ON(!count); +} + extern void test_kmem_cache_bulk(void); =20 void farmer_tests(void) @@ -35904,6 +36261,10 @@ void farmer_tests(void) check_null_expand(&tree); mtree_destroy(&tree); =20 + mt_init_flags(&tree, 0); + check_mtree_dup(&tree); + mtree_destroy(&tree); + /* RCU testing */ mt_init_flags(&tree, 0); check_erase_testset(&tree); --=20 2.20.1 From nobody Fri Jan 2 04:05:48 2026 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 911E0CDB474 for ; Mon, 16 Oct 2023 03:24:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231669AbjJPDYE (ORCPT ); Sun, 15 Oct 2023 23:24:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46618 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231487AbjJPDXu (ORCPT ); Sun, 15 Oct 2023 23:23:50 -0400 Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21EF5121 for ; Sun, 15 Oct 2023 20:23:22 -0700 (PDT) Received: by mail-pj1-x102e.google.com with SMTP id 98e67ed59e1d1-27d425a2dd0so2089438a91.2 for ; Sun, 15 Oct 2023 20:23:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426602; x=1698031402; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mFyp/FJQdSo4OvDS2koRMpNI0AcMCWskpm09jBYSG+0=; b=kCQ6ToiF4tK9Ah92GNg5TaAJH2qFerDDDeci+Dl8QIA4veI+7dF6r+thPfSwSjgPuw U0//5u/7iDbZV/sM1weFdoDACTZwbMou/Jd481oDYd7LXFNTbzixkHBuR8vTLBHT+ZkS U/oa9p9M37Xe8MgWDMpSwaKee3osY/BrU49JpLQtd3Gb05imftp3A1j+x1Ccoa0o+Q3z cCcCCvY32R+Zmwo0kZqUBMvLEuDv4gUi1Uq1Ysl1TbqxUmQ8o/ZTXzNK0id0oKd/wYiu s5bikXmmEINQF++9dUH4ths1yijV4Uos09tPr7uAjhGQAeHAf0WaNgkZ7ATYgZQlv70U /jpQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426602; x=1698031402; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mFyp/FJQdSo4OvDS2koRMpNI0AcMCWskpm09jBYSG+0=; b=HQujiuCD4qfk9hG0IesLfZdri24P/+z6J0ArN7kDLbNb1eBiY/1LJrM3n5MCgpoa0k KEcHvFeFtMbWxtzB93b4XZ89kQggLO6oTNVHPoGnj7KwLkhSb8VVx9wRyQeJG9tOak4H 4sKNZMxfGWvw1kSjbTlRgybaBYoA/HG6OM5UUV0HEhxNzAwL+/vyj2Rq3rtqgXCmvKIS 5Besg4nlS1E2azNhFxEWgH9bhAMGm8sF7X/sIybK0woRu1b6CD6FPb91Atd+VFqa9kq5 fe5OR45AIOsRCLoqxLuFGS8m1XFPoGADvJke593NWe5lrQUZQA7fez3VasJ533dxDoxj WCkg== X-Gm-Message-State: AOJu0YwzDKa6AA2XMgFSgHAEKGu954wHKLjp/tFPit22dYyktgLACW7H /uMVJuWfeMwnNiUH8UOcTsIIuw== X-Google-Smtp-Source: AGHT+IEmk/zJXO2kK7nOf720yU64zVWPpcUxkrQhPVMBOjATtllYWJlNEGVjqoAJdP0W8HkSSk7e1g== X-Received: by 2002:a17:90a:f408:b0:27d:f85:9505 with SMTP id ch8-20020a17090af40800b0027d0f859505mr11824455pjb.24.1697426601858; Sun, 15 Oct 2023 20:23:21 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.23.15 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:23:21 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 06/10] maple_tree: Update the documentation of maple tree Date: Mon, 16 Oct 2023 11:22:22 +0800 Message-Id: <20231016032226.59199-7-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Introduce the new interface mtree_dup() in the documentation. Signed-off-by: Peng Zhang --- Documentation/core-api/maple_tree.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/core-api/maple_tree.rst b/Documentation/core-api= /maple_tree.rst index 45defcf15da7..285e2d2b21ae 100644 --- a/Documentation/core-api/maple_tree.rst +++ b/Documentation/core-api/maple_tree.rst @@ -81,6 +81,9 @@ section. Sometimes it is necessary to ensure the next call to store to a maple tree= does not allocate memory, please see :ref:`maple-tree-advanced-api` for this us= e case. =20 +You can use mtree_dup() to duplicate an entire maple tree. It is a more +efficient way than inserting all elements one by one into a new tree. + Finally, you can remove all entries from a maple tree by calling mtree_destroy(). If the maple tree entries are pointers, you may wish to = free the entries first. @@ -112,6 +115,7 @@ Takes ma_lock internally: * mtree_insert() * mtree_insert_range() * mtree_erase() + * mtree_dup() * mtree_destroy() * mt_set_in_rcu() * mt_clear_in_rcu() --=20 2.20.1 From nobody Fri Jan 2 04:05:48 2026 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 36E2ACDB465 for ; Mon, 16 Oct 2023 03:24:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231689AbjJPDYW (ORCPT ); Sun, 15 Oct 2023 23:24:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38176 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231587AbjJPDYA (ORCPT ); Sun, 15 Oct 2023 23:24:00 -0400 Received: from mail-pf1-x433.google.com (mail-pf1-x433.google.com [IPv6:2607:f8b0:4864:20::433]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99775102 for ; Sun, 15 Oct 2023 20:23:29 -0700 (PDT) Received: by mail-pf1-x433.google.com with SMTP id d2e1a72fcca58-6bd96cfb99cso500625b3a.2 for ; Sun, 15 Oct 2023 20:23:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426608; x=1698031408; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QmT9t2gNl7JC/Wj/BeBLe/fYUtz3EaMSD0bTELVUlD4=; b=PGqbqWCdExRsioHDuhcF8pwe4rhDYhMiyYzpENET4J8HssE32sg5UT+tPIiLfnGHSS qf5Ubjwg/btvdCzgY0RRW/5jmsfBXJH9o9xjijTkWbq42NA2/cT4SrAPyXQRlbIVg7oS XvbYUpObqP0jpqdiZiVGQ8fIl1mz6hBbtDP2ZMx1buFYCrN86DV/YjDgbWxTCR6/SV7u oaTYx/mnAOs0+xlSlBaZeq2jwDTccLFbG6m7SmXayyZWkcwP1Vh2l5OWqYsVXYCeAsxX YZEzL77M++I5C9xdMppQ1ViLBU4TPbLQFGa9y1qc9B+rzSkMZ++Lo7NSaqKYRp7qmcjw bA3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426608; x=1698031408; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QmT9t2gNl7JC/Wj/BeBLe/fYUtz3EaMSD0bTELVUlD4=; b=Q2NCSRiLp27JGfUcBJmB9DkgwlqW7laNxG9ansQDgg+AOo5sdpSXQvmeR70eDBpczI chea6kRNez/WiQTPKOfPdUmhC/ebiDfJ1ZinBFxm5xiQzgcV7uDP36p5R3rIKvx60M83 AHqDUIa7CzATFATkHBsk+mm2IoeIdUhdhWCE28ByUt8RP7wMFoSRNmzET5SOTgxmL3G3 RSPEM3h6vJ/vVbTnTT2j+NbM76Afgds5I2WkUJN9hKdXlFUNCzk1njgrY9+uQOr5i0R7 32LCvnkQdQ7u974mvqFOKtLGA/hS0IhDD78HTD2PvX0rttPwdFlxavBxw9gZ5v2ecq8V zkfQ== X-Gm-Message-State: AOJu0YwDsnAb4rwMmDjF2iiqgS9N2BwBYre1yexV3CpwO6ACzvONUq6B eaRWVQiRv4N6cFx4gXCm15iBDg== X-Google-Smtp-Source: AGHT+IFvL4hHx8r3LC1uMkvj+QBP/kQF+gthm2OJTyOv0wHL/s0lrpx6RI7lgcxm3OD63XtqW60qEg== X-Received: by 2002:a05:6a21:a58b:b0:15d:607b:5a39 with SMTP id gd11-20020a056a21a58b00b0015d607b5a39mr34613164pzc.30.1697426608596; Sun, 15 Oct 2023 20:23:28 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.23.22 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:23:28 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 07/10] maple_tree: Skip other tests when BENCH is enabled Date: Mon, 16 Oct 2023 11:22:23 +0800 Message-Id: <20231016032226.59199-8-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Skip other tests when BENCH is enabled so that performance can be measured in user space. Signed-off-by: Peng Zhang --- lib/test_maple_tree.c | 8 ++++---- tools/testing/radix-tree/maple.c | 2 ++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c index 464eeb90d5ad..de470950714f 100644 --- a/lib/test_maple_tree.c +++ b/lib/test_maple_tree.c @@ -3585,10 +3585,6 @@ static int __init maple_tree_seed(void) =20 pr_info("\nTEST STARTING\n\n"); =20 - mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); - check_root_expand(&tree); - mtree_destroy(&tree); - #if defined(BENCH_SLOT_STORE) #define BENCH mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); @@ -3646,6 +3642,10 @@ static int __init maple_tree_seed(void) goto skip; #endif =20 + mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); + check_root_expand(&tree); + mtree_destroy(&tree); + mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); check_iteration(&tree); mtree_destroy(&tree); diff --git a/tools/testing/radix-tree/maple.c b/tools/testing/radix-tree/ma= ple.c index 12b3390e9591..cb5358674521 100644 --- a/tools/testing/radix-tree/maple.c +++ b/tools/testing/radix-tree/maple.c @@ -36299,7 +36299,9 @@ void farmer_tests(void) =20 void maple_tree_tests(void) { +#if !defined(BENCH) farmer_tests(); +#endif maple_tree_seed(); maple_tree_harvest(); } --=20 2.20.1 From nobody Fri Jan 2 04:05:48 2026 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 63B16CDB482 for ; Mon, 16 Oct 2023 03:25:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232071AbjJPDYa (ORCPT ); Sun, 15 Oct 2023 23:24:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38084 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231415AbjJPDYD (ORCPT ); Sun, 15 Oct 2023 23:24:03 -0400 Received: from mail-pg1-x534.google.com (mail-pg1-x534.google.com [IPv6:2607:f8b0:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 14DF5EE for ; Sun, 15 Oct 2023 20:23:35 -0700 (PDT) Received: by mail-pg1-x534.google.com with SMTP id 41be03b00d2f7-5aaefc07e5cso1384653a12.0 for ; Sun, 15 Oct 2023 20:23:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426615; x=1698031415; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dqxLSD3NSY9H2G/bHFoEqq0XRO6Fu01n0ZJ8sfPfXdw=; b=PWbmx9YuTWFcMGW/NMbyKnIWGT7N3bsKa9JcdoQIYmcFGMDqT0JvXqUu6YRG48FMQT ibe0yEPZ0WgTmMqOO5OBDhOP3YERdeMpsH90uYgBSCjSnbT2t51KBTML5XjTDZHQG8ly ZLllYNAaqrStKl/rJZ4C3sdROmXTTeR7WRzV83FuAsMAx6LbBDtr6txM4p/v4JFdvP6P 0WaJFLZomueAfVemxBoCqcjXxhe4pSgwE7H62bU1L2p/aWr7+bU9LBBkOmrXvA/xHaP2 FlWdVeUBz/2XggJbo5cBvIniXzTvyR47I3PO9uH80C+lZWX5Xj7EHqN/pYPZgJxWQCKu Rkqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426615; x=1698031415; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dqxLSD3NSY9H2G/bHFoEqq0XRO6Fu01n0ZJ8sfPfXdw=; b=mdHyxw4/9qKaEjiYwpL5oUZ2DOBvBW767+iiBebsQgLq+5SGC7MPTD9TAznFnWVgjC IMOiRypyvkGsNJOCnKrcLbpYXuMrDyj8xYiIuwfA+8GVZocjyUkwgOGxRCLm9BaSAEt3 0LVHDyS9xpr+TUTJ33Q2Bfnt4Ow8RxO7sjb7p4bKSV/K8oOvJMjxn8QExsU22M0ZD0nH HO8Y0GvPyst5mIeGsNcbxIWEeSQ9QOuL1yR1yHZzFXUJ6uGQa09JHNkhWdeRuDZx2r74 XTiUcZ/A01TYOp8o0RZYxARO4a5lNl6I6wwxVFLXwF20CYb3hp8kHjYkNFTCJtPTfqGv p63w== X-Gm-Message-State: AOJu0Yyc7A0U10ggXr51ZWv9IMidvGl7Hnxk3XbdMTImoIDmy0LQ5Nlx SwWceRnR1ODKJm0gecGWEOIlvg== X-Google-Smtp-Source: AGHT+IHmA+WtBu9NLQQzhIWS0nTFs0epfhl1qYL4Lf5DRNzLjrSSQh6nGRADfVlcdpst5WMiKPi/tw== X-Received: by 2002:a17:90b:4fc2:b0:278:f907:719d with SMTP id qa2-20020a17090b4fc200b00278f907719dmr25042669pjb.48.1697426615383; Sun, 15 Oct 2023 20:23:35 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.23.29 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:23:35 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 08/10] maple_tree: Update check_forking() and bench_forking() Date: Mon, 16 Oct 2023 11:22:24 +0800 Message-Id: <20231016032226.59199-9-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Updated check_forking() and bench_forking() to use __mt_dup() to duplicate maple tree. Signed-off-by: Peng Zhang --- lib/test_maple_tree.c | 117 ++++++++++++++++++------------------ tools/include/linux/rwsem.h | 4 ++ 2 files changed, 62 insertions(+), 59 deletions(-) diff --git a/lib/test_maple_tree.c b/lib/test_maple_tree.c index de470950714f..3e4597fb49d3 100644 --- a/lib/test_maple_tree.c +++ b/lib/test_maple_tree.c @@ -1834,47 +1834,48 @@ static noinline void __init bench_mas_prev(struct m= aple_tree *mt) } #endif /* check_forking - simulate the kernel forking sequence with the tree. */ -static noinline void __init check_forking(struct maple_tree *mt) +static noinline void __init check_forking(void) { - - struct maple_tree newmt; - int i, nr_entries =3D 134; + struct maple_tree mt, newmt; + int i, nr_entries =3D 134, ret; void *val; - MA_STATE(mas, mt, 0, 0); - MA_STATE(newmas, mt, 0, 0); - struct rw_semaphore newmt_lock; + MA_STATE(mas, &mt, 0, 0); + MA_STATE(newmas, &newmt, 0, 0); + struct rw_semaphore mt_lock, newmt_lock; =20 + init_rwsem(&mt_lock); init_rwsem(&newmt_lock); =20 - for (i =3D 0; i <=3D nr_entries; i++) - mtree_store_range(mt, i*10, i*10 + 5, - xa_mk_value(i), GFP_KERNEL); + mt_init_flags(&mt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN); + mt_set_external_lock(&mt, &mt_lock); =20 - mt_set_non_kernel(99999); mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN); mt_set_external_lock(&newmt, &newmt_lock); - newmas.tree =3D &newmt; - mas_reset(&newmas); - mas_reset(&mas); - down_write(&newmt_lock); - mas.index =3D 0; - mas.last =3D 0; - if (mas_expected_entries(&newmas, nr_entries)) { + + down_write(&mt_lock); + for (i =3D 0; i <=3D nr_entries; i++) { + mas_set_range(&mas, i*10, i*10 + 5); + mas_store_gfp(&mas, xa_mk_value(i), GFP_KERNEL); + } + + down_write_nested(&newmt_lock, SINGLE_DEPTH_NESTING); + ret =3D __mt_dup(&mt, &newmt, GFP_KERNEL); + if (ret) { pr_err("OOM!"); BUG_ON(1); } - rcu_read_lock(); - mas_for_each(&mas, val, ULONG_MAX) { - newmas.index =3D mas.index; - newmas.last =3D mas.last; + + mas_set(&newmas, 0); + mas_for_each(&newmas, val, ULONG_MAX) mas_store(&newmas, val); - } - rcu_read_unlock(); + mas_destroy(&newmas); + mas_destroy(&mas); mt_validate(&newmt); - mt_set_non_kernel(0); __mt_destroy(&newmt); + __mt_destroy(&mt); up_write(&newmt_lock); + up_write(&mt_lock); } =20 static noinline void __init check_iteration(struct maple_tree *mt) @@ -1977,49 +1978,51 @@ static noinline void __init check_mas_store_gfp(str= uct maple_tree *mt) } =20 #if defined(BENCH_FORK) -static noinline void __init bench_forking(struct maple_tree *mt) +static noinline void __init bench_forking(void) { - - struct maple_tree newmt; - int i, nr_entries =3D 134, nr_fork =3D 80000; + struct maple_tree mt, newmt; + int i, nr_entries =3D 134, nr_fork =3D 80000, ret; void *val; - MA_STATE(mas, mt, 0, 0); - MA_STATE(newmas, mt, 0, 0); - struct rw_semaphore newmt_lock; + MA_STATE(mas, &mt, 0, 0); + MA_STATE(newmas, &newmt, 0, 0); + struct rw_semaphore mt_lock, newmt_lock; =20 + init_rwsem(&mt_lock); init_rwsem(&newmt_lock); - mt_set_external_lock(&newmt, &newmt_lock); =20 - for (i =3D 0; i <=3D nr_entries; i++) - mtree_store_range(mt, i*10, i*10 + 5, - xa_mk_value(i), GFP_KERNEL); + mt_init_flags(&mt, MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN); + mt_set_external_lock(&mt, &mt_lock); + + down_write(&mt_lock); + for (i =3D 0; i <=3D nr_entries; i++) { + mas_set_range(&mas, i*10, i*10 + 5); + mas_store_gfp(&mas, xa_mk_value(i), GFP_KERNEL); + } =20 for (i =3D 0; i < nr_fork; i++) { - mt_set_non_kernel(99999); - mt_init_flags(&newmt, MT_FLAGS_ALLOC_RANGE); - newmas.tree =3D &newmt; - mas_reset(&newmas); - mas_reset(&mas); - mas.index =3D 0; - mas.last =3D 0; - rcu_read_lock(); - down_write(&newmt_lock); - if (mas_expected_entries(&newmas, nr_entries)) { - printk("OOM!"); + mt_init_flags(&newmt, + MT_FLAGS_ALLOC_RANGE | MT_FLAGS_LOCK_EXTERN); + mt_set_external_lock(&newmt, &newmt_lock); + + down_write_nested(&newmt_lock, SINGLE_DEPTH_NESTING); + ret =3D __mt_dup(&mt, &newmt, GFP_KERNEL); + if (ret) { + pr_err("OOM!"); BUG_ON(1); } - mas_for_each(&mas, val, ULONG_MAX) { - newmas.index =3D mas.index; - newmas.last =3D mas.last; + + mas_set(&newmas, 0); + mas_for_each(&newmas, val, ULONG_MAX) mas_store(&newmas, val); - } + mas_destroy(&newmas); - rcu_read_unlock(); mt_validate(&newmt); - mt_set_non_kernel(0); __mt_destroy(&newmt); up_write(&newmt_lock); } + mas_destroy(&mas); + __mt_destroy(&mt); + up_write(&mt_lock); } #endif =20 @@ -3615,9 +3618,7 @@ static int __init maple_tree_seed(void) #endif #if defined(BENCH_FORK) #define BENCH - mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); - bench_forking(&tree); - mtree_destroy(&tree); + bench_forking(); goto skip; #endif #if defined(BENCH_MT_FOR_EACH) @@ -3650,9 +3651,7 @@ static int __init maple_tree_seed(void) check_iteration(&tree); mtree_destroy(&tree); =20 - mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); - check_forking(&tree); - mtree_destroy(&tree); + check_forking(); =20 mt_init_flags(&tree, MT_FLAGS_ALLOC_RANGE); check_mas_store_gfp(&tree); diff --git a/tools/include/linux/rwsem.h b/tools/include/linux/rwsem.h index 83971b3cbfce..f8bffd4a987c 100644 --- a/tools/include/linux/rwsem.h +++ b/tools/include/linux/rwsem.h @@ -37,4 +37,8 @@ static inline int up_write(struct rw_semaphore *sem) { return pthread_rwlock_unlock(&sem->lock); } + +#define down_read_nested(sem, subclass) down_read(sem) +#define down_write_nested(sem, subclass) down_write(sem) + #endif /* _TOOLS_RWSEM_H */ --=20 2.20.1 From nobody Fri Jan 2 04:05:48 2026 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 92507CDB465 for ; Mon, 16 Oct 2023 03:24:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231700AbjJPDYK (ORCPT ); Sun, 15 Oct 2023 23:24:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231722AbjJPDXx (ORCPT ); Sun, 15 Oct 2023 23:23:53 -0400 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C65AD19D for ; Sun, 15 Oct 2023 20:23:42 -0700 (PDT) Received: by mail-pj1-x102b.google.com with SMTP id 98e67ed59e1d1-27cfb8bc7eeso3269886a91.0 for ; Sun, 15 Oct 2023 20:23:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426621; x=1698031421; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AVtomugZIRVe5XO/IomDBee5ri378ZRM5/INN5nVYsk=; b=ldXmvkonFc0oiRTa3tuI17TeE/i5DRDVkQ099+h4xoCEQKH/OUMGK9IGih3zfhX1ts BkJAi9wcx46uomc/yOdmAclf6OE/lQ9eVqYIM4+Cb73UjmVkx9DcDY10Qv4yn+z3lGDd cao9Ouzf10x0ug40yO9UYynQ/kv7Sy9MGBtnFalBE+TObIGDy1mEot2XEBlHwv3yBrZa oAqgKELyfPoKnsXiiq67dn7FywAJzYZTVellFmvhkxs9N0hxvOJm2V7JPNoos88uh3Hz vK0DiTCnpbo3WS1zAhUqcoeMggBhBboRZbwu0yNp/PKfC/EA7Xeg7HVOagM+rm9IDqcL DtAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426621; x=1698031421; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AVtomugZIRVe5XO/IomDBee5ri378ZRM5/INN5nVYsk=; b=L2OQMJmZv/KlN+YUoem6hgLzKH9rf/or+jwxAYe9pVn9+e5z8CNTSkwL+++8Ir8XNf WD8+qsRnHPdFOgm42wAqjSUhOy8TRZXN4pGVx9ESflPKxfiHXr7UVHJcKuaDg2yVhTXI eHaeFmFvsUxer8aQYOeafgdNNlgANA9EJgF5c/mLd9LKmVvL1KRnvzEH2Mi2lzucVFlh 9Dmf5yNGUl8z2riWxfMlfpEBul1OaZssGEYGhUoHfkliNaXqhLVF5QDKEjtKLwvsZhZ7 i/51tiD7mp/Ge/DS/dC86EKXLJDBjjc5TwZh9QCU2NzYFQ5E0o7aYXYsNn8qZH2wgJBt 3clw== X-Gm-Message-State: AOJu0YyzKssVJzMK/l1oQZOXXpkH/GQksVSkNFWzfqcB7nwzBDoPD15D zadpBoj/kLMh6g1HANZZBGZjcw== X-Google-Smtp-Source: AGHT+IHSb0DNGBGR2h/8IDjSmu+jqGvudTUl4FEPI1UTDCPUIrsebdcLp2Rpr+bgZ6cxOHBljaILuA== X-Received: by 2002:a17:90a:d48b:b0:27c:f2e5:a82 with SMTP id s11-20020a17090ad48b00b0027cf2e50a82mr15318761pju.15.1697426621551; Sun, 15 Oct 2023 20:23:41 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.23.35 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:23:41 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 09/10] maple_tree: Preserve the tree attributes when destroying maple tree Date: Mon, 16 Oct 2023 11:22:25 +0800 Message-Id: <20231016032226.59199-10-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" When destroying maple tree, preserve its attributes and then turn it into an empty tree. This allows it to be reused without needing to be reinitialized. Signed-off-by: Peng Zhang --- lib/maple_tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/maple_tree.c b/lib/maple_tree.c index 6e0ad83f14e3..9b5e5580b252 100644 --- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -6779,7 +6779,7 @@ void __mt_destroy(struct maple_tree *mt) if (xa_is_node(root)) mte_destroy_walk(root, mt); =20 - mt->ma_flags =3D 0; + mt->ma_flags =3D mt_attr(mt); } EXPORT_SYMBOL_GPL(__mt_destroy); =20 --=20 2.20.1 From nobody Fri Jan 2 04:05:48 2026 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 811E6CDB474 for ; Mon, 16 Oct 2023 03:25:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231496AbjJPDZ5 (ORCPT ); Sun, 15 Oct 2023 23:25:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60168 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231857AbjJPDYW (ORCPT ); Sun, 15 Oct 2023 23:24:22 -0400 Received: from mail-pg1-x531.google.com (mail-pg1-x531.google.com [IPv6:2607:f8b0:4864:20::531]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AB3EE10F for ; Sun, 15 Oct 2023 20:23:48 -0700 (PDT) Received: by mail-pg1-x531.google.com with SMTP id 41be03b00d2f7-5ac865d1358so1336140a12.3 for ; Sun, 15 Oct 2023 20:23:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance.com; s=google; t=1697426628; x=1698031428; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YVqlJjWp+julEUMAnNu/poDkRQ8jCvWS/3JoCR4jyXk=; b=cUgW3XraZYGBgyqXdzWIPoxkGLejaMRa1Q20rGo2WsyOgHl1VzQnbKBTXm2pVqf/gS 8K9u8++UEFMAUazABmgS/CvYLJRCtBfKBavWhkoZ+RXpQB+H4lvUAlMvshX6LD42Wza1 96aCc3xgAwv48m52SVlD8Wg4jGsY40Y2Rj9JiNP1RW4Gj0tlGQTFuJI2TlwkggFKFxeI RMZg+O7i2KecKQmtF+jtZ1HhR+Z8+6MqgkZDPCv2yukqBzzN2Wl0S71YHv3vIb0m5+d5 IfuTj+jqPGce9PlpblrnITryx+fAhNv7Bus2LPGFIprCl5F+yG4B6o7uV3G5lrNDyhea XlPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1697426628; x=1698031428; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YVqlJjWp+julEUMAnNu/poDkRQ8jCvWS/3JoCR4jyXk=; b=sbdrvPhMBT/gcjF9j9eP5Hcp9AaSvc3UPD4pA/QH5XOD+nFgMjwy0q/Rjsy9bNilaJ vWCKFwtsApxmDUcmWhUmNFlSr22v5PTgXgsxSOUAfreby8xFECOtbd3HI9KaOe1JybWc 9NMzsUDwjU0ym7YWomaZJp71fiP1oqtt+J069rTR9sYb2+xQJd5IFDOJmUyjRcp49Eyz BMkhihxjQArG74bGQQQ/PBxwWOE24MuTzP/QOVIls64xLRILQea3/0Or9by7ty/tsqH4 ZdwBWdSq+s2rN9YTkJv3ZG9/yOjG3uxiJVqMmEKQjj6qTULvI+i7mGDMY60l9tcPvZcZ JpdQ== X-Gm-Message-State: AOJu0YwjLF5h3a2Yv0TR0v9cmnama0u78tPHMW+4Ls2fDU1itJS42rn7 BieFm4l92PDeodIEQnLFULG9Ow== X-Google-Smtp-Source: AGHT+IEbtACnFwjalGKrQUsNTxnw+Q9lJ3N5Y1iJnUQdx2iVRQ7BWuSFP1gHP8DWufFa6yDaaFK+cw== X-Received: by 2002:a17:90a:7782:b0:27d:5cca:9b69 with SMTP id v2-20020a17090a778200b0027d5cca9b69mr2361681pjk.45.1697426628084; Sun, 15 Oct 2023 20:23:48 -0700 (PDT) Received: from GL4FX4PXWL.bytedance.net ([139.177.225.232]) by smtp.gmail.com with ESMTPSA id d8-20020a17090ae28800b0027758c7f585sm3452770pjz.52.2023.10.15.20.23.41 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Sun, 15 Oct 2023 20:23:47 -0700 (PDT) From: Peng Zhang To: Liam.Howlett@oracle.com, corbet@lwn.net, akpm@linux-foundation.org, willy@infradead.org, brauner@kernel.org, surenb@google.com, michael.christie@oracle.com, mjguzik@gmail.com, mathieu.desnoyers@efficios.com, npiggin@gmail.com, peterz@infradead.org, oliver.sang@intel.com, mst@redhat.com Cc: zhangpeng.00@bytedance.com, maple-tree@lists.infradead.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v5 10/10] fork: Use __mt_dup() to duplicate maple tree in dup_mmap() Date: Mon, 16 Oct 2023 11:22:26 +0800 Message-Id: <20231016032226.59199-11-zhangpeng.00@bytedance.com> X-Mailer: git-send-email 2.39.3 (Apple Git-145) In-Reply-To: <20231016032226.59199-1-zhangpeng.00@bytedance.com> References: <20231016032226.59199-1-zhangpeng.00@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In dup_mmap(), using __mt_dup() to duplicate the old maple tree and then directly replacing the entries of VMAs in the new maple tree can result in better performance. __mt_dup() uses DFS pre-order to duplicate the maple tree, so it is efficient. The average time complexity of __mt_dup() is O(n), where n is the number of VMAs. The proof of the time complexity is provided in the commit log that introduces __mt_dup(). After duplicating the maple tree, each element is traversed and replaced (ignoring the cases of deletion, which are rare). Since it is only a replacement operation for each element, this process is also O(n). Analyzing the exact time complexity of the previous algorithm is challenging because each insertion can involve appending to a node, pushing data to adjacent nodes, or even splitting nodes. The frequency of each action is difficult to calculate. The worst-case scenario for a single insertion is when the tree undergoes splitting at every level. If we consider each insertion as the worst-case scenario, we can determine that the upper bound of the time complexity is O(n*log(n)), although this is a loose upper bound. However, based on the test data, it appears that the actual time complexity is likely to be O(n). As the entire maple tree is duplicated using __mt_dup(), if dup_mmap() fails, there will be a portion of VMAs that have not been duplicated in the maple tree. To handle this, we mark the failure point with XA_ZERO_ENTRY. In exit_mmap(), if this marker is encountered, stop releasing VMAs that have not been duplicated after this point. There is a "spawn" in byte-unixbench[1], which can be used to test the performance of fork(). I modified it slightly to make it work with different number of VMAs. Below are the test results. The first row shows the number of VMAs. The second and third rows show the number of fork() calls per ten seconds, corresponding to next-20231006 and the this patchset, respectively. The test results were obtained with CPU binding to avoid scheduler load balancing that could cause unstable results. There are still some fluctuations in the test results, but at least they are better than the original performance. 21 121 221 421 821 1621 3221 6421 12821 25621 51221 112100 76261 54227 34035 20195 11112 6017 3161 1606 802 393 114558 83067 65008 45824 28751 16072 8922 4747 2436 1233 599 2.19% 8.92% 19.88% 34.64% 42.37% 44.64% 48.28% 50.17% 51.68% 53.74% 52.42% [1] https://github.com/kdlucas/byte-unixbench/tree/master Signed-off-by: Peng Zhang --- kernel/fork.c | 39 ++++++++++++++++++++++++++++----------- mm/memory.c | 7 ++++++- mm/mmap.c | 9 ++++++--- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/kernel/fork.c b/kernel/fork.c index 0ff2e0cd4109..0be15501e52e 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -650,7 +650,6 @@ static __latent_entropy int dup_mmap(struct mm_struct *= mm, int retval; unsigned long charge =3D 0; LIST_HEAD(uf); - VMA_ITERATOR(old_vmi, oldmm, 0); VMA_ITERATOR(vmi, mm, 0); =20 uprobe_start_dup_mmap(); @@ -678,16 +677,21 @@ static __latent_entropy int dup_mmap(struct mm_struct= *mm, goto out; khugepaged_fork(mm, oldmm); =20 - retval =3D vma_iter_bulk_alloc(&vmi, oldmm->map_count); - if (retval) + /* Use __mt_dup() to efficiently build an identical maple tree. */ + retval =3D __mt_dup(&oldmm->mm_mt, &mm->mm_mt, GFP_KERNEL); + if (unlikely(retval)) goto out; =20 mt_clear_in_rcu(vmi.mas.tree); - for_each_vma(old_vmi, mpnt) { + for_each_vma(vmi, mpnt) { struct file *file; =20 vma_start_write(mpnt); if (mpnt->vm_flags & VM_DONTCOPY) { + retval =3D mas_store_gfp(&vmi.mas, NULL, GFP_KERNEL); + if (retval) + goto loop_out; + vm_stat_account(mm, mpnt->vm_flags, -vma_pages(mpnt)); continue; } @@ -749,9 +753,11 @@ static __latent_entropy int dup_mmap(struct mm_struct = *mm, if (is_vm_hugetlb_page(tmp)) hugetlb_dup_vma_private(tmp); =20 - /* Link the vma into the MT */ - if (vma_iter_bulk_store(&vmi, tmp)) - goto fail_nomem_vmi_store; + /* + * Link the vma into the MT. After using __mt_dup(), memory + * allocation is not necessary here, so it cannot fail. + */ + mas_store(&vmi.mas, tmp); =20 mm->map_count++; if (!(tmp->vm_flags & VM_WIPEONFORK)) @@ -760,15 +766,28 @@ static __latent_entropy int dup_mmap(struct mm_struct= *mm, if (tmp->vm_ops && tmp->vm_ops->open) tmp->vm_ops->open(tmp); =20 - if (retval) + if (retval) { + mpnt =3D vma_next(&vmi); goto loop_out; + } } /* a new mm has just been created */ retval =3D arch_dup_mmap(oldmm, mm); loop_out: vma_iter_free(&vmi); - if (!retval) + if (!retval) { mt_set_in_rcu(vmi.mas.tree); + } else if (mpnt) { + /* + * The entire maple tree has already been duplicated. If the + * mmap duplication fails, mark the failure point with + * XA_ZERO_ENTRY. In exit_mmap(), if this marker is encountered, + * stop releasing VMAs that have not been duplicated after this + * point. + */ + mas_set_range(&vmi.mas, mpnt->vm_start, mpnt->vm_end - 1); + mas_store(&vmi.mas, XA_ZERO_ENTRY); + } out: mmap_write_unlock(mm); flush_tlb_mm(oldmm); @@ -778,8 +797,6 @@ static __latent_entropy int dup_mmap(struct mm_struct *= mm, uprobe_end_dup_mmap(); return retval; =20 -fail_nomem_vmi_store: - unlink_anon_vmas(tmp); fail_nomem_anon_vma_fork: mpol_put(vma_policy(tmp)); fail_nomem_policy: diff --git a/mm/memory.c b/mm/memory.c index b320af6466cc..ea48bd4b1feb 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -374,6 +374,8 @@ void free_pgtables(struct mmu_gather *tlb, struct ma_st= ate *mas, * be 0. This will underflow and is okay. */ next =3D mas_find(mas, ceiling - 1); + if (unlikely(xa_is_zero(next))) + next =3D NULL; =20 /* * Hide vma from rmap and truncate_pagecache before freeing @@ -395,6 +397,8 @@ void free_pgtables(struct mmu_gather *tlb, struct ma_st= ate *mas, && !is_vm_hugetlb_page(next)) { vma =3D next; next =3D mas_find(mas, ceiling - 1); + if (unlikely(xa_is_zero(next))) + next =3D NULL; if (mm_wr_locked) vma_start_write(vma); unlink_anon_vmas(vma); @@ -1743,7 +1747,8 @@ void unmap_vmas(struct mmu_gather *tlb, struct ma_sta= te *mas, unmap_single_vma(tlb, vma, start, end, &details, mm_wr_locked); hugetlb_zap_end(vma, &details); - } while ((vma =3D mas_find(mas, tree_end - 1)) !=3D NULL); + vma =3D mas_find(mas, tree_end - 1); + } while (vma && likely(!xa_is_zero(vma))); mmu_notifier_invalidate_range_end(&range); } =20 diff --git a/mm/mmap.c b/mm/mmap.c index 1855a2d84200..12ce17863e62 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -3213,10 +3213,11 @@ void exit_mmap(struct mm_struct *mm) arch_exit_mmap(mm); =20 vma =3D mas_find(&mas, ULONG_MAX); - if (!vma) { + if (!vma || unlikely(xa_is_zero(vma))) { /* Can happen if dup_mmap() received an OOM */ mmap_read_unlock(mm); - return; + mmap_write_lock(mm); + goto destroy; } =20 lru_add_drain(); @@ -3251,11 +3252,13 @@ void exit_mmap(struct mm_struct *mm) remove_vma(vma, true); count++; cond_resched(); - } while ((vma =3D mas_find(&mas, ULONG_MAX)) !=3D NULL); + vma =3D mas_find(&mas, ULONG_MAX); + } while (vma && likely(!xa_is_zero(vma))); =20 BUG_ON(count !=3D mm->map_count); =20 trace_exit_mmap(mm); +destroy: __mt_destroy(&mm->mm_mt); mmap_write_unlock(mm); vm_unacct_memory(nr_accounted); --=20 2.20.1