linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
To: "linux-mm@kvack.org" <linux-mm@kvack.org>,
	Alex Markuze <amarkuze@redhat.com>,
	"ceph-devel@vger.kernel.org" <ceph-devel@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Cc: "dietmar.eggemann@arm.com" <dietmar.eggemann@arm.com>,
	"rppt@kernel.org" <rppt@kernel.org>,
	"lorenzo.stoakes@oracle.com" <lorenzo.stoakes@oracle.com>,
	Xiubo Li <xiubli@redhat.com>,
	"idryomov@gmail.com" <idryomov@gmail.com>,
	"david@redhat.com" <david@redhat.com>,
	"mgorman@suse.de" <mgorman@suse.de>,
	"vbabka@suse.cz" <vbabka@suse.cz>,
	"vincent.guittot@linaro.org" <vincent.guittot@linaro.org>,
	"akpm@linux-foundation.org" <akpm@linux-foundation.org>,
	"Liam.Howlett@oracle.com" <Liam.Howlett@oracle.com>,
	Ingo Molnar <mingo@redhat.com>,
	"rostedt@goodmis.org" <rostedt@goodmis.org>,
	"surenb@google.com" <surenb@google.com>,
	Valentin Schneider <vschneid@redhat.com>,
	"kees@kernel.org" <kees@kernel.org>,
	"peterz@infradead.org" <peterz@infradead.org>,
	"mhocko@suse.com" <mhocko@suse.com>,
	"bsegall@google.com" <bsegall@google.com>,
	"juri.lelli@redhat.com" <juri.lelli@redhat.com>
Subject: Re:  [RFC PATCH 4/5] ceph: Add BLOG debugfs support
Date: Mon, 3 Nov 2025 21:07:37 +0000	[thread overview]
Message-ID: <e879c32eab8854773ff32d1e1f06b6a74afabec2.camel@ibm.com> (raw)
In-Reply-To: <20251024084259.2359693-5-amarkuze@redhat.com>

On Fri, 2025-10-24 at 08:42 +0000, Alex Markuze wrote:
> Introduce blog_debugfs.c to export BLOG binary logs through the Ceph debugfs
> hierarchy, enabling userspace tools to read and deserialize per-task logging
> buffers for debugging, tracing, and performance analysis.
> 
> **Key Components:**
> 
> **blog_debugfs.c - Binary log export interface:**
> - blog_entries_show(): Seq file iterator over all active BLOG contexts
> - Lock-safe context enumeration with proper synchronization
> - Per-context buffer snapshot mechanism to prevent data corruption
> - Deserialization and formatted output of binary log entries
> - Integration with Ceph debugfs directory structure
> 
> **Locking strategy (critical correctness fix):**
> The implementation employs a splice-snapshot-splice pattern to avoid
> deadlocks and ensure consistent reads:
> 
> 1. **Context enumeration:** Splice logger->contexts list to temporary list
>    under logger->lock, then drop the lock. This allows new contexts to be
>    created and logging to continue unhindered during potentially slow
>    debugfs reads (e.g., cat of large log files).
> 
> 2. **Buffer snapshot:** For each context, acquire pf->lock, snapshot the
>    buffer (head pointer and capacity), copy data to temporary buffer, then
>    drop pf->lock. This prevents concurrent writers from corrupting the read
>    while minimizing lock hold time.
> 
> 3. **Context restoration:** After iteration completes, splice the temporary
>    list back onto logger->contexts under the lock.
> 
> This design prevents the deadlock scenario where holding logger->lock during
> debugfs read would block all new context allocations, while holding pf->lock
> during deserialization would block all logging on that context.
> 
> **debugfs.c modifications:**
> - Call ceph_blog_debugfs_init() during Ceph debugfs setup when CONFIG_BLOG
>   is enabled, registering BLOG-specific entries alongside existing debug
>   files (e.g., mds_sessions, caps, etc.)
> - Call ceph_blog_debugfs_cleanup() during teardown to remove entries
> 
> **Output format:**
> Each log entry is displayed as a single line with timestamp and deserialized
> message, making it easy to parse and correlate with kernel events. Format
> strings are resolved via the BLOG source ID registry.
> 
> No actual logging is performed yet; dout/doutc macros remain unchanged in
> Ceph code. This commit only establishes the drain path for binary log
> consumption. Subsequent commits will activate BLOG by converting logging
> call sites to bout/boutc.

