Skip to content
Permalink
Browse files
vincents dd.c code
  • Loading branch information
jimc committed Nov 22, 2021
1 parent 9ba4504 commit 94cdbcf9aa003a6bf6cb4d302d391693422f9903
Showing 1 changed file with 132 additions and 28 deletions.
@@ -36,6 +36,7 @@
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/netdevice.h>
#include <trace/events/printk.h>

#include <rdma/ib_verbs.h>

@@ -91,6 +92,7 @@ static struct { unsigned flag:8; char opt_char; } opt_array[] = {
{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
{ _DPRINTK_FLAGS_INCL_TID, 't' },
{ _DPRINTK_FLAGS_TRACE, 'x' },
{ _DPRINTK_FLAGS_NONE, '_' },
};

@@ -628,6 +630,96 @@ static inline char *dynamic_emit_prefix(struct _ddebug *desc, char *buf)
return buf;
}

/*
* This code is heavily based on __ftrace_trace_stack().
*
* Allow 4 levels of nesting: normal, softirq, irq, NMI.
*/
#define DYNAMIC_TRACE_NESTING 4

struct dynamic_trace_buf {
char buf[256];
};

struct dynamic_trace_bufs {
struct dynamic_trace_buf bufs[DYNAMIC_TRACE_NESTING];
};

static DEFINE_PER_CPU(struct dynamic_trace_bufs, dynamic_trace_bufs);
static DEFINE_PER_CPU(int, dynamic_trace_reserve);

static void dynamic_trace(const char *fmt, va_list args)
{
struct dynamic_trace_buf *buf;
int bufidx;
int len;

preempt_disable_notrace();

bufidx = __this_cpu_inc_return(dynamic_trace_reserve) - 1;

if (WARN_ON_ONCE(bufidx > DYNAMIC_TRACE_NESTING))
goto out;

/* For the same reasons as in __ftrace_trace_stack(). */
barrier();

buf = this_cpu_ptr(dynamic_trace_bufs.bufs) + bufidx;

len = vscnprintf(buf->buf, sizeof(buf->buf), fmt, args);
trace_dyndbg(buf->buf, len);

out:
/* As above. */
barrier();
__this_cpu_dec(dynamic_trace_reserve);
preempt_enable_notrace();
}

static void dynamic_printk(unsigned int flags, const char *fmt, ...)
{
if (flags & _DPRINTK_FLAGS_TRACE) {
va_list args;

va_start(args, fmt);
/*
* All callers include the KERN_DEBUG prefix to keep the
* vprintk case simple; strip it out for tracing.
*/
dynamic_trace(fmt + strlen(KERN_DEBUG), args);
va_end(args);
}

if (flags & _DPRINTK_FLAGS_PRINTK) {
va_list args;

va_start(args, fmt);
vprintk(fmt, args);
va_end(args);
}
}

static void dynamic_dev_printk(unsigned int flags, const struct device *dev,
const char *fmt, ...)
{

if (flags & _DPRINTK_FLAGS_TRACE) {
va_list args;

va_start(args, fmt);
dynamic_trace(fmt, args);
va_end(args);
}

if (flags & _DPRINTK_FLAGS_PRINTK) {
va_list args;

va_start(args, fmt);
dev_vprintk_emit(LOGLEVEL_DEBUG, dev, fmt, args);
va_end(args);
}
}

