]> git.apps.os.sepia.ceph.com Git - ceph-client.git/commitdiff
cephsan new logger
authorAlex Markuze <amarkuze@redhat.com>
Mon, 17 Mar 2025 16:19:00 +0000 (16:19 +0000)
committerAlex Markuze <amarkuze@redhat.com>
Mon, 17 Mar 2025 16:19:00 +0000 (16:19 +0000)
fs/ceph/debugfs.c
fs/ceph/super.c
fs/ceph/super.h
include/linux/ceph/ceph_debug.h
include/linux/ceph/ceph_san.h [deleted file]
include/linux/ceph/ceph_san_logger.h
net/ceph/Makefile
net/ceph/ceph_san.c [deleted file]
net/ceph/ceph_san_logger.c

index f30bef4ec84609faf5c7c31a23e7eef83f552b3f..8ae3a7b545599f1a254fd4ca19072ae71d6d4a97 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/ktime.h>
 
 #include <linux/ceph/libceph.h>
-#include <linux/ceph/ceph_san.h>
+#include <linux/ceph/ceph_san_logger.h>
 #include <linux/ceph/mon_client.h>
 #include <linux/ceph/auth.h>
 #include <linux/ceph/debugfs.h>
 #include "mds_client.h"
 #include "metric.h"
 
-static int histogram_show(struct seq_file *s, void *p)
-{
-       struct ceph_san_percore_logger *pc;
-       size_t cpu;
-       u64 total_histogram[16] = {0};
-       int i;
-
-       seq_printf(s, "Ceph TLS Histogram Summary:\n");
-       seq_printf(s, "%-10s %-16s\n", "Bucket", "Count");
-       seq_printf(s, "-------------------------\n");
-
-       /* Sum up histograms from all CPUs */
-       for_each_possible_cpu(cpu) {
-               pc = &per_cpu(ceph_san_percore, cpu);
-
-               /* Add each CPU's histogram data to the total */
-               for (i = 0; i < 16; i++) {
-                       total_histogram[i] += pc->histogram.counters[i];
-               }
-       }
-
-       /* Calculate total sum for normalization */
-       u64 sum = 0;
-       for (i = 0; i < 16; i++) {
-               sum += total_histogram[i];
-       }
-
-       /* Display normalized histogram with stars and percentages */
-       for (i = 0; i < 16; i++) {
-               int stars = sum ? (total_histogram[i] * 128) / sum : 0;
-               u64 percent = sum ? (total_histogram[i] * 100) / sum : 0;
-               seq_printf(s, "%-4d [%3llu%%] ", i, percent);
-               while (stars-- > 0)
-                       seq_printf(s, "*");
-               seq_printf(s, "\n");
-       }
-
-       return 0;
-}
-
-static int ceph_san_show(struct seq_file *s, void *p)
-{
-       struct ceph_san_percore_logger *pc;
-       size_t cpu;
-
-       seq_printf(s, "Ceph SAN logs:\n");
-       seq_printf(s, "%-16s %-8s %-32s\n",
-                          "Task", "PID", "Log");
-       seq_printf(s, "--------------------------------------------------------------\n");
-
-       for_each_possible_cpu(cpu) {
-               pc = &per_cpu(ceph_san_percore, cpu);
-               int i;
-
-               int idx = 0;
-               int head_idx = pc->head_idx & (CEPH_SAN_MAX_LOGS - 1);
-               int tail_idx = (head_idx + 1) & (CEPH_SAN_MAX_LOGS - 1);
-
-               for (i = tail_idx; (i & (CEPH_SAN_MAX_LOGS -1)) != head_idx; i++) {
-                       struct timespec64 ts;
-                       struct ceph_san_log_entry *log = &pc->logs[i & (CEPH_SAN_MAX_LOGS -1)];
-                       jiffies_to_timespec64(log->ts, &ts);
-
-                       if (log->ts == 0) {
-                               continue;
-                       }
-                       seq_printf(s, "%zu:%lld.%09ld:%d) %-16s %-8d:%s\n",
-                               cpu,
-                               (long long)ts.tv_sec,
-                               ts.tv_nsec,
-                               idx++,
-                               log->comm,
-                               log->pid,
-                               log->buf);
-               }
-       }
-
-       return 0;
-}
-
 static int mdsmap_show(struct seq_file *s, void *p)
 {
        int i;
@@ -443,104 +363,73 @@ static int status_show(struct seq_file *s, void *p)
        return 0;
 }
 
