From nobody Fri Jun 12 07:28:19 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CF807212542 for ; Wed, 8 Apr 2026 15:47:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775663255; cv=none; b=EeVuFY6H398KheqL+9ygbLRiNMfTIn18eC3dWQR2Me1mAHI9XrVGjHPZZESRJe+96xCC0cV1iD5z4+3pJOyLKcoOLI/Ss6G1o5rrkSF7xyFjrUlAO5LP2CHiceqiOdQNFQyKHSrE6/M9BhGLABSTusqec9bH0xhv2okkS2ux8I0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775663255; c=relaxed/simple; bh=/sCYxACzHeKOBBtKbTf0JYBh6CfVPvs9YQezkVa8oQE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=b71zcMd0/uDLQKJqsH3QExU9ooeIcnancAkFRAVD+5uzi6Rfpr0VlJjK7OTO3UnlAlU4J96EoBO+sXKTGsws1te/d9gcVfgARn0o8P2BbbTB2QJOafCFW6FpTXpihKo/UcqidAl8wfkOO9AWOL13uxV/r4q1t9AoqiYU20AiUEI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=debian.org; spf=none smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=UEQzZNC+; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="UEQzZNC+" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=g56auhKAY5j+dvmNG9CeuB28V6/CJ5EqcS41m0jUuFE=; b=UEQzZNC+f7LrCH9J/cy5DtjfSM 8092LqJ1MyKxSiue0T+1tZmMWlQvTOMbzlv8K+x3pPnNYOAlPUmDlFwoHDL1ccPsmyOp2NGrAQUZH u2sGsbmLYxH8ahlhkUeVF207qcX3fWNLbKWKeO0DUbXJhVH54IID0/NIx2CB0XTvJOIbU13CA+0Fx d2u98SjvgckTKKqW151JTDvlZ8R2urpx+DkEzhH77iNfO9rguHMWT1jbrWYf6aaJRlTI3gJro9Ns3 gg8KuwAVWLdcVsvou1Ahm7sRYgeL+iVDeogo/DdArgk8+GGdYpkv8nfG8N7+9tcG6pDkK/fth7gf0 WtxhX12A==; Received: from authenticated user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wAV7q-008Wdy-22; Wed, 08 Apr 2026 15:47:30 +0000 From: Breno Leitao Date: Wed, 08 Apr 2026 08:47:00 -0700 Subject: [PATCH v2 1/2] mm: huge_memory: use sysfs_match_string() in defrag_store() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260408-thp_defrag-v2-1-bc544c1bde4e@debian.org> References: <20260408-thp_defrag-v2-0-bc544c1bde4e@debian.org> In-Reply-To: <20260408-thp_defrag-v2-0-bc544c1bde4e@debian.org> To: Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Barry Song , Lance Yang Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.16-dev-453a6 X-Developer-Signature: v=1; a=openpgp-sha256; l=4937; i=leitao@debian.org; h=from:subject:message-id; bh=/sCYxACzHeKOBBtKbTf0JYBh6CfVPvs9YQezkVa8oQE=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBp1niIWX4L/u4+a9VuF0VbZDMLGe4Jc6QrcS85Z NJRBgw8Y7KJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCadZ4iAAKCRA1o5Of/Hh3 bWyBD/9t7F391FzPemA6wI+p/T1F7yuIR/Frzv64pDqioDHGIAkFzQBcdEMOty8LAlNgOpioAHT AO4kjK+OBn2+jGezyf68sukbQuxCOioVuade3ueVws2wNn5JCz8itLc6p7AIEUaRduPpCLZSWnS dvMIYUqL1sZXUKNOZTckmRuRgMNSa01drx1bV6Xj3zf8l+f63jJnp8GMhLch1jSf1TBzDdLlmPy edbNel9XFzhA7b3fg3iwUtyjI7gOV7FaFdgBGkMTVOH+LTx8oUFVbhGnCEy+LVt9AOs0RjjwHpa Xo72K/0BRWtPeoQVmI69drU2tJOz59U7IPF4xtGFjQKHRL/0va5CZReh2oNA1FfEBwkpO9WDdGc aXcEpnDyF3vxygqx+3LuPtk0VQlc5s4Fas88NFW0Aw3LopG8+kqQVNF1RiCqp/HMwUrUM+OC7+4 4rwfiWrPibc9k4zGF0IcRf5YDgO1BEu+xr5TRCQojStEF5EKmM+ZXTN2x56kI6AP4AjAUsbD1gr kd65zFRDxFkzzTmdTx5TsZ9MLhZQJdIIAw/5oIms2K4nk+gnc952rFyYA2fZmzkqqK4kTTQKs0X sQFmfLwbZ7z+lnRfQWobqP+LbxVOOKJK48lSlThZpP2+5Mb+OZx4V52cZCJFD0o/KxhbuNUhUK5 RRQ5MsGsBkAuE5w== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao Replace the if/else chain of sysfs_streq() calls in defrag_store() with sysfs_match_string() and a defrag_mode_strings[] table. Introduce enum defrag_mode and defrag_flags[] array mapping each mode to its corresponding transparent_hugepage_flag. The store function now loops over defrag_flags[], setting the bit for the selected mode and clearing the others. When mode is DEFRAG_NEVER (index 4), no index in the 4-element defrag_flags[] matches, so all flags are cleared. Note that the enum ordering (always, defer, defer+madvise, madvise, never) differs from the original if/else chain order in defrag_store() (always, defer+madvise, defer, madvise, never). This is intentional to match the display order used by defrag_show(). This is a follow-up cleanup to commit 522dfb4ba71f ("mm: huge_memory: refactor anon_enabled_store() with change_anon_orders()") which applied the same sysfs_match_string() pattern to anon_enabled_store(). Acked-by: David Hildenbrand (Arm) Tested-by: Lance Yang Reviewed-by: Lance Yang Reviewed-by: Barry Song Signed-off-by: Breno Leitao Acked-by: Zi Yan Reviewed-by: Lorenzo Stoakes Tested-by: Zi Yan --- mm/huge_memory.c | 60 ++++++++++++++++++++++++++++++++--------------------= ---- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 970e077019b75..76f2d32428c7f 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -429,6 +429,29 @@ ssize_t single_hugepage_flag_store(struct kobject *kob= j, return count; } =20 +enum defrag_mode { + DEFRAG_ALWAYS =3D 0, + DEFRAG_DEFER, + DEFRAG_DEFER_MADVISE, + DEFRAG_MADVISE, + DEFRAG_NEVER, +}; + +static const char * const defrag_mode_strings[] =3D { + [DEFRAG_ALWAYS] =3D "always", + [DEFRAG_DEFER] =3D "defer", + [DEFRAG_DEFER_MADVISE] =3D "defer+madvise", + [DEFRAG_MADVISE] =3D "madvise", + [DEFRAG_NEVER] =3D "never", +}; + +static const enum transparent_hugepage_flag defrag_flags[] =3D { + [DEFRAG_ALWAYS] =3D TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, + [DEFRAG_DEFER] =3D TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, + [DEFRAG_DEFER_MADVISE] =3D TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLA= G, + [DEFRAG_MADVISE] =3D TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, +}; + static ssize_t defrag_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -456,34 +479,19 @@ static ssize_t defrag_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { - if (sysfs_streq(buf, "always")) { - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage= _flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_= hugepage_flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepa= ge_flags); - set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage_f= lags); - } else if (sysfs_streq(buf, "defer+madvise")) { - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage= _flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage= _flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepa= ge_flags); - set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_hu= gepage_flags); - } else if (sysfs_streq(buf, "defer")) { - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage= _flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_= hugepage_flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepa= ge_flags); - set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage_f= lags); - } else if (sysfs_streq(buf, "madvise")) { - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage= _flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage= _flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_= hugepage_flags); - set_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepage= _flags); - } else if (sysfs_streq(buf, "never")) { - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, &transparent_hugepage= _flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, &transparent_hugepage= _flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, &transparent_= hugepage_flags); - clear_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, &transparent_hugepa= ge_flags); - } else + int mode, m; + + mode =3D sysfs_match_string(defrag_mode_strings, buf); + if (mode < 0) return -EINVAL; =20 + for (m =3D 0; m < ARRAY_SIZE(defrag_flags); m++) { + if (m =3D=3D mode) + set_bit(defrag_flags[m], &transparent_hugepage_flags); + else + clear_bit(defrag_flags[m], &transparent_hugepage_flags); + } + return count; } static struct kobj_attribute defrag_attr =3D __ATTR_RW(defrag); --=20 2.52.0 From nobody Fri Jun 12 07:28:19 2026 Received: from stravinsky.debian.org (stravinsky.debian.org [82.195.75.108]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D6D2A2EA749 for ; Wed, 8 Apr 2026 15:47:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=82.195.75.108 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775663258; cv=none; b=ArFl6C6jeQJsJdxq7Ov6rBnllvL+GJsrpb0EFnWVHR0IxEdyHvbbFOc7g7e+EYv7qtjfdMsuvdOwbArTFAZ+QodZLPQzD6zRVRbfvqhGJ3IQ+CnhPh8J2T3ORcmtMeNZXiCwgdAzso7aWPH7iZhdHXeG2srRGwqmizdqHeIwF+Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775663258; c=relaxed/simple; bh=mTQwwZt5uj8cXUAizL9ChIQTeOvHj/NUcNxSipTdwOE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=jvlxmsgQLE/H7KMZbu5PPrBJVHT5cCRB/MDBfsnISozAwmt1vxc31htvMpXfc7ryhUYf9vcPX+d+ShfOmmig5s4IUGh6E2uPuTK4daSxWvAewNvtd9LTkcHglsrGY22v7GiIX6q08CSsR2sseeQVAryjRfERAk9ld00g622S6jg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=debian.org; spf=none smtp.mailfrom=debian.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b=drahk1PU; arc=none smtp.client-ip=82.195.75.108 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=debian.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=debian.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=debian.org header.i=@debian.org header.b="drahk1PU" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debian.org; s=smtpauto.stravinsky; h=X-Debian-User:Cc:To:In-Reply-To:References: Message-Id:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject:Date: From:Reply-To:Content-ID:Content-Description; bh=LT/kDv7NmM6H9XF70WMUnfbRhC7vWN8v8AgsiqkvL94=; b=drahk1PUkWRinoPqEMUu/IGpID sespBLN33xkv3O6Jo4lmIb3svEtdh52lD2jPc7b0qva+SWObuIwmOPSmZNk9IKPMqJ4Sa1pCRWgjX qosQDrkepdDMvgAYye/KH+of2EIVWESUABROUReQFWpLz5K+H/LObbOQeNql6RS2v+Cj6ddAj5TLi zZ/sy4yB1R4M68fFS5SrZRdObpTnLHHCx8Owi9DBY8DPs2cwZd6Rt/dSbOfL7JxE4admIhTp3hKnp Z5MWFZ5Ax0fRtqTbbchR7hrpDsLy7PaSmpzG6X9+CTT2DGLiY0mEfnCV0Y0f2S1TfXLMsd26ezjWE 7vv09mhg==; Received: from authenticated user by stravinsky.debian.org with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.96) (envelope-from ) id 1wAV7v-008We3-02; Wed, 08 Apr 2026 15:47:35 +0000 From: Breno Leitao Date: Wed, 08 Apr 2026 08:47:01 -0700 Subject: [PATCH v2 2/2] mm: huge_memory: refactor defrag_show() to use defrag_flags[] Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260408-thp_defrag-v2-2-bc544c1bde4e@debian.org> References: <20260408-thp_defrag-v2-0-bc544c1bde4e@debian.org> In-Reply-To: <20260408-thp_defrag-v2-0-bc544c1bde4e@debian.org> To: Andrew Morton , David Hildenbrand , Lorenzo Stoakes , Zi Yan , Baolin Wang , "Liam R. Howlett" , Nico Pache , Ryan Roberts , Dev Jain , Barry Song , Lance Yang Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, Breno Leitao , kernel-team@meta.com X-Mailer: b4 0.16-dev-453a6 X-Developer-Signature: v=1; a=openpgp-sha256; l=2413; i=leitao@debian.org; h=from:subject:message-id; bh=mTQwwZt5uj8cXUAizL9ChIQTeOvHj/NUcNxSipTdwOE=; b=owEBbQKS/ZANAwAIATWjk5/8eHdtAcsmYgBp1niIJkVjI5JeQhzpSXj5cT6B2M8rkQkPYw/h8 B1diSfbV5KJAjMEAAEIAB0WIQSshTmm6PRnAspKQ5s1o5Of/Hh3bQUCadZ4iAAKCRA1o5Of/Hh3 bfBVD/9GZrthmy+SIFfHPYogBzJSYvug1zP4vuKbzqQl/Q4yLcfr6lsLsWBVn9EnAcdF8K3hiO6 4qua0ajk1RjssYSxMNSoBvbgT30y1bFciqPEqXOb/zFOHPevTxoBe2NuVOfQVcjMmp8n8I3qJE0 5PuJrHyY7tD2V7wI3nQO0zU5TOzmaFWXrXQJHrh7LqlvUWxvD4TnOdE2v1T9cSArRf0mFBopR23 7m6Cq53UJulAOtNsSH8tjNyEkBR+/z4RrLyY5tZxdxtOHQ0dCF+OTpXU6LwJMGGq1x+Osl9FHrz 9PLz2oOvMvjWWjPcvIP8wH1XHXwFjUZXu7StH5wLgGKAr1fDPYzHMIiasVSm2/Q03wmI0ZksH7/ kOGchHKltrb3rEZn4jB/FNYn5QrKaNL+aQn8cqRCt3mgYXOZaD3JGz9zedTjmdrl6USkgFZmTXr WPsgssF1UKp9Lx1tYEyNgI+omLMkCa95GFJWjsjwZNQcmypJYf03dUEr6rfjc6/l8JL+CJx95Dj O2ChzMieK5qo/w8Oic1TuoSt26rauwBhlXFx6KHqTlRpYEOK0h8StUzazfMYUR7USEnHpl7Yf93 SBvEusTF9/tbH3aUbdpJZ8JEnfFFq80OUX8ZBaFnyn2ARNGlMRbmB1kICX+UGqu4D5KGaQlpQye tOuSyoN97RpVNgw== X-Developer-Key: i=leitao@debian.org; a=openpgp; fpr=AC8539A6E8F46702CA4A439B35A3939FFC78776D X-Debian-User: leitao Replace the hardcoded if/else chain of test_bit() calls and string literals in defrag_show() with a loop over defrag_flags[] and defrag_mode_strings[] arrays introduced in the previous commit. This makes defrag_show() consistent with defrag_store() and eliminates the duplicated mode name strings. Acked-by: David Hildenbrand (Arm) Tested-by: Lance Yang Reviewed-by: Lance Yang Reviewed-by: Barry Song Signed-off-by: Breno Leitao Acked-by: Zi Yan Reviewed-by: Lorenzo Stoakes Tested-by: Zi Yan --- mm/huge_memory.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 76f2d32428c7f..6993c6d8709dc 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -455,24 +455,30 @@ static const enum transparent_hugepage_flag defrag_fl= ags[] =3D { static ssize_t defrag_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { - const char *output; + int active =3D DEFRAG_NEVER; + int len =3D 0; + int i; =20 - if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_DIRECT_FLAG, - &transparent_hugepage_flags)) - output =3D "[always] defer defer+madvise madvise never"; - else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_FLAG, - &transparent_hugepage_flags)) - output =3D "always [defer] defer+madvise madvise never"; - else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_KSWAPD_OR_MADV_FLAG, - &transparent_hugepage_flags)) - output =3D "always defer [defer+madvise] madvise never"; - else if (test_bit(TRANSPARENT_HUGEPAGE_DEFRAG_REQ_MADV_FLAG, - &transparent_hugepage_flags)) - output =3D "always defer defer+madvise [madvise] never"; - else - output =3D "always defer defer+madvise madvise [never]"; + for (i =3D 0; i < ARRAY_SIZE(defrag_flags); i++) { + if (test_bit(defrag_flags[i], &transparent_hugepage_flags)) { + active =3D i; + break; + } + } =20 - return sysfs_emit(buf, "%s\n", output); + for (i =3D 0; i < ARRAY_SIZE(defrag_mode_strings); i++) { + if (i =3D=3D active) + len +=3D sysfs_emit_at(buf, len, "[%s] ", + defrag_mode_strings[i]); + else + len +=3D sysfs_emit_at(buf, len, "%s ", + defrag_mode_strings[i]); + } + + /* Replace trailing space with newline */ + buf[len - 1] =3D '\n'; + + return len; } =20 static ssize_t defrag_store(struct kobject *kobj, --=20 2.52.0