This code implements dedicated to Ceph debugfs interface. Does it mean that
every other potential kernel modules or subsystems will need to implement the
same own debugfs/tracefs/etc interface? Could we have some unified interface
that all subsystems can use? I assume that it should be pretty the same for any
other than Ceph subsystems?

Thanks,
Slava.

> 
> Signed-off-by: Alex Markuze <amarkuze@redhat.com>
> ---
>  fs/ceph/blog_debugfs.c | 361 +++++++++++++++++++++++++++++++++++++++++
>  fs/ceph/debugfs.c      |  33 +++-
>  2 files changed, 388 insertions(+), 6 deletions(-)
>  create mode 100644 fs/ceph/blog_debugfs.c
> 
> diff --git a/fs/ceph/blog_debugfs.c b/fs/ceph/blog_debugfs.c
> new file mode 100644
> index 000000000000..b34b6829b444
> --- /dev/null
> +++ b/fs/ceph/blog_debugfs.c
> @@ -0,0 +1,361 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Ceph BLOG debugfs interface
> + *
> + * Provides debugfs entries to view and manage BLOG entries for Ceph
> + */
> +
> +#include <linux/module.h>
> +#include <linux/debugfs.h>
> +#include <linux/seq_file.h>
> +#include <linux/slab.h>
> +#include <linux/string.h>
> +#include <linux/jiffies.h>
> +#include <linux/timekeeping.h>
> +#include <linux/ceph/ceph_debug.h>
> +#include <linux/ceph/ceph_blog.h>
> +#include <linux/blog/blog.h>
> +#include <linux/blog/blog_des.h>
> +
> +static struct dentry *ceph_blog_debugfs_dir;
> +
> +static int jiffies_to_formatted_time(u64 jiffies_value, char *buffer,
> +	size_t buffer_len);
> +
> +/**
> + * blog_entries_show - Show all BLOG entries for Ceph
> + *
> + * Iterates through all contexts and their pagefrags, deserializing entries
> + * using BLOG's deserialization with Ceph's client callback
> + */
> +static int blog_entries_show(struct seq_file *s, void *p)
> +{
> +	LIST_HEAD(snapshot);
> +	struct blog_tls_ctx *ctx;
> +	struct blog_log_iter iter;
> +	struct blog_log_entry *entry;
> +	char output_buf[1024];
> +	int ret;
> +	int entry_count = 0;
> +	int ctx_count = 0;
> +
> +	if (!ceph_blog_ctx || !ceph_blog_ctx->logger) {
> +		seq_puts(s, "Ceph BLOG context not initialized\n");
> +		return 0;
> +	}
> +
> +	/* Detach the current context list so producers can continue unhindered */
> +	spin_lock(&ceph_blog_ctx->logger->lock);
> +	list_splice_init(&ceph_blog_ctx->logger->contexts, &snapshot);
> +	spin_unlock(&ceph_blog_ctx->logger->lock);
> +
> +	list_for_each_entry(ctx, &snapshot, list) {
> +		struct blog_pagefrag *pf = blog_ctx_pf(ctx);
> +		u64 head;
> +
> +		ctx_count++;
> +
> +		/* Lock to prevent buffer reset/recycling during iteration */
> +		spin_lock(&pf->lock);
> +		head = pf->head;
> +
> +		if (!head) {
> +			spin_unlock(&pf->lock);
> +			continue;
> +		}
> +
> +		/* Initialize iterator with head snapshot, iterate in-place */
> +		blog_log_iter_init(&iter, pf, head);
> +
> +		while ((entry = blog_log_iter_next(&iter)) != NULL) {
> +			entry_count++;
> +			memset(output_buf, 0, sizeof(output_buf));
> +			ret = blog_des_entry(ceph_blog_ctx->logger, entry, output_buf,
> +				     sizeof(output_buf), ceph_blog_client_des_callback);
> +			if (ret < 0) {
> +				seq_printf(s, "[Error deserializing entry %d: %d]\n",
> +					   entry_count, ret);
> +			} else {
> +				char time_buf[64];
> +				u64 entry_jiffies = ctx->base_jiffies + entry->ts_delta;
> +				if (jiffies_to_formatted_time(entry_jiffies, time_buf,
> +					sizeof(time_buf)) < 0)
> +					strscpy(time_buf, "(invalid)", sizeof(time_buf));
> +				seq_printf(s, "%s %s\n", time_buf, output_buf);
> +			}
> +		}
> +
> +		spin_unlock(&pf->lock);
> +	}
> +
> +	/* Merge snapshot back into main list, preserving any new contexts */
> +	spin_lock(&ceph_blog_ctx->logger->lock);
> +	list_splice_tail_init(&snapshot, &ceph_blog_ctx->logger->contexts);
> +	spin_unlock(&ceph_blog_ctx->logger->lock);
> +
> +	return 0;
> +}
> +
> +static int blog_entries_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, blog_entries_show, inode->i_private);
> +}
> +
> +static const struct file_operations blog_entries_fops = {
> +	.open = blog_entries_open,
> +	.read = seq_read,
> +	.llseek = seq_lseek,
> +	.release = single_release,
> +};
> +
> +/**
> + * blog_stats_show - Show BLOG statistics
> + */
> +static int blog_stats_show(struct seq_file *s, void *p)
> +{
> +	seq_puts(s, "Ceph BLOG Statistics\n");
> +	seq_puts(s, "====================\n\n");
> +
> +	if (!ceph_blog_ctx || !ceph_blog_ctx->logger) {
> +		seq_puts(s, "Ceph BLOG context not initialized\n");
> +		return 0;
> +	}
> +
> +	seq_puts(s, "Ceph Module Logger State:\n");
> +	seq_printf(s, "  Total contexts allocated: %lu\n",
> +		   ceph_blog_ctx->logger->total_contexts_allocated);
> +	seq_printf(s, "  Next context ID: %llu\n", ceph_blog_ctx->logger->next_ctx_id);
> +	seq_printf(s, "  Next source ID: %u\n",
> +		   atomic_read(&ceph_blog_ctx->logger->next_source_id));
> +
> +	seq_puts(s, "\nAllocation Batch:\n");
> +	seq_printf(s, "  Full magazines: %u\n", ceph_blog_ctx->logger->alloc_batch.nr_full);
> +	seq_printf(s, "  Empty magazines: %u\n", ceph_blog_ctx->logger->alloc_batch.nr_empty);
> +
> +	seq_puts(s, "\nLog Batch:\n");
> +	seq_printf(s, "  Full magazines: %u\n", ceph_blog_ctx->logger->log_batch.nr_full);
> +	seq_printf(s, "  Empty magazines: %u\n", ceph_blog_ctx->logger->log_batch.nr_empty);
> +
> +	return 0;
> +}
> +
> +static int blog_stats_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, blog_stats_show, inode->i_private);
> +}
> +
> +static const struct file_operations blog_stats_fops = {
> +	.open = blog_stats_open,
> +	.read = seq_read,
> +	.llseek = seq_lseek,
> +	.release = single_release,
> +};
> +
> +/**
> + * blog_sources_show - Show all registered source locations
> + */
> +static int blog_sources_show(struct seq_file *s, void *p)
> +{
> +	struct blog_source_info *source;
> +	u32 id;
> +	int count = 0;
> +
> +	seq_puts(s, "Ceph BLOG Source Locations\n");
> +	seq_puts(s, "===========================\n\n");
> +
> +	if (!ceph_blog_ctx || !ceph_blog_ctx->logger) {
> +		seq_puts(s, "Ceph BLOG context not initialized\n");
> +		return 0;
> +	}
> +
> +	for (id = 1; id < BLOG_MAX_SOURCE_IDS; id++) {
> +		source = blog_get_source_info(ceph_blog_ctx->logger, id);
> +		if (!source || !source->file)
> +			continue;
> +
> +		count++;
> +		seq_printf(s, "ID %u: %s:%s:%u\n", id,
> +			  source->file, source->func, source->line);
> +		seq_printf(s, "  Format: %s\n", source->fmt ? source->fmt : "(null)");
> +		seq_printf(s, "  Warnings: %d\n", source->warn_count);
> +
> +#if BLOG_TRACK_USAGE
> +		seq_printf(s, "  NAPI usage: %d calls, %d bytes\n",
> +			  atomic_read(&source->napi_usage),
> +			  atomic_read(&source->napi_bytes));
> +		seq_printf(s, "  Task usage: %d calls, %d bytes\n",
> +			  atomic_read(&source->task_usage),
> +			  atomic_read(&source->task_bytes));
> +#endif
> +		seq_puts(s, "\n");
> +	}
> +
> +	seq_printf(s, "Total registered sources: %d\n", count);
> +
> +	return 0;
> +}
> +
> +static int blog_sources_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, blog_sources_show, inode->i_private);
> +}
> +
> +static const struct file_operations blog_sources_fops = {
> +	.open = blog_sources_open,
> +	.read = seq_read,
> +	.llseek = seq_lseek,
> +	.release = single_release,
> +};
> +
> +/**
> + * blog_clients_show - Show all registered Ceph clients
> + */
> +static int blog_clients_show(struct seq_file *s, void *p)
> +{
> +	u32 id;
> +	int count = 0;
> +	const struct ceph_blog_client_info *info;
> +
> +	seq_puts(s, "Ceph BLOG Registered Clients\n");
> +	seq_puts(s, "=============================\n\n");
> +
> +	for (id = 1; id < CEPH_BLOG_MAX_CLIENTS; id++) {
> +		info = ceph_blog_get_client_info(id);
> +		if (!info || info->global_id == 0)
> +			continue;
> +
> +		count++;
> +
> +		seq_printf(s, "Client ID %u:\n", id);
> +		seq_printf(s, "  FSID: %pU\n", info->fsid);
> +		seq_printf(s, "  Global ID: %llu\n", info->global_id);
> +		seq_puts(s, "\n");
> +	}
> +
> +	seq_printf(s, "Total registered clients: %d\n", count);
> +
> +	return 0;
> +}
> +
> +static int blog_clients_open(struct inode *inode, struct file *file)
> +{
> +	return single_open(file, blog_clients_show, inode->i_private);
> +}
> +
> +static const struct file_operations blog_clients_fops = {
> +	.open = blog_clients_open,
> +	.read = seq_read,
> +	.llseek = seq_lseek,
> +	.release = single_release,
> +};
> +
> +/**
> + * blog_clear_write - Clear all BLOG entries (write-only)
> + */
> +static ssize_t blog_clear_write(struct file *file, const char __user *buf,
> +				size_t count, loff_t *ppos)
> +{
> +	char cmd[16];
> +
> +	if (count >= sizeof(cmd))
> +		return -EINVAL;
> +
> +	if (copy_from_user(cmd, buf, count))
> +		return -EFAULT;
> +
> +	cmd[count] = '\0';
> +
> +	/* Only accept "clear" command */
> +	if (strncmp(cmd, "clear", 5) != 0)
> +		return -EINVAL;
> +
> +	/* Reset all contexts */
> +	if (ceph_blog_ctx && ceph_blog_ctx->logger) {
> +		struct blog_tls_ctx *tls_ctx;
> +
> +		spin_lock(&ceph_blog_ctx->logger->lock);
> +		list_for_each_entry(tls_ctx, &ceph_blog_ctx->logger->contexts, list) {
> +			blog_pagefrag_reset(blog_ctx_pf(tls_ctx));
> +		}
> +		spin_unlock(&ceph_blog_ctx->logger->lock);
> +		pr_info("ceph: BLOG entries cleared via debugfs\n");
> +	}
> +
> +	return count;
> +}
> +
> +static const struct file_operations blog_clear_fops = {
> +	.write = blog_clear_write,
> +};
> +
> +/**
> + * ceph_blog_debugfs_init - Initialize Ceph BLOG debugfs entries
> + * @parent: Parent debugfs directory (usually ceph root)
> + *
> + * Return: 0 on success, negative error code on failure
> + */
> +int ceph_blog_debugfs_init(struct dentry *parent)
> +{
> +	if (!parent)
> +		return -EINVAL;
> +
> +	/* Create blog subdirectory */
> +	ceph_blog_debugfs_dir = debugfs_create_dir("blog", parent);
> +	if (!ceph_blog_debugfs_dir)
> +		return -ENOMEM;
> +
> +	/* Create debugfs entries */
> +	debugfs_create_file("entries", 0444, ceph_blog_debugfs_dir, NULL,
> +			   &blog_entries_fops);
> +
> +	debugfs_create_file("stats", 0444, ceph_blog_debugfs_dir, NULL,
> +			   &blog_stats_fops);
> +
> +	debugfs_create_file("sources", 0444, ceph_blog_debugfs_dir, NULL,
> +			   &blog_sources_fops);
> +
> +	debugfs_create_file("clients", 0444, ceph_blog_debugfs_dir, NULL,
> +			   &blog_clients_fops);
> +
> +	debugfs_create_file("clear", 0200, ceph_blog_debugfs_dir, NULL,
> +			   &blog_clear_fops);
> +
> +	pr_info("ceph: BLOG debugfs initialized\n");
> +	return 0;
> +}
> +EXPORT_SYMBOL(ceph_blog_debugfs_init);
> +
> +/**
> + * ceph_blog_debugfs_cleanup - Clean up Ceph BLOG debugfs entries
> + */
> +void ceph_blog_debugfs_cleanup(void)
> +{
> +	debugfs_remove_recursive(ceph_blog_debugfs_dir);
> +	ceph_blog_debugfs_dir = NULL;
> +	pr_info("ceph: BLOG debugfs cleaned up\n");
> +}
> +EXPORT_SYMBOL(ceph_blog_debugfs_cleanup);
> +
> +static int jiffies_to_formatted_time(u64 jiffies_value, char *buffer,
> +	size_t buffer_len)
> +{
> +	u64 now_ns = ktime_get_real_ns();
> +	u64 now_jiffies = get_jiffies_64();
> +	u64 delta_jiffies = (now_jiffies > jiffies_value) ?
> +		now_jiffies - jiffies_value : 0;
> +	u64 delta_ns = jiffies64_to_nsecs(delta_jiffies);
> +	u64 event_ns = (delta_ns > now_ns) ? 0 : now_ns - delta_ns;
> +	struct timespec64 event_ts = ns_to_timespec64(event_ns);
> +	struct tm tm_time;
> +
> +	if (!buffer || !buffer_len)
> +		return -EINVAL;
> +
> +	time64_to_tm(event_ts.tv_sec, 0, &tm_time);
> +
> +	return scnprintf(buffer, buffer_len,
> +			"%04ld-%02d-%02d %02d:%02d:%02d.%03lu",
> +			tm_time.tm_year + 1900, tm_time.tm_mon + 1, tm_time.tm_mday,
> +			tm_time.tm_hour, tm_time.tm_min, tm_time.tm_sec,
> +			(unsigned long)(event_ts.tv_nsec / NSEC_PER_MSEC));
> +}
> diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
> index f3fe786b4143..9b9c89b88fca 100644
> --- a/fs/ceph/debugfs.c
> +++ b/fs/ceph/debugfs.c
> @@ -9,11 +9,18 @@
>  #include <linux/seq_file.h>
>  #include <linux/math64.h>
>  #include <linux/ktime.h>
> +#include <linux/jiffies.h>
> +#include <linux/timekeeping.h>
> +#include <linux/rtc.h>
> +#include <linux/printk.h>
> +#include <linux/time.h>
> +#include <linux/time_types.h>
>  
>  #include <linux/ceph/libceph.h>
>  #include <linux/ceph/mon_client.h>
>  #include <linux/ceph/auth.h>
>  #include <linux/ceph/debugfs.h>
> +#include <linux/ceph/ceph_blog.h>
>  
>  #include "super.h"
>  
> @@ -360,6 +367,7 @@ static int status_show(struct seq_file *s, void *p)
>  	return 0;
>  }
>  
> +
>  DEFINE_SHOW_ATTRIBUTE(mdsmap);
>  DEFINE_SHOW_ATTRIBUTE(mdsc);
>  DEFINE_SHOW_ATTRIBUTE(caps);
> @@ -396,7 +404,7 @@ DEFINE_SIMPLE_ATTRIBUTE(congestion_kb_fops, congestion_kb_get,
>  
>  void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
>  {
> -	doutc(fsc->client, "begin\n");
> +	boutc(fsc->client, "begin\n");
>  	debugfs_remove(fsc->debugfs_bdi);
>  	debugfs_remove(fsc->debugfs_congestion_kb);
>  	debugfs_remove(fsc->debugfs_mdsmap);
> @@ -405,14 +413,20 @@ void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
>  	debugfs_remove(fsc->debugfs_status);
>  	debugfs_remove(fsc->debugfs_mdsc);
>  	debugfs_remove_recursive(fsc->debugfs_metrics_dir);
> -	doutc(fsc->client, "done\n");
> +
> +#ifdef CONFIG_BLOG
> +	/* Clean up BLOG debugfs entries */
> +	ceph_blog_debugfs_cleanup();
> +#endif
> +
> +	boutc(fsc->client, "done\n");
>  }
>  
>  void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
>  {
>  	char name[NAME_MAX];
>  
> -	doutc(fsc->client, "begin\n");
> +	boutc(fsc->client, "begin\n");
>  	fsc->debugfs_congestion_kb =
>  		debugfs_create_file("writeback_congestion_kb",
>  				    0600,
> @@ -457,6 +471,8 @@ void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
>  						  fsc,
>  						  &status_fops);
>  
> +
> +
>  	fsc->debugfs_metrics_dir = debugfs_create_dir("metrics",
>  						      fsc->client->debugfs_dir);
>  
> @@ -468,9 +484,14 @@ void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
>  			    &metrics_size_fops);
>  	debugfs_create_file("caps", 0400, fsc->debugfs_metrics_dir, fsc,
>  			    &metrics_caps_fops);
> -	doutc(fsc->client, "done\n");
> -}
>  
> +#ifdef CONFIG_BLOG
> +	/* Initialize BLOG debugfs entries */
> +	ceph_blog_debugfs_init(fsc->client->debugfs_dir);
> +#endif
> +
> +	boutc(fsc->client, "done\n");
> +}
>  
>  #else  /* CONFIG_DEBUG_FS */
>  
> @@ -482,4 +503,4 @@ void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
>  {
>  }
>  
> -#endif  /* CONFIG_DEBUG_FS */
> +#endif	/* CONFIG_DEBUG_FS */

  reply	other threads:[~2025-11-03 21:08 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-24  8:42 [RFC PATCH 0/5] BLOG: per-task logging contexts with Ceph consumer Alex Markuze
2025-10-24  8:42 ` [RFC PATCH 1/5] sched, fork: Wire BLOG contexts into task lifecycle Alex Markuze
2025-10-24 17:44   ` Steven Rostedt
2025-10-29 18:57   ` Viacheslav Dubeyko
2025-10-24  8:42 ` [RFC PATCH 2/5] lib: Introduce BLOG (Binary LOGging) subsystem Alex Markuze
2025-10-30 18:47   ` Viacheslav Dubeyko
2025-10-24  8:42 ` [RFC PATCH 3/5] ceph: Add BLOG scaffolding Alex Markuze
2025-11-03 22:37   ` Viacheslav Dubeyko
2025-10-24  8:42 ` [RFC PATCH 4/5] ceph: Add BLOG debugfs support Alex Markuze
2025-11-03 21:07   ` Viacheslav Dubeyko [this message]
2025-10-24  8:42 ` [RFC PATCH 5/5] ceph: Activate BLOG logging Alex Markuze
2025-11-03 21:00   ` Viacheslav Dubeyko
2025-10-24 15:32 ` [RFC PATCH 0/5] BLOG: per-task logging contexts with Ceph consumer David Hildenbrand
2025-10-24 17:53 ` Steven Rostedt
2025-10-25 10:50   ` Alex Markuze
2025-10-25 14:59     ` Steven Rostedt
2025-10-25 17:54       ` Alex Markuze
2025-10-27 14:54         ` Steven Rostedt
2025-10-28 17:07 ` Viacheslav Dubeyko

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=e879c32eab8854773ff32d1e1f06b6a74afabec2.camel@ibm.com \
    --to=slava.dubeyko@ibm.com \
    --cc=Liam.Howlett@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=amarkuze@redhat.com \
    --cc=bsegall@google.com \
    --cc=ceph-devel@vger.kernel.org \
    --cc=david@redhat.com \
    --cc=dietmar.eggemann@arm.com \
    --cc=idryomov@gmail.com \
    --cc=juri.lelli@redhat.com \
    --cc=kees@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lorenzo.stoakes@oracle.com \
    --cc=mgorman@suse.de \
    --cc=mhocko@suse.com \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=rppt@kernel.org \
    --cc=surenb@google.com \
    --cc=vbabka@suse.cz \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    --cc=xiubli@redhat.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).