Add a target to print its debug information when lightnvm debug information is printed trough configure_debug. In rrpc, we add statistics on inflight reads and writes, as well as submitted and synced writes. Signed-off-by: Javier González <javier@xxxxxxxxxxxx> --- drivers/lightnvm/core.c | 10 +++++++++ drivers/lightnvm/rrpc.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/lightnvm/rrpc.h | 8 +++++++ include/linux/lightnvm.h | 4 ++++ 4 files changed, 79 insertions(+) diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index 5471cc5..ef64243 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -771,6 +771,8 @@ static int __nvm_configure_remove(struct nvm_ioctl_remove *remove) static int nvm_configure_show(const char *val) { struct nvm_dev *dev; + struct nvm_target *t = NULL; + struct nvm_tgt_type *tt; char opcode, devname[DISK_NAME_LEN]; int ret; @@ -793,6 +795,14 @@ static int nvm_configure_show(const char *val) dev->mt->lun_info_print(dev); + down_write(&nvm_lock); + list_for_each_entry(dev, &nvm_devices, devices) + list_for_each_entry(t, &dev->online_targets, list) { + tt = t->type; + tt->print_debug(t->disk->private_data); + } + up_write(&nvm_lock); + return 0; } diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c index 6348d52..41bd9b0 100644 --- a/drivers/lightnvm/rrpc.c +++ b/drivers/lightnvm/rrpc.c @@ -784,6 +784,11 @@ static void rrpc_sync_buffer(struct rrpc *rrpc, struct rrpc_addr *p) WARN_ON(test_and_set_bit((p->addr - bppa), buf->sync_bitmap)); +#ifdef CONFIG_NVM_DEBUG + atomic_dec(&rrpc->inflight_writes); + atomic_inc(&rrpc->sync_writes); +#endif + if (unlikely(bitmap_full(buf->sync_bitmap, buf->nentries))) { /* Write buffer out-of-bounds */ WARN_ON((buf->cur_mem != buf->nentries) && @@ -820,6 +825,9 @@ static void rrpc_end_io_read(struct rrpc *rrpc, struct nvm_rq *rqd, rrpc_unlock_rq(rrpc, rrqd); mempool_free(rrqd, rrpc->rrq_pool); +#ifdef CONFIG_NVM_DEBUG + atomic_sub(nr_pages, &rrpc->inflight_reads); +#endif } static void rrpc_end_io(struct nvm_rq *rqd) @@ -919,6 +927,11 @@ static int rrpc_write_ppalist_rq(struct rrpc *rrpc, struct bio *bio, rrqd->addr = p; +#ifdef CONFIG_NVM_DEBUG + atomic_inc(&rrpc->inflight_writes); + atomic_inc(&rrpc->req_writes); +#endif + err = rrpc_write_to_buffer(rrpc, bio, rrqd, p, w_buf, flags); if (err) { pr_err("rrpc: could not write to write buffer\n"); @@ -967,6 +980,11 @@ static int rrpc_write_rq(struct rrpc *rrpc, struct bio *bio, rrqd->addr = p; +#ifdef CONFIG_NVM_DEBUG + atomic_inc(&rrpc->inflight_writes); + atomic_inc(&rrpc->req_writes); +#endif + err = rrpc_write_to_buffer(rrpc, bio, rrqd, p, w_buf, flags); if (err) { pr_err("rrpc: could not write to write buffer\n"); @@ -1023,6 +1041,10 @@ static int rrpc_read_ppalist_rq(struct rrpc *rrpc, struct bio *bio, } brrqd[i].addr = gp; + +#ifdef CONFIG_NVM_DEBUG + atomic_inc(&rrpc->inflight_reads); +#endif } rqd->opcode = NVM_OP_HBREAD; @@ -1055,6 +1077,10 @@ static int rrpc_read_rq(struct rrpc *rrpc, struct bio *bio, struct nvm_rq *rqd, rqd->opcode = NVM_OP_HBREAD; rrqd->addr = gp; +#ifdef CONFIG_NVM_DEBUG + atomic_inc(&rrpc->inflight_reads); +#endif + return NVM_IO_OK; } @@ -1615,6 +1641,9 @@ submit_io: mempool_free(rqd, rrpc->rq_pool); bio_put(bio); } +#ifdef CONFIG_NVM_DEBUG + atomic_add(pgs_to_sync, &rrpc->sub_writes); +#endif } spin_unlock(&rlun->parent->lock); @@ -2128,6 +2157,14 @@ static void *rrpc_init(struct nvm_dev *dev, struct gendisk *tdisk, /* simple round-robin strategy */ atomic_set(&rrpc->next_lun, -1); +#ifdef CONFIG_NVM_DEBUG + atomic_set(&rrpc->inflight_writes, 0); + atomic_set(&rrpc->req_writes, 0); + atomic_set(&rrpc->sub_writes, 0); + atomic_set(&rrpc->sync_writes, 0); + atomic_set(&rrpc->inflight_reads, 0); +#endif + ret = rrpc_luns_init(rrpc, lun_begin, lun_end); if (ret) { pr_err("nvm: rrpc: could not initialize luns\n"); @@ -2182,6 +2219,24 @@ err: return ERR_PTR(ret); } +#ifdef CONFIG_NVM_DEBUG +static void rrpc_print_debug(void *private) +{ + struct rrpc *rrpc = private; + + pr_info("rrpc: %u\t%u\t%u\t%u\t%u\n", + atomic_read(&rrpc->inflight_writes), + atomic_read(&rrpc->inflight_reads), + atomic_read(&rrpc->req_writes), + atomic_read(&rrpc->sub_writes), + atomic_read(&rrpc->sync_writes)); +} +#else +static void rrpc_print_debug(void *private) +{ +} +#endif + /* round robin, page-based FTL, and cost-based GC */ static struct nvm_tgt_type tt_rrpc = { .name = "rrpc", @@ -2193,6 +2248,8 @@ static struct nvm_tgt_type tt_rrpc = { .init = rrpc_init, .exit = rrpc_exit, + + .print_debug = rrpc_print_debug, }; static int __init rrpc_module_init(void) diff --git a/drivers/lightnvm/rrpc.h b/drivers/lightnvm/rrpc.h index 6e188b4..b7c40de 100644 --- a/drivers/lightnvm/rrpc.h +++ b/drivers/lightnvm/rrpc.h @@ -167,6 +167,14 @@ struct rrpc { * to point to the next write lun */ +#ifdef CONFIG_NVM_DEBUG + atomic_t inflight_writes; + atomic_t req_writes; + atomic_t sub_writes; + atomic_t sync_writes; + atomic_t inflight_reads; +#endif + spinlock_t bio_lock; struct bio_list requeue_bios; struct work_struct ws_requeue; diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h index ae26ced..12a4296 100644 --- a/include/linux/lightnvm.h +++ b/include/linux/lightnvm.h @@ -428,6 +428,7 @@ typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *); typedef sector_t (nvm_tgt_capacity_fn)(void *); typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int); typedef void (nvm_tgt_exit_fn)(void *); +typedef void (nvm_tgt_print_debug_fn)(void *); struct nvm_tgt_type { const char *name; @@ -442,6 +443,9 @@ struct nvm_tgt_type { nvm_tgt_init_fn *init; nvm_tgt_exit_fn *exit; + /* debugging */ + nvm_tgt_print_debug_fn *print_debug; + /* For internal use */ struct list_head list; }; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-block" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html