anolis: sw64: improve sw64_rrk
ANBZ: #4688 Implement an improved sw64_rrk which stores the timestamp and loglevel. Signed-off-by: Mao Minkai <maominkai@wxiat.com> Reviewed-by: He Sheng <hesheng@wxiat.com> Signed-off-by: Gu Zitao <guzitao@wxiat.com> Reviewed-by: Min Li <gumi@linux.alibaba.com> Link: https://gitee.com/anolis/cloud-kernel/pulls/5372
This commit is contained in:
parent
d4872090ae
commit
cc583d3b7a
|
@ -12,33 +12,88 @@
|
|||
|
||||
static DEFINE_SPINLOCK(printk_lock);
|
||||
|
||||
unsigned long sw64_printk_offset;
|
||||
static unsigned long sw64_printk_offset;
|
||||
#define PRINTK_SIZE 0x100000UL
|
||||
|
||||
void sw64_printk(const char *fmt, va_list args)
|
||||
static bool rrk_last_newline_end;
|
||||
static unsigned long rrk_last_id;
|
||||
static const char * const level_str[] = {
|
||||
"(0)EMERG",
|
||||
"(1)ALERT",
|
||||
"(2)CRIT",
|
||||
"(3)ERR",
|
||||
"(4)WARNING",
|
||||
"(5)NOTICE",
|
||||
"(6)INFO",
|
||||
"(7)DEBUG"
|
||||
};
|
||||
#define LEVEL_STR_MAX_LEN 10 // length of "(4)WARNING"
|
||||
|
||||
void sw64_rrk_store(const char *text, u16 text_len, u64 ts_nsec, int level,
|
||||
unsigned long id, bool newline_end)
|
||||
{
|
||||
char *sw64_printk_buf;
|
||||
unsigned long flags;
|
||||
char textbuf[1024];
|
||||
const char *text;
|
||||
size_t text_len;
|
||||
size_t __maybe_unused rrk_len;
|
||||
char header_buf[128];
|
||||
/* same time fmt as print_time() in printk.c */
|
||||
char header_fmt[] = "[%5llu.%06llu %-"__stringify(LEVEL_STR_MAX_LEN)"s] ";
|
||||
size_t header_len;
|
||||
char *newline;
|
||||
/* if writing a new entry while the last one did not end with '\n', print '\n' first */
|
||||
bool newline_first = rrk_last_id && (rrk_last_id != id) && (!rrk_last_newline_end);
|
||||
bool wrap = false;
|
||||
unsigned long max_offset_allowed;
|
||||
|
||||
spin_lock_irqsave(&printk_lock, flags);
|
||||
|
||||
sw64_printk_buf = (char *)(KERNEL_PRINTK_BUFF_BASE + sw64_printk_offset);
|
||||
header_len = scnprintf(header_buf, sizeof(header_buf), header_fmt,
|
||||
ts_nsec / NSEC_PER_SEC, (ts_nsec % NSEC_PER_SEC) / NSEC_PER_USEC,
|
||||
level >= 0 ? level_str[level] : "CONT");
|
||||
|
||||
text_len = vscnprintf(textbuf, sizeof(textbuf), fmt, args);
|
||||
text = printk_skip_headers(textbuf);
|
||||
text_len -= text - textbuf;
|
||||
|
||||
if (sw64_printk_offset >= (PRINTK_SIZE - 1024)) {
|
||||
max_offset_allowed = PRINTK_SIZE - text_len - header_len - (newline_first ? 1 : 0);
|
||||
if (unlikely(sw64_printk_offset >= max_offset_allowed)) {
|
||||
sw64_printk_offset = 0;
|
||||
sw64_printk_buf = (char *)(KERNEL_PRINTK_BUFF_BASE + sw64_printk_offset);
|
||||
memset(sw64_printk_buf, 0, PRINTK_SIZE);
|
||||
wrap = true;
|
||||
}
|
||||
sw64_printk_buf = (char *)(KERNEL_PRINTK_BUFF_BASE + sw64_printk_offset);
|
||||
|
||||
if (unlikely(newline_first)) {
|
||||
sw64_printk_buf[0] = '\n';
|
||||
sw64_printk_buf++;
|
||||
sw64_printk_offset++;
|
||||
}
|
||||
|
||||
if (likely(level != -1) || unlikely(wrap)) {
|
||||
memcpy(sw64_printk_buf, header_buf, header_len);
|
||||
sw64_printk_offset += header_len;
|
||||
sw64_printk_buf += header_len;
|
||||
}
|
||||
|
||||
while (unlikely((newline = strnchr(text, text_len, '\n')))) {
|
||||
size_t len;
|
||||
|
||||
/* copy the first line */
|
||||
newline++;
|
||||
len = newline - text;
|
||||
memcpy(sw64_printk_buf, text, len);
|
||||
|
||||
/* add padding for next line */
|
||||
memset(&sw64_printk_buf[len], ' ', header_len);
|
||||
|
||||
text += len;
|
||||
text_len -= len;
|
||||
sw64_printk_buf += len + header_len;
|
||||
sw64_printk_offset += len + header_len;
|
||||
}
|
||||
|
||||
memcpy(sw64_printk_buf, text, text_len);
|
||||
sw64_printk_offset += text_len;
|
||||
if (likely(sw64_printk_buf[text_len - 1] != '\n' && newline_end)) {
|
||||
sw64_printk_buf[text_len] = '\n';
|
||||
sw64_printk_offset++;
|
||||
}
|
||||
|
||||
if (is_in_emul()) {
|
||||
void __iomem *addr = __va(QEMU_PRINTF_BUFF_BASE);
|
||||
|
@ -47,6 +102,9 @@ void sw64_printk(const char *fmt, va_list args)
|
|||
*(u64 *)addr = data;
|
||||
}
|
||||
|
||||
rrk_last_id = id;
|
||||
rrk_last_newline_end = newline_end;
|
||||
|
||||
spin_unlock_irqrestore(&printk_lock, flags);
|
||||
}
|
||||
#endif
|
||||
|
@ -55,8 +113,8 @@ void sw64_printk(const char *fmt, va_list args)
|
|||
#include <linux/uaccess.h>
|
||||
|
||||
static DEFINE_SPINLOCK(printf_lock);
|
||||
#define USER_PRINT_BUFF_BASE (0x600000UL + __START_KERNEL_map)
|
||||
#define USER_PRINT_BUFF_LEN 0x100000UL
|
||||
#define USER_PRINT_BUFF_BASE (0x600000UL + __START_KERNEL_map)
|
||||
#define USER_PRINT_BUFF_LEN 0x100000UL
|
||||
#define USER_MESSAGE_MAX_LEN 0x100000UL
|
||||
unsigned long sw64_printf_offset;
|
||||
int sw64_user_printf(const char __user *buf, int len)
|
||||
|
|
|
@ -504,6 +504,10 @@ static void truncate_msg(u16 *text_len, u16 *trunc_msg_len)
|
|||
*trunc_msg_len = 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SW64_RRK
|
||||
extern void sw64_rrk_store(const char *text, u16 text_len, u64 ts_nsec, int level,
|
||||
unsigned long id, bool final);
|
||||
#endif
|
||||
/* insert record into the buffer, discard old ones, update heads */
|
||||
static int log_store(u32 caller_id, int facility, int level,
|
||||
enum log_flags flags, u64 ts_nsec,
|
||||
|
@ -547,6 +551,11 @@ static int log_store(u32 caller_id, int facility, int level,
|
|||
else
|
||||
prb_final_commit(&e);
|
||||
|
||||
#ifdef CONFIG_SW64_RRK
|
||||
sw64_rrk_store(&r.text_buf[0], r.info->text_len, r.info->ts_nsec, r.info->level,
|
||||
e.id, !!(flags & LOG_NEWLINE));
|
||||
#endif
|
||||
|
||||
return (text_len + trunc_msg_len);
|
||||
}
|
||||
|
||||
|
@ -1974,6 +1983,10 @@ static size_t log_output(int facility, int level, enum log_flags lflags,
|
|||
} else {
|
||||
prb_commit(&e);
|
||||
}
|
||||
#ifdef CONFIG_SW64_RRK
|
||||
sw64_rrk_store(text, text_len, r.info->ts_nsec, -1,
|
||||
e.id, !!(lflags & LOG_NEWLINE));
|
||||
#endif
|
||||
return text_len;
|
||||
}
|
||||
}
|
||||
|
@ -1993,11 +2006,6 @@ int vprintk_store(int facility, int level,
|
|||
size_t text_len;
|
||||
enum log_flags lflags = 0;
|
||||
|
||||
#ifdef CONFIG_SW64_RRK
|
||||
extern void sw64_printk(const char *fmt, va_list args);
|
||||
sw64_printk(fmt, args);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The printf needs to come first; we need the syslog
|
||||
* prefix which might be passed-in as a parameter.
|
||||
|
|
Loading…
Reference in New Issue