/**
@file
@brief Debugging printing
@details Copyright (c) 2017-2021 Acronis International GmbH
@author Mikhail Krivtsov (mikhail.krivtsov@acronis.com)
@since $Id: $
*/
#pragma once
#ifndef KERNEL_MOCK
#include <asm/current.h> // struct task_struct *current
#include <linux/printk.h>
#include <linux/ratelimit.h> // __ratelimit()
#include <linux/sched.h> // struct task_struct
#include <linux/string.h> // strrchr()
#define xPRINTF(prefix, format, args...) \
do { \
const char *f = __FILE__; \
const char *n = strrchr(f, '/'); \
printk(PRINTK_TAG "|%5u:%5u:%s:%u:%s| " prefix format "\n", \
(unsigned)current->tgid, \
(unsigned)current->pid, \
(n) ? n+1 : f, __LINE__, __FUNCTION__, ##args); \
} while(0)
// in descending order of importance
#define FPRINTF(format, args...) xPRINTF("EMERGENCY: ", format, ##args)
#define APRINTF(format, args...) xPRINTF( "ALERT: ", format, ##args)
#define CPRINTF(format, args...) xPRINTF( "CRITICAL: ", format, ##args)
#define EPRINTF(format, args...) xPRINTF( "ERROR: ", format, ##args)
#define WPRINTF(format, args...) xPRINTF( "WARNING: ", format, ##args)
#define NPRINTF(format, args...) xPRINTF( "NOTICE: ", format, ##args)
#define IPRINTF(format, args...) xPRINTF( "INFO: ", format, ##args)
#ifdef __DEBUG__
#define DPRINTF(format, args...) xPRINTF( "DEBUG: ", format, ##args)
#else
#define DPRINTF(format, args...)
#endif
#ifdef __DEBUG_LEVEL__
typedef enum logger_log_level_e {
LOG_LEVEL_DEBUG1 = 0,
LOG_LEVEL_DEBUG2,
LOG_LEVEL_DEBUG3,
LOG_LEVEL_DEBUG4,
LOG_LEVEL_DEBUG5,
LOG_LEVEL_DEBUG6,
LOG_LEVEL_DEBUG7,
LOG_LEVEL_DEBUG8,
LOG_LEVEL_DEBUG9,
} logger_log_level_t;
extern unsigned int logger_debug_level;
#define xPRINTF_LEVEL(prefix, level, format, args...) \
do { \
if (__builtin_expect(logger_debug_level > level, true)){ \
const char *f = __FILE__; \
const char *n = strrchr(f, '/'); \
printk(PRINTK_TAG "|%5u:%5u:%s:%u:%s| " prefix format "\n", \
(unsigned)current->tgid, \
(unsigned)current->pid, \
(n) ? n+1 : f, __LINE__, __FUNCTION__, ##args); \
} \
} while(0)
#define DPRINTF_LEVEL(level, format, args...) xPRINTF_LEVEL( "DEBUG_LEVEL: ", level, format, ##args)
#else
#define DPRINTF_LEVEL(level, format, args...)
#endif
#define xPRINTF_RATELIMITED(prefix, format, args...) \
do { \
static DEFINE_RATELIMIT_STATE(ratelimit_state, \
DEFAULT_RATELIMIT_INTERVAL, \
DEFAULT_RATELIMIT_BURST); \
if (__ratelimit(&ratelimit_state)) \
xPRINTF(prefix, format, ##args); \
} while(0)
#define FPRINTF_RATELIMITED(format, args...) xPRINTF_RATELIMITED("EMERGENCY: ", format, ##args)
#define APRINTF_RATELIMITED(format, args...) xPRINTF_RATELIMITED( "ALERT: ", format, ##args)
#define CPRINTF_RATELIMITED(format, args...) xPRINTF_RATELIMITED( "CRITICAL: ", format, ##args)
#define EPRINTF_RATELIMITED(format, args...) xPRINTF_RATELIMITED( "ERROR: ", format, ##args)
#define WPRINTF_RATELIMITED(format, args...) xPRINTF_RATELIMITED( "WARNING: ", format, ##args)
#define NPRINTF_RATELIMITED(format, args...) xPRINTF_RATELIMITED( "NOTICE: ", format, ##args)
#define IPRINTF_RATELIMITED(format, args...) xPRINTF_RATELIMITED( "INFO: ", format, ##args)
#ifdef __DEBUG__
#define DPRINTF_RATELIMITED(format, args...) xPRINTF_RATELIMITED( "DEBUG: ", format, ##args)
#else
#define DPRINTF_RATELIMITED(format, args...)
#endif
#define HEX_DUMP(dump_prefix, addr, size) \
print_hex_dump(PRINTK_TAG "|", dump_prefix, DUMP_PREFIX_OFFSET, \
16, 1, addr, size, true)
#else // KERNEL_MOCK
#include "lib/debug.h"
#endif
|