From: "Łukasz Bartosik" <lb@semihalf.com>
To: Andreas Noever <andreas.noever@gmail.com>,
Michael Jamet <michael.jamet@intel.com>,
Mika Westerberg <mika.westerberg@linux.intel.com>,
Yehezkel Bernat <YehezkelShB@gmail.com>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
upstream@semihalf.com
Subject: [PATCH v1 1/2] thunderbolt: add tracefs support to tb_* logging helpers
Date: Thu, 27 Jul 2023 15:13:25 +0200 [thread overview]
Message-ID: <20230727131326.2282301-1-lb@semihalf.com> (raw)
Thunderbolt tracing is a lightweight alternative to traditional
thunderbolt debug logging. While thunderbolt debug logging is quite
convenient when reproducing a specific issue, it doesn't help when
something goes wrong unexpectedly. There are a couple of reasons why
one does not want to enable thunderbolt debug logging at all times:
1. We don't want to overwhelm kernel log with thunderbolt spam, others
want to use it too
2. Console logging is slow
Thunderbolt tracing aims to solve both these problems. Use of
the thunderbolt tracefs instance allows to enable thunderbolt
logging in production without impacting performance or spamming
the system logs.
To use thunderbolt tracing, set the thunderbolt.trace module parameter
(via cmdline or sysfs) to true:
::
eg: echo true > /sys/module/thunderbolt/parameters/trace
Once active, all log messages will be written to the thunderbolt trace.
Once at capacity, the trace will overwrite old messages with new ones.
At any point, one can read the trace file to extract the previous
thunderbolt messages:
::
eg: cat /sys/kernel/tracing/instances/thunderbolt/trace
The thunderbolt trace instance is subsystem wide, so if you have multiple
devices active, they will be adding logs to the same trace.
Signed-off-by: Łukasz Bartosik <lb@semihalf.com>
---
drivers/thunderbolt/nhi.c | 81 +++++++++++++++++++++++++++++++++++++++
drivers/thunderbolt/tb.h | 60 ++++++++++++++++++++++++++---
2 files changed, 136 insertions(+), 5 deletions(-)
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index 4b7bec74e89f..3ff89817e421 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -20,6 +20,7 @@
#include <linux/delay.h>
#include <linux/property.h>
#include <linux/string_helpers.h>
+#include <linux/trace.h>
#include "nhi.h"
#include "nhi_regs.h"
@@ -50,6 +51,19 @@ static bool host_reset = true;
module_param(host_reset, bool, 0444);
MODULE_PARM_DESC(host_reset, "reset USBv2 host router (default: true)");
+#ifdef CONFIG_TRACING
+/*
+ * __tb_debug_trace - enable debug logs to the thunderbolt tracefs instance
+ */
+bool __tb_debug_trace;
+EXPORT_SYMBOL(__tb_debug_trace);
+
+MODULE_PARM_DESC(trace, "enable debug logs to the thunderbolt tracefs instance (default: false) (bool)");
+module_param_named(trace, __tb_debug_trace, bool, 0600);
+
+static struct trace_array *trace_arr;
+#endif
+
static int ring_interrupt_index(const struct tb_ring *ring)
{
int bit = ring->hop;
@@ -1539,6 +1553,71 @@ static struct pci_driver nhi_driver = {
.driver.pm = &nhi_pm_ops,
};
+#ifdef CONFIG_TRACING
+
+/**
+ * tb_trace_init - initializes the thunderbolt trace array
+ *
+ * This function fetches (or creates) the thunderbolt trace array.
+ * This should be called once on thunderbolt subsystem creation
+ * and matched with tb_trace_cleanup().
+ */
+void tb_trace_init(void)
+{
+ int ret;
+
+ trace_arr = trace_array_get_by_name("thunderbolt");
+ if (!trace_arr)
+ return;
+
+ ret = trace_array_init_printk(trace_arr);
+ if (ret)
+ tb_trace_cleanup();
+}
+
+/**
+ * tb_trace_printf - adds an entry to the thunderbolt tracefs instance
+ * @format: printf format of the message to add to the trace
+ *
+ * This function adds a new entry in the thunderbolt tracefs instance
+ */
+void tb_trace_printf(const struct device *dev, const char *format, ...)
+{
+ struct va_format vaf;
+ va_list args;
+
+ va_start(args, format);
+ vaf.fmt = format;
+ vaf.va = &args;
+
+ if (dev)
+ trace_array_printk(trace_arr, _THIS_IP_, "%s %s: %pV",
+ dev_driver_string(dev), dev_name(dev),
+ &vaf);
+ else
+ trace_array_printk(trace_arr, _THIS_IP_,
+ "(NULL device *): %pV", &vaf);
+ va_end(args);
+}
+
+/**
+ * tb_trace_cleanup - destroys the thunderbolt trace array
+ *
+ * This function destroys the thunderbolt trace array created
+ * with tb_trace_init. This should be called once on thunderbolt
+ * subsystem close and matched with tb_trace_init().
+ */
+void tb_trace_cleanup(void)
+{
+ if (trace_arr) {
+ trace_array_put(trace_arr);
+ trace_array_destroy(trace_arr);
+ trace_arr = NULL;
+ }
+}
+
+#endif
+
static int __init nhi_init(void)
{
int ret;
@@ -1549,11 +1628,13 @@ static int __init nhi_init(void)
ret = pci_register_driver(&nhi_driver);
if (ret)
tb_domain_exit();
+ tb_trace_init();
return ret;
}
static void __exit nhi_unload(void)
{
+ tb_trace_cleanup();
pci_unregister_driver(&nhi_driver);
tb_domain_exit();
}
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 57a9b272cb94..3d874182b996 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -14,6 +14,7 @@
#include <linux/thunderbolt.h>
#include <linux/uuid.h>
#include <linux/bitfield.h>
+#include <linux/kern_levels.h>
#include "tb_regs.h"
#include "ctl.h"
@@ -685,11 +686,60 @@ static inline int tb_port_write(struct tb_port *port, const void *buffer,
length);
}
-#define tb_err(tb, fmt, arg...) dev_err(&(tb)->nhi->pdev->dev, fmt, ## arg)
-#define tb_WARN(tb, fmt, arg...) dev_WARN(&(tb)->nhi->pdev->dev, fmt, ## arg)
-#define tb_warn(tb, fmt, arg...) dev_warn(&(tb)->nhi->pdev->dev, fmt, ## arg)
-#define tb_info(tb, fmt, arg...) dev_info(&(tb)->nhi->pdev->dev, fmt, ## arg)
-#define tb_dbg(tb, fmt, arg...) dev_dbg(&(tb)->nhi->pdev->dev, fmt, ## arg)
+#ifdef CONFIG_TRACING
+extern bool __tb_debug_trace;
+
+void tb_trace_init(void);
+__printf(2, 3)
+void tb_trace_printf(const struct device *dev, const char *format, ...);
+void tb_trace_cleanup(void);
+
+static inline bool tb_dbg_trace_enabled(void)
+{
+ return unlikely(__tb_debug_trace);
+}
+
+#else
+static inline void tb_trace_init(void)
+{
+}
+
+__printf(2, 3)
+static inline void tb_trace_printf(const struct device *dev,
+ const char *format, ...)
+{
+}
+
+static inline void tb_trace_cleanup(void)
+{
+}
+
+static inline bool tb_dbg_trace_enabled(void)
+{
+ return 0;
+}
+#endif
+
+#define __LOG_TRACE_PRINT(log_func, tb, fmt, arg...) \
+ do { \
+ const struct device *dev = &(tb)->nhi->pdev->dev; \
+ \
+ log_func(dev, fmt, ## arg); \
+ \
+ if (tb_dbg_trace_enabled()) \
+ tb_trace_printf(dev, fmt, ## arg); \
+ } while (0)
+
+#define tb_err(tb, fmt, arg...) \
+ __LOG_TRACE_PRINT(dev_err, tb, fmt, ## arg)
+#define tb_WARN(tb, fmt, arg...) \
+ dev_WARN(&(tb)->nhi->pdev->dev, fmt, ## arg)
+#define tb_warn(tb, fmt, arg...) \
+ __LOG_TRACE_PRINT(dev_warn, tb, fmt, ## arg)
+#define tb_info(tb, fmt, arg...) \
+ __LOG_TRACE_PRINT(dev_info, tb, fmt, ## arg)
+#define tb_dbg(tb, fmt, arg...) \
+ __LOG_TRACE_PRINT(dev_dbg, tb, fmt, ## arg)
#define __TB_SW_PRINT(level, sw, fmt, arg...) \
do { \
--
2.41.0.487.g6d72f3e995-goog
next reply other threads:[~2023-07-27 13:15 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-27 13:13 Łukasz Bartosik [this message]
2023-07-27 13:13 ` [PATCH v1 2/2] thunderbolt: add tracefs support to dev_* logging helpers Łukasz Bartosik
2023-07-27 14:46 ` [PATCH v1 1/2] thunderbolt: add tracefs support to tb_* " Greg KH
2023-07-28 14:50 ` Łukasz Bartosik
2023-07-28 15:32 ` Greg KH
2023-07-28 15:49 ` Łukasz Bartosik
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=20230727131326.2282301-1-lb@semihalf.com \
--to=lb@semihalf.com \
--cc=YehezkelShB@gmail.com \
--cc=andreas.noever@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=michael.jamet@intel.com \
--cc=mika.westerberg@linux.intel.com \
--cc=upstream@semihalf.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