void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
{
va_list args;
@@ -642,7 +734,8 @@ void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
vaf.fmt = fmt;
vaf.va = &args;

printk(KERN_DEBUG "%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
dynamic_printk(descriptor->flags, KERN_DEBUG "%s%pV",
dynamic_emit_prefix(descriptor, buf), &vaf);

va_end(args);
}
@@ -652,6 +745,7 @@ void __dynamic_dev_dbg(struct _ddebug *descriptor,
const struct device *dev, const char *fmt, ...)
{
struct va_format vaf;
unsigned int flags;
va_list args;

BUG_ON(!descriptor);
@@ -661,16 +755,18 @@ void __dynamic_dev_dbg(struct _ddebug *descriptor,

vaf.fmt = fmt;
vaf.va = &args;
flags = descriptor->flags;

if (!dev) {
printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
dynamic_printk(flags, KERN_DEBUG "(NULL device *): %pV",
&vaf);
} else {
char buf[PREFIX_SIZE] = "";

dev_printk_emit(LOGLEVEL_DEBUG, dev, "%s%s %s: %pV",
dynamic_emit_prefix(descriptor, buf),
dev_driver_string(dev), dev_name(dev),
&vaf);
dynamic_dev_printk(flags, dev, "%s%s %s: %pV",
dynamic_emit_prefix(descriptor, buf),
dev_driver_string(dev), dev_name(dev),
&vaf);
}

va_end(args);
@@ -683,6 +779,7 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,
const struct net_device *dev, const char *fmt, ...)
{
struct va_format vaf;
unsigned int flags;
va_list args;

BUG_ON(!descriptor);
@@ -692,22 +789,24 @@ void __dynamic_netdev_dbg(struct _ddebug *descriptor,

vaf.fmt = fmt;
vaf.va = &args;
flags = descriptor->flags;

if (dev && dev->dev.parent) {
char buf[PREFIX_SIZE] = "";

dev_printk_emit(LOGLEVEL_DEBUG, dev->dev.parent,
"%s%s %s %s%s: %pV",
dynamic_emit_prefix(descriptor, buf),
dev_driver_string(dev->dev.parent),
dev_name(dev->dev.parent),
netdev_name(dev), netdev_reg_state(dev),
&vaf);
dynamic_dev_printk(flags, dev->dev.parent,
"%s%s %s %s%s: %pV",
dynamic_emit_prefix(descriptor, buf),
dev_driver_string(dev->dev.parent),
dev_name(dev->dev.parent),
netdev_name(dev), netdev_reg_state(dev),
&vaf);
} else if (dev) {
printk(KERN_DEBUG "%s%s: %pV", netdev_name(dev),
netdev_reg_state(dev), &vaf);
} else {
printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
dynamic_printk(flags, KERN_DEBUG "%s%s: %pV",
netdev_name(dev), netdev_reg_state(dev), &vaf);
} else {
dynamic_printk(flags, KERN_DEBUG "(NULL net_device): %pV",
&vaf);
}

va_end(args);
@@ -723,29 +822,34 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
{
struct va_format vaf;
va_list args;
unsigned int flags;

va_start(args, fmt);

vaf.fmt = fmt;
vaf.va = &args;
flags = descriptor->flags;

if (ibdev && ibdev->dev.parent) {
char buf[PREFIX_SIZE] = "";

dev_printk_emit(LOGLEVEL_DEBUG, ibdev->dev.parent,
"%s%s %s %s: %pV",
dynamic_emit_prefix(descriptor, buf),
dev_driver_string(ibdev->dev.parent),
dev_name(ibdev->dev.parent),
dev_name(&ibdev->dev),
&vaf);
dynamic_dev_printk(flags, ibdev->dev.parent,
"%s%s %s %s: %pV",
dynamic_emit_prefix(descriptor, buf),
dev_driver_string(ibdev->dev.parent),
dev_name(ibdev->dev.parent),
dev_name(&ibdev->dev),
&vaf);

} else if (ibdev) {
printk(KERN_DEBUG "%s: %pV", dev_name(&ibdev->dev), &vaf);
} else {
printk(KERN_DEBUG "(NULL ib_device): %pV", &vaf);
dynamic_printk(flags, KERN_DEBUG "%s%s: %pV",
dev_name(&ibdev->dev), &vaf);
} else {
dynamic_printk(flags, KERN_DEBUG "(NULL ip_device): %pV",
&vaf);
}

va_end(args);
va_end(args);
}
EXPORT_SYMBOL(__dynamic_ibdev_dbg);

0 comments on commit 94cdbcf

Please sign in to comment.