diff options
Diffstat (limited to 'lwis_debug.c')
-rw-r--r-- | lwis_debug.c | 157 |
1 files changed, 106 insertions, 51 deletions
diff --git a/lwis_debug.c b/lwis_debug.c index 90eaaeb..5813476 100644 --- a/lwis_debug.c +++ b/lwis_debug.c @@ -320,70 +320,61 @@ static int generate_buffer_info(struct lwis_device *lwis_dev, char *buffer, size return 0; } -void lwis_debug_save_register_io_to_history(struct lwis_device *lwis_dev, - struct lwis_io_entry *entry, size_t access_size) +static int generate_register_io_history(struct lwis_device *lwis_dev, char *buffer, size_t buffer_size) { - lwis_dev->debug_info.io_entry_hist[lwis_dev->debug_info.cur_io_entry_hist_idx].io_entry = - *entry; - lwis_dev->debug_info.io_entry_hist[lwis_dev->debug_info.cur_io_entry_hist_idx].access_size = - access_size; - lwis_dev->debug_info.io_entry_hist[lwis_dev->debug_info.cur_io_entry_hist_idx] - .start_timestamp = ktime_to_ns(lwis_get_time()); - lwis_dev->debug_info.cur_io_entry_hist_idx++; - if (lwis_dev->debug_info.cur_io_entry_hist_idx >= IO_ENTRY_DEBUG_HISTORY_SIZE) { - lwis_dev->debug_info.cur_io_entry_hist_idx = 0; - } -} - -int lwis_debug_print_register_io_history(struct lwis_device *lwis_dev) -{ - int i, hist_idx; + /* Temporary buffer to be concatenated to the main buffer. */ + char tmp_buf[128] = {}; struct lwis_register_io_info *reg_io; + int i, hist_idx; - /* TODO(bian): Change dev_warn to print_to_log style. */ - dev_warn(lwis_dev->dev, "=== LWIS REGISTER IO INFO: %s ===", lwis_dev->name); - dev_warn(lwis_dev->dev, "Last register read/writes:\n"); + if (lwis_dev == NULL) { + pr_err("Unknown LWIS device pointer\n"); + return -EINVAL; + } + + scnprintf(buffer, buffer_size, "=== LWIS REGISTER IO INFO: %s ===\n", lwis_dev->name); + strlcat(buffer, "Last register read/writes:\n", buffer_size); hist_idx = lwis_dev->debug_info.cur_io_entry_hist_idx; for (i = 0; i < IO_ENTRY_DEBUG_HISTORY_SIZE; ++i) { reg_io = &lwis_dev->debug_info.io_entry_hist[hist_idx]; /* Skip uninitialized entries */ if (reg_io->start_timestamp != 0) { if (reg_io->io_entry.type == LWIS_IO_ENTRY_READ) { - dev_warn( - lwis_dev->dev, - "READ: bid %d, offset %llu, val %llu, access_size %lu, start_timestamp %llu\n", - reg_io->io_entry.rw.bid, reg_io->io_entry.rw.offset, - reg_io->io_entry.rw.val, reg_io->access_size, - reg_io->start_timestamp); + scnprintf(tmp_buf, sizeof(tmp_buf), + "READ: bid %d, offset %llu, val %llu, access_size %lu, start_timestamp %llu\n", + reg_io->io_entry.rw.bid, reg_io->io_entry.rw.offset, + reg_io->io_entry.rw.val, reg_io->access_size, + reg_io->start_timestamp); + strlcat(buffer, tmp_buf, buffer_size); } else if (reg_io->io_entry.type == LWIS_IO_ENTRY_READ_BATCH) { - dev_warn( - lwis_dev->dev, - "READ_BATCH: bid %d, offset %llu, size_in_bytes %lu, access_size %lu, start_timestamp %llu\n", - reg_io->io_entry.rw_batch.bid, - reg_io->io_entry.rw_batch.offset, - reg_io->io_entry.rw_batch.size_in_bytes, - reg_io->access_size, reg_io->start_timestamp); + scnprintf(tmp_buf, sizeof(tmp_buf), + "READ_BATCH: bid %d, offset %llu, size_in_bytes %lu, access_size %lu, start_timestamp %llu\n", + reg_io->io_entry.rw_batch.bid, + reg_io->io_entry.rw_batch.offset, + reg_io->io_entry.rw_batch.size_in_bytes, + reg_io->access_size, reg_io->start_timestamp); + strlcat(buffer, tmp_buf, buffer_size); } else if (reg_io->io_entry.type == LWIS_IO_ENTRY_WRITE) { - dev_warn( - lwis_dev->dev, - "WRITE: bid %d, offset %llu, val %llu, access_size %lu, start_timestamp %llu\n", - reg_io->io_entry.rw.bid, reg_io->io_entry.rw.offset, - reg_io->io_entry.rw.val, reg_io->access_size, - reg_io->start_timestamp); + scnprintf(tmp_buf, sizeof(tmp_buf), + "WRITE: bid %d, offset %llu, val %llu, access_size %lu, start_timestamp %llu\n", + reg_io->io_entry.rw.bid, reg_io->io_entry.rw.offset, + reg_io->io_entry.rw.val, reg_io->access_size, + reg_io->start_timestamp); + strlcat(buffer, tmp_buf, buffer_size); } else if (reg_io->io_entry.type == LWIS_IO_ENTRY_WRITE_BATCH) { - dev_warn( - lwis_dev->dev, - "WRITE_BATCH: bid %d, offset %llu, size_in_bytes %lu, access_size %lu, start_timestamp %llu\n", - reg_io->io_entry.rw_batch.bid, - reg_io->io_entry.rw_batch.offset, - reg_io->io_entry.rw_batch.size_in_bytes, - reg_io->access_size, reg_io->start_timestamp); + scnprintf(tmp_buf, sizeof(tmp_buf), + "WRITE_BATCH: bid %d, offset %llu, size_in_bytes %lu, access_size %lu, start_timestamp %llu\n", + reg_io->io_entry.rw_batch.bid, + reg_io->io_entry.rw_batch.offset, + reg_io->io_entry.rw_batch.size_in_bytes, + reg_io->access_size, reg_io->start_timestamp); + strlcat(buffer, tmp_buf, buffer_size); } else if (reg_io->io_entry.type == LWIS_IO_ENTRY_MODIFY) { - dev_warn( - lwis_dev->dev, - "MODIFY: bid %d, offset %llu, access_size %lu, start_timestamp %llu\n", - reg_io->io_entry.mod.bid, reg_io->io_entry.mod.offset, - reg_io->access_size, reg_io->start_timestamp); + scnprintf(tmp_buf, sizeof(tmp_buf), + "MODIFY: bid %d, offset %llu, access_size %lu, start_timestamp %llu\n", + reg_io->io_entry.mod.bid, reg_io->io_entry.mod.offset, + reg_io->access_size, reg_io->start_timestamp); + strlcat(buffer, tmp_buf, buffer_size); } } hist_idx++; @@ -395,6 +386,29 @@ int lwis_debug_print_register_io_history(struct lwis_device *lwis_dev) return 0; } +int lwis_debug_print_register_io_history(struct lwis_device *lwis_dev) +{ + int ret = 0; + /* Buffer to store information */ + const size_t buffer_size = 10240; + char *buffer = kzalloc(buffer_size, GFP_KERNEL); + if (!buffer) { + dev_err(lwis_dev->dev, "Failed to allocate register io history log buffer\n"); + return -ENOMEM; + } + + ret = generate_register_io_history(lwis_dev, buffer, buffer_size); + if (ret) { + dev_err(lwis_dev->dev, "Failed to generate register io history"); + goto exit; + } + print_to_log(buffer); + +exit: + kfree(buffer); + return 0; +} + int lwis_debug_print_device_info(struct lwis_device *lwis_dev) { int ret = 0; @@ -571,6 +585,31 @@ exit: return ret; } +static ssize_t register_io_history_read(struct file *fp, char __user *user_buf, size_t count, + loff_t *position) +{ + int ret = 0; + /* Buffer to store information */ + const size_t buffer_size = 10240; + struct lwis_device *lwis_dev = fp->f_inode->i_private; + char *buffer = kzalloc(buffer_size, GFP_KERNEL); + if (!buffer) { + dev_err(lwis_dev->dev, "Failed to allocate register io history log buffer\n"); + return -ENOMEM; + } + + ret = generate_register_io_history(lwis_dev, buffer, buffer_size); + if (ret) { + dev_err(lwis_dev->dev, "Failed to generate register io history"); + goto exit; + } + + ret = simple_read_from_buffer(user_buf, count, position, buffer, strlen(buffer)); +exit: + kfree(buffer); + return ret; +} + static struct file_operations dev_info_fops = { .owner = THIS_MODULE, .read = dev_info_read, @@ -591,6 +630,11 @@ static struct file_operations buffer_info_fops = { .read = buffer_info_read, }; +static struct file_operations register_io_history_fops = { + .owner = THIS_MODULE, + .read = register_io_history_read, +}; + int lwis_device_debugfs_setup(struct lwis_device *lwis_dev, struct dentry *dbg_root) { struct dentry *dbg_dir; @@ -598,6 +642,7 @@ int lwis_device_debugfs_setup(struct lwis_device *lwis_dev, struct dentry *dbg_r struct dentry *dbg_event_file; struct dentry *dbg_transaction_file; struct dentry *dbg_buffer_file; + struct dentry *dbg_reg_io_file; /* DebugFS not present, just return */ if (dbg_root == NULL) { @@ -643,11 +688,20 @@ int lwis_device_debugfs_setup(struct lwis_device *lwis_dev, struct dentry *dbg_r dbg_buffer_file = NULL; } + dbg_reg_io_file = + debugfs_create_file("io_history", 0444, dbg_dir, lwis_dev, ®ister_io_history_fops); + if (IS_ERR_OR_NULL(dbg_reg_io_file)) { + dev_warn(lwis_dev->dev, "Failed to create DebugFS io_history - %ld", + PTR_ERR(dbg_reg_io_file)); + dbg_reg_io_file = NULL; + } + lwis_dev->dbg_dir = dbg_dir; lwis_dev->dbg_dev_info_file = dbg_dev_info_file; lwis_dev->dbg_event_file = dbg_event_file; lwis_dev->dbg_transaction_file = dbg_transaction_file; lwis_dev->dbg_buffer_file = dbg_buffer_file; + lwis_dev->dbg_reg_io_file = dbg_reg_io_file; return 0; } @@ -664,6 +718,7 @@ int lwis_device_debugfs_cleanup(struct lwis_device *lwis_dev) lwis_dev->dbg_event_file = NULL; lwis_dev->dbg_transaction_file = NULL; lwis_dev->dbg_buffer_file = NULL; + lwis_dev->dbg_reg_io_file = NULL; return 0; } |