From: Alexander Potapenko <glider@google.com>
To: glider@google.com, catalin.marinas@arm.com, will@kernel.org,
pcc@google.com, andreyknvl@gmail.com,
andriy.shevchenko@linux.intel.com, aleksander.lobakin@intel.com,
linux@rasmusvillemoes.dk, yury.norov@gmail.com,
alexandru.elisei@arm.com
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, eugenis@google.com,
syednwaris@gmail.com, william.gray@linaro.org
Subject: [PATCH v9 4/4] arm64: mte: implement CONFIG_ARM64_MTE_SWAP_STATS
Date: Mon, 13 Nov 2023 11:52:33 +0100 [thread overview]
Message-ID: <20231113105234.32058-5-glider@google.com> (raw)
In-Reply-To: <20231113105234.32058-1-glider@google.com>
Provide a config to collect the usage statistics for ARM MTE tag
compression. This patch introduces allocation/deallocation counters
for buffers that were stored uncompressed (and thus occupy 128 bytes of
heap plus the Xarray overhead to store a pointer) and those that were
compressed into 8-byte pointers (effectively using 0 bytes of heap in
addition to the Xarray overhead).
The counters are exposed to the userspace via
/sys/kernel/debug/mteswap/stats:
# cat /sys/kernel/debug/mteswap/stats
8 bytes: 102496 allocations, 67302 deallocations
128 bytes: 212234 allocations, 178278 deallocations
uncompressed tag storage size: 8851200
compressed tag storage size: 4346368
Suggested-by: Yury Norov <yury.norov@gmail.com>
Signed-off-by: Alexander Potapenko <glider@google.com>
---
This patch was split off from the "arm64: mte: add compression support
to mteswap.c" patch
(https://lore.kernel.org/linux-arm-kernel/ZUVulBKVYK7cq2rJ@yury-ThinkPad/T/#m819ec30beb9de53d5c442f7e3247456f8966d88a)
v9:
- add this patch, put the stats behind a separate config,
mention /sys/kernel/debug/mteswap/stats in the documentation
---
.../arch/arm64/mte-tag-compression.rst | 12 +++
arch/arm64/Kconfig | 15 +++
arch/arm64/mm/mteswap.c | 93 ++++++++++++++++++-
3 files changed, 118 insertions(+), 2 deletions(-)
diff --git a/Documentation/arch/arm64/mte-tag-compression.rst b/Documentation/arch/arm64/mte-tag-compression.rst
index 8fe6b51a9db6d..4c25b96f7d4b5 100644
--- a/Documentation/arch/arm64/mte-tag-compression.rst
+++ b/Documentation/arch/arm64/mte-tag-compression.rst
@@ -145,6 +145,18 @@ Tag compression and decompression implicitly rely on the fixed MTE tag size
(4 bits) and number of tags per page. Should these values change, the algorithm
may need to be revised.
+Stats
+=====
+
+When `CONFIG_ARM64_MTE_SWAP_STATS` is enabled, `arch/arm64/mm/mteswap.c` exports
+usage statistics for tag compression used when swapping tagged pages. The data
+can be accessed via debugfs::
+
+ # cat /sys/kernel/debug/mteswap/stats
+ 8 bytes: 10438 allocations, 10417 deallocations
+ 128 bytes: 26180 allocations, 26179 deallocations
+ uncompressed tag storage size: 2816
+ compressed tag storage size: 128
Programming Interface
=====================
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 92104994aaf18..60c969bd4078b 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -2095,6 +2095,21 @@ config ARM64_MTE_COMP_KUNIT_TEST
be compressed into pointer-size values and correctly decompressed
afterwards.
+config ARM64_MTE_SWAP_STATS
+ bool "Collect usage statistics of tag compression for swapped MTE tags"
+ default y
+ depends on ARM64_MTE && ARM64_MTE_COMP
+ help
+ Collect usage statistics for ARM64 MTE tag compression during swapping.
+
+ Adds allocation/deallocation counters for buffers that were stored
+ uncompressed (and thus occupy 128 bytes of heap plus the Xarray
+ overhead to store a pointer) and those that were compressed into
+ 8-byte pointers (effectively using 0 bytes of heap in addition to
+ the Xarray overhead).
+ The counters are exposed to the userspace via
+ /sys/kernel/debug/mteswap/stats.
+
config ARM64_SVE
bool "ARM Scalable Vector Extension support"
default y
diff --git a/arch/arm64/mm/mteswap.c b/arch/arm64/mm/mteswap.c
index 70f5c8ecd640d..1c6c78b9a9037 100644
--- a/arch/arm64/mm/mteswap.c
+++ b/arch/arm64/mm/mteswap.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/debugfs.h>
#include <linux/pagemap.h>
#include <linux/xarray.h>
#include <linux/slab.h>
@@ -11,16 +12,54 @@
static DEFINE_XARRAY(mte_pages);
+enum mteswap_counters {
+ MTESWAP_CTR_INLINE = 0,
+ MTESWAP_CTR_OUTLINE,
+ MTESWAP_CTR_SIZE
+};
+
+#if defined(CONFIG_ARM64_MTE_SWAP_STATS)
+static atomic_long_t alloc_counters[MTESWAP_CTR_SIZE];
+static atomic_long_t dealloc_counters[MTESWAP_CTR_SIZE];
+
+static void inc_alloc_counter(int kind)
+{
+ atomic_long_inc(&alloc_counters[kind]);
+}
+
+static void inc_dealloc_counter(int kind)
+{
+ atomic_long_inc(&dealloc_counters[kind]);
+}
+#else
+static void inc_alloc_counter(int kind)
+{
+}
+
+static void inc_dealloc_counter(int kind)
+{
+}
+#endif
+
void *mte_allocate_tag_storage(void)
{
+ void *ret;
+
/* tags granule is 16 bytes, 2 tags stored per byte */
- return kmalloc(MTE_PAGE_TAG_STORAGE, GFP_KERNEL);
+ ret = kmalloc(MTE_PAGE_TAG_STORAGE, GFP_KERNEL);
+ if (ret)
+ inc_alloc_counter(MTESWAP_CTR_OUTLINE);
+ return ret;
}
void mte_free_tag_storage(char *storage)
{
- if (!mte_is_compressed(storage))
+ if (!mte_is_compressed(storage)) {
kfree(storage);
+ inc_dealloc_counter(MTESWAP_CTR_OUTLINE);
+ } else {
+ inc_dealloc_counter(MTESWAP_CTR_INLINE);
+ }
}
int mte_save_tags(struct page *page)
@@ -39,6 +78,7 @@ int mte_save_tags(struct page *page)
if (compressed_storage) {
mte_free_tag_storage(tag_storage);
tag_storage = compressed_storage;
+ inc_alloc_counter(MTESWAP_CTR_INLINE);
}
/* lookup the swap entry.val from the page */
@@ -98,3 +138,52 @@ void mte_invalidate_tags_area(int type)
}
xa_unlock(&mte_pages);
}
+
+#if defined(CONFIG_ARM64_MTE_SWAP_STATS)
+/* DebugFS interface. */
+static int stats_show(struct seq_file *seq, void *v)
+{
+ unsigned long total_mem_alloc = 0, total_mem_dealloc = 0;
+ unsigned long total_num_alloc = 0, total_num_dealloc = 0;
+ unsigned long sizes[2] = { 8, MTE_PAGE_TAG_STORAGE };
+ long alloc, dealloc;
+ unsigned long size;
+ int i;
+
+ for (i = 0; i < MTESWAP_CTR_SIZE; i++) {
+ alloc = atomic_long_read(&alloc_counters[i]);
+ dealloc = atomic_long_read(&dealloc_counters[i]);
+ total_num_alloc += alloc;
+ total_num_dealloc += dealloc;
+ size = sizes[i];
+ /*
+ * Do not count 8-byte buffers towards compressed tag storage
+ * size.
+ */
+ if (i) {
+ total_mem_alloc += (size * alloc);
+ total_mem_dealloc += (size * dealloc);
+ }
+ seq_printf(seq,
+ "%lu bytes:\t%lu allocations,\t%lu deallocations\n",
+ size, alloc, dealloc);
+ }
+ seq_printf(seq, "uncompressed tag storage size:\t%lu\n",
+ (total_num_alloc - total_num_dealloc) *
+ MTE_PAGE_TAG_STORAGE);
+ seq_printf(seq, "compressed tag storage size:\t%lu\n",
+ total_mem_alloc - total_mem_dealloc);
+ return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(stats);
+
+static int mteswap_init(void)
+{
+ struct dentry *mteswap_dir;
+
+ mteswap_dir = debugfs_create_dir("mteswap", NULL);
+ debugfs_create_file("stats", 0444, mteswap_dir, NULL, &stats_fops);
+ return 0;
+}
+module_init(mteswap_init);
+#endif
--
2.42.0.869.gea05f2083d-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-11-13 10:53 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-13 10:52 [PATCH v9 0/4] Implement MTE tag compression for swapped pages Alexander Potapenko
2023-11-13 10:52 ` [PATCH v9 1/4] arm64: mte: implement CONFIG_ARM64_MTE_COMP Alexander Potapenko
2023-12-12 17:16 ` Catalin Marinas
2023-12-13 12:16 ` Will Deacon
2023-12-14 9:27 ` Alexander Potapenko
2023-11-13 10:52 ` [PATCH v9 2/4] arm64: mte: add a test for MTE tags compression Alexander Potapenko
2023-12-12 17:16 ` Catalin Marinas
2023-11-13 10:52 ` [PATCH v9 3/4] arm64: mte: add compression support to mteswap.c Alexander Potapenko
2023-12-12 17:17 ` Catalin Marinas
2023-11-13 10:52 ` Alexander Potapenko [this message]
2023-12-12 17:18 ` [PATCH v9 4/4] arm64: mte: implement CONFIG_ARM64_MTE_SWAP_STATS Catalin Marinas
2023-12-13 12:31 ` [PATCH v9 0/4] Implement MTE tag compression for swapped pages Will Deacon
2023-12-13 14:01 ` Alexander Potapenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231113105234.32058-5-glider@google.com \
--to=glider@google.com \
--cc=aleksander.lobakin@intel.com \
--cc=alexandru.elisei@arm.com \
--cc=andreyknvl@gmail.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=catalin.marinas@arm.com \
--cc=eugenis@google.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=pcc@google.com \
--cc=syednwaris@gmail.com \
--cc=will@kernel.org \
--cc=william.gray@linaro.org \
--cc=yury.norov@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).