-static int ceph_san_contexts_show(struct seq_file *s, void *p)
+static int ceph_san_tls_show(struct seq_file *s, void *p)
 {
-       struct tls_ceph_san_context *ctx;
-       struct ceph_san_tls_logger *logger;
-       struct timespec64 ts;
-       unsigned long flags;
-       int count = 0;
+       struct ceph_san_tls_ctx *ctx;
+       struct ceph_san_log_iter iter;
+       struct ceph_san_log_entry *entry;
 
-       seq_printf(s, "All Ceph SAN TLS contexts:\n");
-       seq_printf(s, "%-8s %-16s %-20s %-12s %-12s\n",
-                          "PID", "Task", "Last Activity", "Cache Type", "Log Count");
-       seq_printf(s, "--------------------------------------------------------------\n");
+       /* Lock the logger to safely traverse the contexts list */
+       spin_lock(&g_logger.lock);
 
-       spin_lock_irqsave(&g_ceph_san_contexts_lock, flags);
+       list_for_each_entry(ctx, &g_logger.contexts, list) {
+               /* Print context information */
+               seq_printf(s, "Context: PID=%d Command=%s\n", ctx->pid, ctx->comm);
 
-       list_for_each_entry(ctx, &g_ceph_san_contexts, list) {
-               logger = &ctx->logger;
-               count++;
+               /* Initialize iterator for this context's pagefrag */
+               ceph_san_log_iter_init(&iter, &ctx->pf);
 
-               /* Get timestamp of most recent log entry */
-               int head_idx = logger->head_idx & (CEPH_SAN_MAX_LOGS - 1);
-               struct ceph_san_log_entry_tls *entry = &logger->logs[head_idx];
+               /* Lock the pagefrag before accessing entries */
+               spin_lock(&ctx->pf.lock);
 
-               if (entry->ts == 0) {
-                       seq_printf(s, "%-8s %-16s %-20s %-12s %-12d\n",
-                                         "N/A", "N/A", "N/A", "N/A", 0);
-                       continue;
-               }
+               /* Iterate through all log entries in this context */
+               while ((entry = ceph_san_log_iter_next(&iter)) != NULL) {
+                       if (entry->debug_poison != CEPH_SAN_LOG_ENTRY_POISON) {
+                               seq_puts(s, "    [Corrupted Entry]\n");
+                               continue;
+                       }
 
-               jiffies_to_timespec64(entry->ts, &ts);
+                       seq_printf(s, "    [%llu] %s:%u: %.*s\n",
+                                         entry->ts,
+                                         entry->file,
+                                         entry->line,
+                                         entry->len,
+                                         entry->buffer);
+               }
 
-               seq_printf(s, "%-8d %-16s %-20lld.%09ld\n",
-                               logger->pid,
-                               logger->comm,
-                                (long long)ts.tv_sec,
-                                ts.tv_nsec);
+               /* Unlock the pagefrag after we're done with this context */
+               spin_unlock(&ctx->pf.lock);
        }
 
-       spin_unlock_irqrestore(&g_ceph_san_contexts_lock, flags);
-
-       seq_printf(s, "\nTotal contexts: %d\n", count);
-
+       spin_unlock(&g_logger.lock);
        return 0;
 }
 
-static int ceph_san_tls_show(struct seq_file *s, void *p)
+static int ceph_san_contexts_show(struct seq_file *s, void *p)
 {
-       struct tls_ceph_san_context *ctx;
-       struct ceph_san_tls_logger *logger;
-       struct ceph_san_log_entry_tls *entry;
+       struct ceph_san_tls_ctx *ctx;
        unsigned long flags;
-       int count = 0;
-
-       seq_printf(s, "All Ceph SAN TLS logs from all contexts:\n");
-       seq_printf(s, "%-8s %-16s %-20s %-8s %-s\n",
-                          "PID", "Task", "Timestamp", "Index", "Log Message");
-       seq_printf(s, "-------------------------------------------------------------------------\n");
-
-       spin_lock_irqsave(&g_ceph_san_contexts_lock, flags);
-
-       list_for_each_entry(ctx, &g_ceph_san_contexts, list) {
-               logger = &ctx->logger;
-               count++;
-
-               seq_printf(s, "\n=== Context for PID %d ===\n", logger->pid);
-
-               int idx = 0;
-               int head_idx = logger->head_idx & (CEPH_SAN_MAX_LOGS - 1);
-               int tail_idx = (head_idx + 1) & (CEPH_SAN_MAX_LOGS - 1);
 
-               for (int i = tail_idx; (i & (CEPH_SAN_MAX_LOGS - 1)) != head_idx; i++) {
-                       struct timespec64 ts;
-                       entry = &logger->logs[i & (CEPH_SAN_MAX_LOGS - 1)];
+       /* Lock the logger to safely traverse the contexts list */
+       spin_lock_irqsave(&g_logger.lock, flags);
 
-                       if (entry->ts == 0 || !entry->buf) {
-                               continue;
-                       }
+       seq_puts(s, "Active TLS Contexts:\n");
+       seq_puts(s, "PID      Command          Buffer Size\n");
+       seq_puts(s, "----------------------------------------\n");
 
-                       jiffies_to_timespec64(entry->ts, &ts);
-
-                       seq_printf(s, "%-8d %-16s %lld.%09ld\n",
-                                         logger->pid,
-                                         logger->comm,
-                                         (long long)ts.tv_sec,
-                                         ts.tv_nsec);
+       list_for_each_entry(ctx, &g_logger.contexts, list) {
+               unsigned int buffer_size = ctx->pf.head - ctx->pf.tail;
+               if (ctx->pf.head < ctx->pf.tail) {
+                       buffer_size = CEPHSAN_PAGEFRAG_SIZE - ctx->pf.tail + ctx->pf.head;
                }
 
-               seq_printf(s, "\n");
-       }
-
-       spin_unlock_irqrestore(&g_ceph_san_contexts_lock, flags);
-
-       if (count == 0) {
-               seq_printf(s, "No TLS contexts found.\n");
-       } else {
-               seq_printf(s, "\nTotal contexts: %d\n", count);
+               seq_printf(s, "%-8d %-15s %u bytes\n",
+                                 ctx->pid,
+                                 ctx->comm,
+                                 buffer_size);
        }
 
+       spin_unlock_irqrestore(&g_logger.lock, flags);
        return 0;
 }
 
@@ -553,10 +442,8 @@ DEFINE_SHOW_ATTRIBUTE(metrics_file);
 DEFINE_SHOW_ATTRIBUTE(metrics_latency);
 DEFINE_SHOW_ATTRIBUTE(metrics_size);
 DEFINE_SHOW_ATTRIBUTE(metrics_caps);
-DEFINE_SHOW_ATTRIBUTE(ceph_san);
-DEFINE_SHOW_ATTRIBUTE(histogram);
-DEFINE_SHOW_ATTRIBUTE(ceph_san_contexts);
 DEFINE_SHOW_ATTRIBUTE(ceph_san_tls);
+DEFINE_SHOW_ATTRIBUTE(ceph_san_contexts);
 
 
 /*
@@ -592,8 +479,6 @@ void ceph_fs_debugfs_cleanup(struct ceph_fs_client *fsc)
        debugfs_remove(fsc->debugfs_caps);
        debugfs_remove(fsc->debugfs_status);
        debugfs_remove(fsc->debugfs_mdsc);
-       debugfs_remove(fsc->debugfs_cephsan);
-       debugfs_remove(fsc->debugfs_histogram);
        debugfs_remove(fsc->debugfs_cephsan_tls);
        debugfs_remove(fsc->debugfs_cephsan_contexts);
        debugfs_remove_recursive(fsc->debugfs_metrics_dir);
@@ -648,17 +533,7 @@ void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
                                                  fsc->client->debugfs_dir,
                                                  fsc,
                                                  &status_fops);
-       fsc->debugfs_cephsan = debugfs_create_file("cephsan",
-                                                       0444,
-                                                       fsc->client->debugfs_dir,
-                                                       fsc,
-                                                       &ceph_san_fops);
 
-       fsc->debugfs_histogram = debugfs_create_file("histogram",
-                                                       0444,
-                                                       fsc->client->debugfs_dir,
-                                                       fsc,
-                                                       &histogram_fops);
 
        fsc->debugfs_cephsan_tls = debugfs_create_file("cephsan_tls",
                                                        0444,
@@ -666,13 +541,13 @@ void ceph_fs_debugfs_init(struct ceph_fs_client *fsc)
                                                        fsc,
                                                        &ceph_san_tls_fops);
 
+       /* Add the new contexts-only view */
        fsc->debugfs_cephsan_contexts = debugfs_create_file("cephsan_contexts",
                                                        0444,
                                                        fsc->client->debugfs_dir,
                                                        fsc,
                                                        &ceph_san_contexts_fops);
 
-
        fsc->debugfs_metrics_dir = debugfs_create_dir("metrics",
                                                      fsc->client->debugfs_dir);
 
index 6b5c1657febb2e312d277cbdc6a3e16c9bcc716b..5d81b6509816567287c21d47ea3e39c638618489 100644 (file)
@@ -1,8 +1,8 @@
-// SPDX-License-Identifier: GPL-2.0-only
+
 
 #include "linux/mm_types.h"
 #include <linux/ceph/ceph_debug.h>
-#include <linux/ceph/ceph_san.h>
+#include <linux/ceph/ceph_san_logger.h>
 
 #include <linux/backing-dev.h>
 #include <linux/ctype.h>
@@ -1639,15 +1639,18 @@ static int __init init_ceph(void)
                goto out;
 
        ceph_flock_init();
-       ret = cephsan_init();
-       ret = register_filesystem(&ceph_fs_type);
+       ret = ceph_san_logger_init();
        if (ret)
                goto out_caches;
+       ret = register_filesystem(&ceph_fs_type);
+       if (ret)
+               goto out_logger;
 
        pr_info("loaded (mds proto %d)\n", CEPH_MDSC_PROTOCOL);
 
        return 0;
-
+out_logger:
+       ceph_san_logger_cleanup();
 out_caches:
        destroy_caches();
 out:
@@ -1657,7 +1660,7 @@ out:
 static void __exit exit_ceph(void)
 {
        dout("exit_ceph\n");
-       cephsan_cleanup();
+       ceph_san_logger_cleanup();
        unregister_filesystem(&ceph_fs_type);
        destroy_caches();
 }
index 21c4d94c2a824286517f802b18e2ac5800a3ae9d..584a3fd15ed863d8fb614fc2362c860074f3ef3e 100644 (file)
@@ -153,8 +153,6 @@ struct ceph_fs_client {
        struct dentry *debugfs_status;
        struct dentry *debugfs_mds_sessions;
        struct dentry *debugfs_metrics_dir;
-       struct dentry *debugfs_cephsan;
-       struct dentry *debugfs_histogram;
        struct dentry *debugfs_cephsan_contexts;
        struct dentry *debugfs_cephsan_tls;
 #endif
index 229dbda82df936f5dcc5602939dd21842432366a..59c35957e0238e322e6856b1d977abc919c74036 100644 (file)
@@ -6,7 +6,7 @@
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/string.h>
-#include <linux/ceph/ceph_san.h>
+#include <linux/ceph/ceph_san_logger.h>
 
 #ifdef CONFIG_CEPH_LIB_PRETTYDEBUG
 
@@ -51,9 +51,9 @@
 /*
  * or, just wrap pr_debug
  */
-# define dout(fmt, ...)        pr_debug(" " fmt, ##__VA_ARGS__)
+# define dout(fmt, ...)        CEPH_SAN_LOG(fmt, ##__VA_ARGS__)
 # define doutc(client, fmt, ...)                                       \
-       pr_debug(" [%pU %llu] %s: " fmt, &client->fsid,                 \
+       CEPH_SAN_LOG(" [%pU %llu] %s: " fmt, &client->fsid,                     \
                 client->monc.auth->global_id, __func__, ##__VA_ARGS__)
 
 #endif
diff --git a/include/linux/ceph/ceph_san.h b/include/linux/ceph/ceph_san.h
deleted file mode 100644 (file)
index cb804ba..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-#ifndef CEPHSAN_H
-#define CEPHSAN_H
-
-#include <linux/types.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include "ceph_san_pagefrag.h"
-
-DECLARE_PER_CPU(struct ceph_san_percore_logger, ceph_san_percore);
-DECLARE_PER_CPU(struct cephsan_pagefrag, ceph_san_pagefrag);
-
-#ifdef CONFIG_DEBUG_FS
-#define CEPH_SAN_MAX_LOGS (8192 << 2) //4MB per core
-#define LOG_BUF_SIZE 256
-#define LOG_BUF_SMALL 128
-
-void cephsan_cleanup(void);
-int cephsan_init(void);
-
-void log_cephsan(char *buf);
-void log_cephsan_tls(char *buf);
-int cephsan_dump_all_contexts(char *buf, size_t size);
-
-#define CEPH_SAN_LOG(fmt, ...) do { \
-    char buf[LOG_BUF_SIZE] = {0}; \
-    snprintf(buf, LOG_BUF_SIZE, fmt, ##__VA_ARGS__); \
-    log_cephsan(buf); \
-} while (0)
-
-#define CEPH_SAN_LOG_TLS(fmt, ...) do { \
-    char buf[LOG_BUF_SIZE] = {0}; \
-    snprintf(buf, LOG_BUF_SIZE, fmt, ##__VA_ARGS__); \
-    log_cephsan_tls(buf); \
-} while (0)
-
-/*
- * Internal definitions for Ceph SAN logs.
- * These definitions are not part of the public API but are required by debugfs.c.
- */
-struct ceph_san_log_entry {
-    char comm[TASK_COMM_LEN];
-    char *buf;
-    u64 ts;
-    pid_t pid;
-    u32 len;
-};
-
-struct ceph_san_log_entry_tls {
-    u64 ts;
-    char *buf;
-};
-
-struct histogram {
-    u64 counters[32];
-};
-
-struct ceph_san_percore_logger {
-    size_t head_idx;
-    struct page *pages;
-    struct ceph_san_log_entry *logs;
-    struct histogram histogram;
-};
-
-struct ceph_san_tls_logger {
-    char comm[TASK_COMM_LEN];
-    pid_t pid;
-    size_t head_idx;
-    struct ceph_san_log_entry_tls logs[CEPH_SAN_MAX_LOGS];
-};
-
-/* Bundled TLS context containing both logger and memory caches */
-struct tls_ceph_san_context {
-    u64 sig;
-    struct list_head list;  /* For global list of contexts */
-    struct ceph_san_tls_logger logger;
-};
-
-/* Global list of all TLS contexts and its protection lock */
-extern struct list_head g_ceph_san_contexts;
-extern spinlock_t g_ceph_san_contexts_lock;
-
-#else /* CONFIG_DEBUG_FS */
-
-#define CEPH_SAN_LOG(param) do {} while (0)
-#define CEPH_SAN_LOG_TLS(param) do {} while (0)
-
-static inline void cephsan_cleanup(void) {}
-static inline int __init cephsan_init(void) { return 0; }
-
-#endif /* CONFIG_DEBUG_FS */
-
-#define CEPH_SAN_SET_REQ(req) do { current->journal_info = req; } while (0)
-#define CEPH_SAN_RESET_REQ() do { current->journal_info = NULL; } while (0)
-#define CEPH_SAN_GET_REQ() (current->journal_info)
-
-#endif /* CEPHSAN_H */
index 4ce1ed182bf3240a7b623a9944b5e0a659d3a0ac..e8614e46a51aecbd2f8dfc3e2cd0f401bfc59188 100644 (file)
@@ -67,4 +67,7 @@ struct ceph_san_tls_ctx *ceph_san_get_tls_ctx(void);
 #define CEPH_SAN_LOG(fmt, ...) \
     ceph_san_log(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
 
+/* Global logger instance */
+extern struct ceph_san_logger g_logger;
+
 #endif /* CEPH_SAN_LOGGER_H */
\ No newline at end of file
index 1df96e9561fa7dc341f9c837cf9f7198f70c882a..c0766fd8b2cd209e3aef9e0f2545211a3396bd0e 100644 (file)
@@ -10,7 +10,7 @@ libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
        osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \
        striper.o \
        debugfs.o \
-       ceph_san.o ceph_san_pagefrag.o ceph_san_batch.o \
+       ceph_san_pagefrag.o ceph_san_batch.o  ceph_san_logger.o \
        auth.o auth_none.o \
        crypto.o armor.o \
        auth_x.o \
diff --git a/net/ceph/ceph_san.c b/net/ceph/ceph_san.c
deleted file mode 100644 (file)
index 710ba1a..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/sched.h>
-#include <linux/jiffies.h>
-#include <linux/ceph/ceph_san.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-
-/* Use per-core TLS logger; no global list or lock needed */
-DEFINE_PER_CPU(struct ceph_san_percore_logger, ceph_san_percore);
-EXPORT_SYMBOL(ceph_san_percore);
-
-DEFINE_PER_CPU(struct cephsan_pagefrag, ceph_san_pagefrag);
-
-/* Global list of all TLS contexts and its protection lock */
-LIST_HEAD(g_ceph_san_contexts);
-DEFINE_SPINLOCK(g_ceph_san_contexts_lock);
-EXPORT_SYMBOL(g_ceph_san_contexts);
-EXPORT_SYMBOL(g_ceph_san_contexts_lock);
-
-/* Memory caches for log entries */
-struct kmem_cache *ceph_san_log_128_cache;
-struct kmem_cache *ceph_san_log_256_cache;
-
-struct kmem_cache *ceph_san_tls_logger_cache;
-
-#define CEPH_SAN_SIG 0xDEADC0DE
-
-/* Release function for TLS storage */
-static void ceph_san_tls_release(void *ptr)
-{
-    struct tls_ceph_san_context *context = ptr;
-    if (!context)
-        return;
-
-    if (context->sig != CEPH_SAN_SIG) {
-        pr_err("sig is wrong %p %llx != %llx", context, context->sig, CEPH_SAN_SIG);
-        return;
-    }
-
-    /* Remove from global list with lock protection */
-    spin_lock(&g_ceph_san_contexts_lock);
-    list_del(&context->list);
-    spin_unlock(&g_ceph_san_contexts_lock);
-
-    /* Free all log entries */
-    int head_idx = context->logger.head_idx & (CEPH_SAN_MAX_LOGS - 1);
-    int tail_idx = (head_idx + 1) & (CEPH_SAN_MAX_LOGS - 1);
-
-    for (int i = tail_idx; (i & (CEPH_SAN_MAX_LOGS - 1)) != head_idx; i++) {
-        struct ceph_san_log_entry_tls *entry = &context->logger.logs[i & (CEPH_SAN_MAX_LOGS - 1)];
-        if (entry->buf) {
-            if (entry->ts & 0x1)
-                kmem_cache_free(ceph_san_log_256_cache, entry->buf);
-            else
-                kmem_cache_free(ceph_san_log_128_cache, entry->buf);
-            entry->buf = NULL;
-        }
-    }
-
-    kmem_cache_free(ceph_san_tls_logger_cache, context);
-}
-
-static struct tls_ceph_san_context *get_cephsan_context(void)
-{
-    struct tls_ceph_san_context *context;
-
-    context = current->tls.state;
-    if (context)
-        return context;
-
-    context = kmem_cache_alloc(ceph_san_tls_logger_cache, GFP_KERNEL);
-    if (!context) {
-        pr_err("Failed to allocate TLS logger for PID %d\n", current->pid);
-        return NULL;
-    }
-
-    context->logger.pid = current->pid;
-    memcpy(context->logger.comm, current->comm, TASK_COMM_LEN);
-
-    /* Initialize list entry */
-    INIT_LIST_HEAD(&context->list);
-    context->sig = CEPH_SAN_SIG;
-
-    current->tls.state = context;
-    current->tls.release = ceph_san_tls_release;
-
-    /* Add to global list with lock protection */
-    spin_lock(&g_ceph_san_contexts_lock);
-    list_add(&context->list, &g_ceph_san_contexts);
-    spin_unlock(&g_ceph_san_contexts_lock);
-
-    return context;
-}
-
-void log_cephsan_tls(char *buf)
-{
-    /* Use the task's TLS storage */
-    int len = strlen(buf);
-    struct tls_ceph_san_context *ctx;
-    struct ceph_san_tls_logger *logger;
-    char *new_buf;
-
-    ctx = get_cephsan_context();
-    if (!ctx)
-        return;
-
-    logger = &ctx->logger;
-
-    /* Log the message */
-    int head_idx = logger->head_idx + 1 & (CEPH_SAN_MAX_LOGS - 1);
-    struct ceph_san_log_entry_tls *entry = &logger->logs[head_idx];
-
-    /* Only free and reallocate if sizes differ */
-    if (!entry->buf || (entry->ts & 0x1) != (len > LOG_BUF_SMALL)) {
-        if (entry->buf) {
-            if (entry->ts & 0x1)
-                kmem_cache_free(ceph_san_log_256_cache, entry->buf);
-            else
-                kmem_cache_free(ceph_san_log_128_cache, entry->buf);
-            entry->buf = NULL;
-        }
-
-        /* Allocate new buffer from appropriate cache */
-        if (len <= LOG_BUF_SMALL) {
-            new_buf = kmem_cache_alloc(ceph_san_log_128_cache, GFP_KERNEL);
-            entry->ts = jiffies & ~0x1;
-        } else {
-            new_buf = kmem_cache_alloc(ceph_san_log_256_cache, GFP_KERNEL);
-            entry->ts = jiffies | 0x1;
-        }
-    } else {
-        /* Reuse existing buffer since size category hasn't changed */
-        new_buf = entry->buf;
-    }
-
-    if (!new_buf)
-        return;
-
-    buf[len-1] = '\0';
-    entry->buf = new_buf;
-    memcpy(entry->buf, buf, len);
-
-    logger->head_idx = head_idx;
-}
-
-static void log_cephsan_percore(char *buf)
-{
-    /* Use the per-core TLS logger */
-    u64 buf_idx;
-    int len = strlen(buf);
-    struct ceph_san_percore_logger *pc = this_cpu_ptr(&ceph_san_percore);
-    struct cephsan_pagefrag *pf = this_cpu_ptr(&ceph_san_pagefrag);
-
-    int head_idx = pc->head_idx + 1 & (CEPH_SAN_MAX_LOGS - 1);
-    int pre_len = pc->logs[head_idx].len;
-
-    buf[len-1] = '\0';
-    pc->logs[head_idx].pid = current->pid;
-    pc->logs[head_idx].ts = jiffies;
-    memcpy(pc->logs[head_idx].comm, current->comm, TASK_COMM_LEN);
-
-    cephsan_pagefrag_free(pf, pre_len);
-    pc->logs[head_idx].len = 0;
-
-    buf_idx = cephsan_pagefrag_alloc(pf, len);
-    if (buf_idx) {
-        pc->head_idx = head_idx;
-        pc->histogram.counters[(len >= 256) ? 31 : len >> 3]++;
-        pc->logs[head_idx].len = len;
-        pc->logs[head_idx].buf = cephsan_pagefrag_get_ptr(pf, buf_idx);
-        memcpy(pc->logs[head_idx].buf, buf, len);
-    }
-}
-
-void log_cephsan(char *buf)
-{
-    log_cephsan_percore(buf);
-    log_cephsan_tls(buf);
-}
-EXPORT_SYMBOL(log_cephsan);
-
-/* Cleanup function to free all TLS logger objects.
- * Call this at module exit to free allocated TLS loggers.
- */
-void cephsan_cleanup(void)
-{
-    int cpu;
-    struct ceph_san_percore_logger *pc;
-
-    for_each_possible_cpu(cpu) {
-        pc = per_cpu_ptr(&ceph_san_percore, cpu);
-        if (pc->pages) {
-            free_pages((unsigned long)pc->pages, get_order(CEPH_SAN_MAX_LOGS * sizeof(struct ceph_san_log_entry)));
-            pc->pages = NULL;
-        }
-    }
-#if 0
-    /* Let the TLS contexts cleanup lazily */
-    if (ceph_san_tls_logger_cache) {
-        kmem_cache_destroy(ceph_san_tls_logger_cache);
-        ceph_san_tls_logger_cache = NULL;
-    }
-
-    if (ceph_san_log_128_cache) {
-        kmem_cache_destroy(ceph_san_log_128_cache);
-        ceph_san_log_128_cache = NULL;
-    }
-
-    if (ceph_san_log_256_cache) {
-        kmem_cache_destroy(ceph_san_log_256_cache);
-        ceph_san_log_256_cache = NULL;
-    }
-#endif
-}
-EXPORT_SYMBOL(cephsan_cleanup);
-
-/* Initialize the Ceph SAN logging infrastructure.
- * Call this at module init to set up the global list and lock.
- */
-int cephsan_init(void)
-{
-    int cpu;
-    struct ceph_san_percore_logger *pc;
-    struct cephsan_pagefrag *pf;
-
-    /* Initialize the global list */
-    INIT_LIST_HEAD(&g_ceph_san_contexts);
-
-    /* Create memory caches for log entries */
-    ceph_san_log_128_cache = kmem_cache_create("ceph_san_log_128",
-                                             LOG_BUF_SMALL,
-                                             0, SLAB_HWCACHE_ALIGN,
-                                             NULL);
-    if (!ceph_san_log_128_cache)
-        goto cleanup_128_cache;
-
-    ceph_san_log_256_cache = kmem_cache_create("ceph_san_log_256",
-                                             LOG_BUF_SIZE,
-                                             0, SLAB_HWCACHE_ALIGN,
-                                             NULL);
-    if (!ceph_san_log_256_cache)
-        goto cleanup_256_cache;
-
-    ceph_san_tls_logger_cache = kmem_cache_create("ceph_san_tls_logger",
-                                             sizeof(struct tls_ceph_san_context),
-                                             0, SLAB_HWCACHE_ALIGN,
-                                             NULL);
-    if (!ceph_san_tls_logger_cache)
-        goto cleanup_logger_cache;
-
-    for_each_possible_cpu(cpu) {
-        pc = per_cpu_ptr(&ceph_san_percore, cpu);
-        pc->pages = alloc_pages(GFP_KERNEL, get_order(CEPH_SAN_MAX_LOGS * sizeof(struct ceph_san_log_entry)));
-        if (!pc->pages) {
-            pr_err("Failed to allocate TLS logs for CPU %d\n", cpu);
-            goto cleanup;
-        }
-        pc->logs = (struct ceph_san_log_entry *)page_address(pc->pages);
-    }
-
-    for_each_possible_cpu(cpu) {
-        pf = per_cpu_ptr(&ceph_san_pagefrag, cpu);
-        cephsan_pagefrag_init(pf);
-    }
-    return 0;
-
-cleanup:
-    cephsan_cleanup();
-    return -ENOMEM;
-
-cleanup_logger_cache:
-    kmem_cache_destroy(ceph_san_log_256_cache);
-    ceph_san_log_256_cache = NULL;
-
-cleanup_256_cache:
-    kmem_cache_destroy(ceph_san_log_128_cache);
-    ceph_san_log_128_cache = NULL;
-
-cleanup_128_cache:
-    return -ENOMEM;
-}
-EXPORT_SYMBOL(cephsan_init);
-
-/**
- * cephsan_dump_all_contexts - Dump logs from all TLS contexts to a buffer
- * @buf: Buffer to write logs to
- * @size: Size of the buffer
- *
- * This function iterates through all TLS contexts in the global list and
- * dumps their logs to the provided buffer. It's useful for debugging and
- * crash analysis.
- *
- * Return: Number of bytes written to the buffer
- */
-int cephsan_dump_all_contexts(char *buf, size_t size)
-{
-    struct tls_ceph_san_context *ctx;
-    struct ceph_san_tls_logger *tls;
-    struct ceph_san_log_entry_tls *entry;
-    unsigned long flags;
-    int len = 0;
-    int count = 0;
-
-    if (!buf || size == 0)
-        return 0;
-
-    len += snprintf(buf + len, size - len,
-                   "=== Ceph SAN TLS logs from all contexts ===\n");
-
-    spin_lock_irqsave(&g_ceph_san_contexts_lock, flags);
-
-    list_for_each_entry(ctx, &g_ceph_san_contexts, list) {
-        tls = &ctx->logger;
-        count++;
-
-        if (len >= size - 1)
-            break;
-
-        len += snprintf(buf + len, size - len,
-                       "\n=== Context %d (PID %d, comm %s) ===\n",
-                       count, tls->pid, tls->comm);
-        int head_idx = tls->head_idx & (CEPH_SAN_MAX_LOGS - 1);
-        int tail_idx = (head_idx + 1) & (CEPH_SAN_MAX_LOGS - 1);
-
-        for (int i = tail_idx; (i & (CEPH_SAN_MAX_LOGS - 1)) != head_idx; i++) {
-            struct timespec64 ts;
-            entry = &tls->logs[i & (CEPH_SAN_MAX_LOGS - 1)];
-
-            if (entry->ts == 0 || !entry->buf)
-                continue;
-
-            if (len >= size - 1)
-                break;
-
-            jiffies_to_timespec64(entry->ts, &ts);
-
-            len += snprintf(buf + len, size - len,
-                           "[%lld.%09ld] : %s\n",
-                           (long long)ts.tv_sec,
-                           ts.tv_nsec,
-                           entry->buf ? entry->buf : "(null)");
-        }
-    }
-
-    spin_unlock_irqrestore(&g_ceph_san_contexts_lock, flags);
-
-    if (count == 0 && len < size - 1) {
-        len += snprintf(buf + len, size - len, "No TLS contexts found.\n");
-    } else if (len < size - 1) {
-        len += snprintf(buf + len, size - len, "\nTotal contexts: %d\n", count);
-    }
-
-    return len;
-}
-EXPORT_SYMBOL(cephsan_dump_all_contexts);
index 9b3a8ebc57fc096629eb80aff39e450dff658e36..4e4461fe655d17104abeea9906775c4a1baab521 100644 (file)
@@ -9,7 +9,8 @@
 
 #define CEPH_SAN_LOG_BATCH_MAX_FULL 128
 /* Global logger instance */
-static struct ceph_san_logger g_logger;
+struct ceph_san_logger g_logger;
+EXPORT_SYMBOL(g_logger);
 
 static void *alloc_tls_ctx(void)
 {