All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 2/7] histogram: add helper function to expose histograms to userspace
@ 2020-05-28 23:52 Axel Rasmussen
  0 siblings, 0 replies; only message in thread
From: Axel Rasmussen @ 2020-05-28 23:52 UTC (permalink / raw)
  To: Andrew Morton, David Rientjes, Davidlohr Bueso, Ingo Molnar,
	Ingo Molnar, Jerome Glisse, Laurent Dufour, Liam R . Howlett,
	Matthew Wilcox, Michel Lespinasse, Peter Zijlstra,
	Vlastimil Babka, Will Deacon
  Cc: linux-fsdevel, linux-kernel, linux-mm, AKASHI Takahiro,
	Aleksa Sarai, Alexander Potapenko, Alexey Dobriyan, Al Viro,
	Andrei Vagin, Ard Biesheuvel, Brendan Higgins, chenqiwu,
	Christian Brauner, Christian Kellner, Corentin Labbe,
	Daniel Jordan, Dan Williams, David Gow, David S. Miller,
	Dmitry V. Levin, Eric W. Biederman, Eugene Syromiatnikov,
	Jamie Liu, Jason Gunthorpe, John Garry, John Hubbard,
	Jonathan Adams, Junaid Shahid, Kees Cook, Kirill A. Shutemov,
	Konstantin Khlebnikov, Krzysztof Kozlowski, Mark Rutland,
	Masahiro Yamada, Masami Hiramatsu, Mathieu Desnoyers,
	Michal Hocko, Mikhail Zaslonko, Petr Mladek, Ralph Campbell,
	Randy Dunlap, Roman Gushchin, Shakeel Butt, Steven Rostedt,
	Tal Gilboa, Thomas Gleixner, Uwe Kleine-König,
	Vincenzo Frascino, Yang Shi, Yu Zhao, Axel Rasmussen

This change introduces the histogram_print_buckets_rcu(). This API is
used for implementing e.g. procfs or sysfs files exposing histograms.
print_buckets can be combined with e.g. seq_file to provide a read
interface for such a file.

This is a squashed, refactored, and modified version of a
previously-internal implementation. Thanks to the following individuals
for portions of the implementation:

  Junaid Shahid <junaids@google.com> - Original implementation
  Yu Zhao <yuzhao@google.com> - Simplification

Signed-off-by: Axel Rasmussen <axelrasmussen@google.com>
---
 include/linux/histogram.h | 23 ++++++++++++++++
 lib/histogram.c           | 55 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 78 insertions(+)

diff --git a/include/linux/histogram.h b/include/linux/histogram.h
index 137930ca933f..7a1dc33fff5e 100644
--- a/include/linux/histogram.h
+++ b/include/linux/histogram.h
@@ -65,6 +65,12 @@
  * histogram_destroy_rcu(&hrcu);
  */
 
+/*
+ * Max number of digits in decimal needed to represent U64_MAX threshold,
+ * plus one space.
+ */
+#define HISTO_MAX_CHARS_PER_THRESHOLD (20 + 1)
+
 struct histogram {
 	struct rcu_head rcu;
 	u64 __percpu *buckets;
@@ -189,6 +195,23 @@ static inline void histogram_record_rcu(struct histogram_rcu *hrcu, u64 val,
 ssize_t histogram_read_rcu(const struct histogram_rcu *hrcu, u64 *buckets,
 			   u64 *thresholds, size_t nr_thresholds);
 
+/**
+ * histogram_print_buckets_rcu() - helper function to print histogram buckets
+ * @hrcu: histogram
+ * @buffer: output buffer to fill
+ * @len: length of the output buffer
+ *
+ * Reads buckets by calling histogram_read_rcu(), then fills the output buffer.
+ *
+ * Context: Performs allocation with GFP_ATOMIC.
+ *
+ * Returns: The number of characters written to @buffer, or a negative error
+ * code on failure. If the buffer isn't large enough to contain the output,
+ * -EINVAL is returned.
+ */
+int histogram_print_buckets_rcu(struct histogram_rcu *hrcu, char *buffer,
+				int len);
+
 /**
  * histogram_set_thresholds_rcu() - set RCU-protected histogram thresholds
  * @hrcu: histogram
diff --git a/lib/histogram.c b/lib/histogram.c
index b68334275a46..1a23590fc6e9 100644
--- a/lib/histogram.c
+++ b/lib/histogram.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <linux/cache.h>
+#include <linux/ctype.h>
 #include <linux/cpumask.h>
 #include <linux/err.h>
 #include <linux/export.h>
@@ -133,6 +134,60 @@ ssize_t histogram_read_rcu(const struct histogram_rcu *hrcu, u64 *buckets,
 }
 EXPORT_SYMBOL_GPL(histogram_read_rcu);
 
+int histogram_print_buckets_rcu(struct histogram_rcu *hrcu, char *buffer,
+				int len)
+{
+	const struct histogram *hist;
+	u64 *buckets = NULL;
+	u64 lower = 0;
+	size_t nr_buckets;
+	size_t i;
+	int ret;
+	int remaining = len;
+
+	rcu_read_lock_sched();
+	hist = rcu_dereference_sched(hrcu->hist);
+
+	nr_buckets = hist->nr_thresholds;
+	if (!nr_buckets) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	buckets = kmalloc_array(nr_buckets, sizeof(*hist->buckets), GFP_ATOMIC);
+	if (!buckets) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	histogram_read_buckets(hist, buckets);
+
+	for (i = 0; i < nr_buckets; i++) {
+		if (i == nr_buckets - 1)
+			ret = snprintf(buffer, remaining, "%llu-inf %llu\n",
+				       lower, buckets[i]);
+		else
+			ret = snprintf(buffer, remaining, "%llu-%llu %llu\n",
+				       lower, hist->thresholds[i], buckets[i]);
+		if (ret >= remaining) {
+			ret = -EINVAL;
+			goto out;
+		}
+
+		buffer += ret;
+		remaining -= ret;
+
+		lower = hist->thresholds[i] + 1;
+	}
+
+	ret = len - remaining;
+out:
+	rcu_read_unlock_sched();
+	kfree(buckets);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(histogram_print_buckets_rcu);
+
 int histogram_set_thresholds_rcu(struct histogram_rcu *hrcu,
 				 const u64 *thresholds, size_t nr_thresholds)
 {
-- 
2.27.0.rc0.183.gde8f92d652-goog



^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2020-05-28 23:52 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-28 23:52 [PATCH v2 2/7] histogram: add helper function to expose histograms to userspace Axel Rasmussen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.