/*
- * drivers/misc/zlogger.c
+ * kernel/zlogger/zlogger.c
*
- * A Logging Subsystem for Tizen TV
+ * Zero-copy logging for Tizen
*
- * Copyright (C) 2021 Samsung Electronics Co., Ltd
+ * Copyright (C) 2022 Samsung Electronics Co., Ltd
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
#define ZLOG_FD_BUFER (2 * ZLOGGER_MB)
-struct thread_t {
- uint16_t block;
-};
-
-struct queue_t {
+struct queue {
char name[5];
uint16_t front;
uint16_t rear;
};
// taken from dlog.h
-typedef enum {
+enum log_priority {
DLOG_UNKNOWN = 0, /**< Keep this always at the start */
DLOG_DEFAULT, /**< Default */
DLOG_VERBOSE, /**< Verbose */
DLOG_FATAL, /**< Fatal */
DLOG_SILENT, /**< Silent */
DLOG_PRIO_MAX /**< Keep this always at the end. */
-} log_priority;
+};
-/*zlogger file channel */
+/* zlogger file channel */
#define LOG_BUFFER_SIZE 512
-const char default_tag[] = "STDOUT";
-typedef struct {
+static const char default_tag[] = "STDOUT";
+struct zlog_file {
char prio;
char tag[ZLOGGER_TAG_MAX];
char msg[ZLOGGER_MSG_MAX];
char *buffer;
size_t buffer_len;
-} zlog_file_t;
+};
-/*--zlogger file channel*/
+/* --zlogger file channel */
static struct miscdevice zlogger_device;
static struct mutex g_block_mutex;
static struct mutex g_task_mutex;
-static struct queue_t g_free_q;
+static struct queue g_free_q;
static int g_max_thread_id;
static int g_zlog_enable = 1;
module_param_named(zlog_enable, g_zlog_enable, int, 0644);
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0))
+#if (KERNEL_VERSION(3, 17, 0) > LINUX_VERSION_CODE)
static inline u64 ktime_get_ns(void)
{
return ktime_to_ns(ktime_get());
return 0;
hash_for_each_possible(g_thread_table->data, ptr, next, tid) {
- if (ptr->tid == tid && ptr->is_stdout == is_stdout) {
+ if (ptr->tid == tid && ptr->is_stdout == is_stdout)
return ptr->blk;
- }
}
return 0;
return (struct zlogger_block *)(p + (offset * ZLOGGER_BLOCK_SIZE));
}
-static inline void queue_init(struct queue_t *q, const char *name, uint16_t capacity)
+static inline void queue_init(struct queue *q, const char *name, uint16_t capacity)
{
snprintf(q->name, sizeof(q->name), "%s", name);
q->front = 0;
q->rear = capacity - 1;
q->count = 0;
q->capacity = capacity;
- q->values = kzalloc(capacity * sizeof(uint16_t), GFP_KERNEL);
+ q->values = kcalloc(capacity, sizeof(uint16_t), GFP_KERNEL);
}
-static inline void queue_deinit(struct queue_t *q)
+static inline void queue_deinit(struct queue *q)
{
- if (q->values)
- kfree(q->values);
+ kfree(q->values);
+ q->values = NULL;
}
-static inline uint16_t queue_pop(struct queue_t *q)
+static inline uint16_t queue_pop(struct queue *q)
{
uint16_t r;
return r;
}
-static inline void queue_push(struct queue_t *q, uint16_t value)
+static inline void queue_push(struct queue *q, uint16_t value)
{
if (q->count >= q->capacity) {
pr_info("[%s] Queue is full", q->name);
static int zlogger_open(struct inode *inode, struct file *file)
{
int ret = nonseekable_open(inode, file);
+
if (ret)
return ret;
file->private_data = NULL;
static int zlogger_release(struct inode *ignored, struct file *file)
{
if (file->private_data != NULL) {
- zlog_file_t *zlog_file_data = (zlog_file_t *)file->private_data;
+ struct zlog_file *zlog_file_data = (struct zlog_file *)file->private_data;
if (zlog_file_data->buffer != NULL) {
kfree(zlog_file_data->buffer);
static ssize_t init_file_zlog_tag_data(struct file *filep)
{
- zlog_file_t *zlog_file_data = kmalloc(sizeof(zlog_file_t), GFP_KERNEL);
- if (!zlog_file_data) {
- pr_err("init_zlog_tag_data: no memory \n");
+ struct zlog_file *zlog_file_data = kmalloc(sizeof(struct zlog_file), GFP_KERNEL);
+
+ if (!zlog_file_data)
return -ENOMEM;
- }
zlog_file_data->buffer = NULL;
memcpy(zlog_file_data->tag, default_tag, sizeof(default_tag) - 1);
zlog_file_data->tag[sizeof(default_tag) - 1] = '\0';
return 0;
}
-int update_zlog_data_buffer_size(zlog_file_t *zlog_file_data, size_t len)
+int update_zlog_data_buffer_size(struct zlog_file *zlog_file_data, size_t len)
{
char *new_buffer = kmalloc(len, GFP_KERNEL);
+
if (!new_buffer)
return -ENOMEM;
kfree(zlog_file_data->buffer);
struct zlogger_entry tmp;
if (block == NULL) {
- pr_err("_zlog_write: no memory\n");
+ pr_err("%s: no block available\n", __func__);
return -ENOMEM;
}
return (int)entry_size;
}
-static void endl_to_zero(zlog_file_t *zlog_file_data, size_t len)
+static void endl_to_zero(struct zlog_file *zlog_file_data, size_t len)
{
- char *cb = (char*)zlog_file_data->buffer;
- while(cb < (char*)zlog_file_data->buffer + len) {
- if(*cb == '\n') {
+ char *cb = (char *)zlog_file_data->buffer;
+
+ while (cb < (char *)zlog_file_data->buffer + len) {
+ if (*cb == '\n')
*cb = '\0';
- }
cb++;
}
}
-static ssize_t partition_write_buffer(zlog_file_t *zlog_file_data, size_t len)
+static ssize_t partition_write_buffer(struct zlog_file *zlog_file_data, size_t len)
{
- char *cb = (char*)zlog_file_data->buffer;
- char *buffer = (char*)zlog_file_data->buffer;
+ char *cb = (char *)zlog_file_data->buffer;
+ char *buffer = (char *)zlog_file_data->buffer;
endl_to_zero(zlog_file_data, len);
- while(cb < buffer + len ) {
+ while (cb < buffer + len) {
+ int res;
- if(*cb == '\0' && cb < buffer + len ) {
+ if (*cb == '\0' && cb < buffer + len) {
cb++;
continue;
}
-
- int res = _zlog_write((const unsigned char)zlog_file_data->prio, (const char *)&zlog_file_data->tag, (const char *)cb);
- if(res < 0) {
+ res = _zlog_write((const unsigned char)zlog_file_data->prio, (const char *)&zlog_file_data->tag, (const char *)cb);
+ if (res < 0) {
pr_err("_zlog_write failed\n");
return -EFAULT;
}
- if(cb < buffer + len) {
+ if (cb < buffer + len)
cb += strnlen(cb, len - (cb - buffer));
- }
}
return 0;
}
static ssize_t zlogger_write(struct file *filep, const char *buffer, size_t len, loff_t *offset)
{
- if( (!filep->private_data ) && init_file_zlog_tag_data(filep)) {
- pr_err("zlogger_write init zlog tag data failed\n");
+ struct zlog_file *zlog_file_data;
+ unsigned long copied;
+ ssize_t res;
+
+ if ((!filep->private_data) && init_file_zlog_tag_data(filep)) {
+ pr_err("init_file_zlog_tag_data failed\n");
return -ENOMEM;
}
- zlog_file_t *zlog_file_data = (zlog_file_t *)filep->private_data;
+ zlog_file_data = (struct zlog_file *)filep->private_data;
if (len > zlog_file_data->buffer_len && !update_zlog_data_buffer_size(zlog_file_data, len)) {
pr_err("update_zlog_data_buffer_size failed\n");
return -ENOMEM;
}
- unsigned long copied = copy_from_user(zlog_file_data->buffer, buffer, len);
+ copied = copy_from_user(zlog_file_data->buffer, buffer, len);
- if(copied != 0) {
+ if (copied != 0) {
pr_err("copy_from_user failed\n");
return -EFAULT;
}
- ssize_t res = partition_write_buffer(zlog_file_data, len);
- if(res < 0) {
+ res = partition_write_buffer(zlog_file_data, len);
+ if (res < 0) {
pr_err("partition_write_buffer failed\n");
return -EFAULT;
}
return len;
}
-static long update_prio(zlog_file_t *zlog_file_data, void __user *argp)
+static long update_prio(struct zlog_file *zlog_file_data, void __user *argp)
{
char prio;
prio = (char)(uintptr_t)argp;
- if (prio < (char)DLOG_DEFAULT || prio >=DLOG_PRIO_MAX) {
+ if (prio < (char)DLOG_DEFAULT || prio >= DLOG_PRIO_MAX)
return -EINVAL;
- }
zlog_file_data->prio = prio;
return 0;
static long zlogger_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
+ void __user *argp;
+ struct zlog_file *zlog_file_data;
+
if (cmd == ZLOGGER_IOCTL_COMMAND_ALLOC)
return alloc_block_for_thread(false);
- #ifdef CONFIG_COMPAT
- void __user *argp = compat_ptr(arg);
- #else
- void __user *argp = (void __user *)arg;
- #endif
+#ifdef CONFIG_COMPAT
+ argp = compat_ptr(arg);
+#else
+ argp = (void __user *)arg;
+#endif
if (cmd == ZLOGGER_IOCTL_COMMAND_SET_DEFAULT_PRIORITY) {
- if( (!file->private_data ) && init_file_zlog_tag_data(file)) {
+ if ((!file->private_data) && init_file_zlog_tag_data(file)) {
pr_err("zlogger_write init zlog tag data failed\n");
return -ENOMEM;
}
- zlog_file_t *zlog_file_data = (zlog_file_t *)file->private_data;
+ zlog_file_data = (struct zlog_file *)file->private_data;
return update_prio(zlog_file_data, argp);
}
- if(cmd == ZLOGGER_IOCTL_COMMAND_SET_DEFAULT_TAG) {
- if( (!file->private_data ) && init_file_zlog_tag_data(file)) {
+ if (cmd == ZLOGGER_IOCTL_COMMAND_SET_DEFAULT_TAG) {
+ if ((!file->private_data) && init_file_zlog_tag_data(file)) {
pr_err("zlogger_write init zlog tag data failed\n");
return -ENOMEM;
}
- zlog_file_t *zlog_file_data = (zlog_file_t *)file->private_data;
+ zlog_file_data = (struct zlog_file *)file->private_data;
return copy_from_user(&zlog_file_data->tag, (char *)(uintptr_t)argp, strnlen((char *)(uintptr_t)argp, ZLOGGER_TAG_MAX));
}
for (i = 0; i < g_max_thread_id; i++) {
for (is_stdout = 0; is_stdout <= 1; ++is_stdout) {
if (get_thread_table(i, is_stdout) > 0)
- thread_count ++;
+ thread_count++;
}
}
return 0;
out_free_g_thread_table_g_shm_ptr:
- for (i = 0; i < g_shm_ptr_i; ++i){
+ for (i = 0; i < g_shm_ptr_i; ++i) {
kfree(g_shm_ptr[i]);
g_shm_ptr[i] = NULL;
}
g_shm_ptr[i] = NULL;
}
-
-
g_init = 0;
sysfs_remove_group(&zlogger_device.this_device->kobj, &zlogger_attr_group);
+/*
+ * tests/zlog_stdout/zlog_stdout.c
+ *
+ * Zero-copy logging for Tizen
+ *
+ * Copyright (C) 2022 Samsung Electronics Co., Ltd
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
DLOG_PRIO_MAX /**< Keep this always at the end. */
} log_priority;
-static const char* prio_default = "Prio: DEFAULT\n";
-static const char* prio_verbose = "Prio: VERBOSE\n";
-static const char* prio_debug = "Prio: DEBUG\n";
-static const char* prio_info = "Prio: INFO\n";
-static const char* prio_warn = "Prio: WARN\n";
-static const char* prio_error = "Prio: ERROR\n";
-static const char* prio_fatal = "Prio: FATAL\n";
-static const char* prio_silent = "Prio: SILENT\n";
+static const char *prio_default = "Prio: DEFAULT\n";
+static const char *prio_verbose = "Prio: VERBOSE\n";
+static const char *prio_debug = "Prio: DEBUG\n";
+static const char *prio_info = "Prio: INFO\n";
+static const char *prio_warn = "Prio: WARN\n";
+static const char *prio_error = "Prio: ERROR\n";
+static const char *prio_fatal = "Prio: FATAL\n";
+static const char *prio_silent = "Prio: SILENT\n";
-static const char* test_message = "A test message\n";
+static const char *test_message = "A test message\n";
int main(int argc, char *argv[])
{
+ int fd;
+
printf("Simple zlog test!\n");
printf("see at zlogutil messages\n");
- int fd = open("/dev/zlogger", O_RDWR);
+
+ fd = open("/dev/zlogger", O_RDWR);
if (fd < 0) {
printf("Error opening zlog device\n");
return -1;