2018-08-29 12:32:58

by Hans Holmberg

[permalink] [raw]
Subject: [PATCH 0/4] Introduce trace events for pblk

From: Hans Holmberg <[email protected]>

This patchset adds trace events for tracking the internal state of
pblk. I've used the events extensively the last few months, and
they have proven very useful.

The patches depend on some of Javier's for-4.20 patches.
For ordering, see:

Branch: for-4.20/pblk
Remote: ssh://github.com/OpenChannelSSD/linux

Hans Holmberg (4):
lightnvm: pblk: add trace events for chunk states
lightnvm: pblk: add trace events for line state changes
lightnvm: pblk: add trace events for pblk state changes
lightnvm: pblk: add tracing for chunk resets

drivers/lightnvm/pblk-core.c | 69 ++++++++++++++++++-
drivers/lightnvm/pblk-gc.c | 8 +++
drivers/lightnvm/pblk-init.c | 8 +++
drivers/lightnvm/pblk-recovery.c | 6 ++
drivers/lightnvm/pblk-trace.h | 145 +++++++++++++++++++++++++++++++++++++++
drivers/lightnvm/pblk-write.c | 10 ++-
drivers/lightnvm/pblk.h | 14 ++++
7 files changed, 256 insertions(+), 4 deletions(-)
create mode 100644 drivers/lightnvm/pblk-trace.h

--
2.7.4



2018-08-29 12:33:02

by Hans Holmberg

[permalink] [raw]
Subject: [PATCH 4/4] lightnvm: pblk: add tracing for chunk resets

From: Hans Holmberg <[email protected]>

Trace state of chunk resets.

Signed-off-by: Hans Holmberg <[email protected]>
---
drivers/lightnvm/pblk-core.c | 12 ++++++++++++
drivers/lightnvm/pblk-trace.h | 31 +++++++++++++++++++++++++++++++
drivers/lightnvm/pblk.h | 6 ++++++
3 files changed, 49 insertions(+)

diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index 566a5d3165ee..b874001d1175 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -90,9 +90,15 @@ static void __pblk_end_io_erase(struct pblk *pblk, struct nvm_rq *rqd)
atomic_dec(&line->left_seblks);

if (rqd->error) {
+ trace_pblk_chunk_reset(pblk_disk_name(pblk),
+ &rqd->ppa_addr, PBLK_CHUNK_RESET_FAILED);
+
chunk->state = NVM_CHK_ST_OFFLINE;
pblk_mark_bb(pblk, line, rqd->ppa_addr);
} else {
+ trace_pblk_chunk_reset(pblk_disk_name(pblk),
+ &rqd->ppa_addr, PBLK_CHUNK_RESET_DONE);
+
chunk->state = NVM_CHK_ST_FREE;
}

@@ -958,6 +964,9 @@ int pblk_line_erase(struct pblk *pblk, struct pblk_line *line)
WARN_ON(test_and_set_bit(bit, line->erase_bitmap));
spin_unlock(&line->lock);

+ trace_pblk_chunk_reset(pblk_disk_name(pblk),
+ &ppa, PBLK_CHUNK_RESET_START);
+
ret = pblk_blk_erase_sync(pblk, ppa);
if (ret) {
pblk_err(pblk, "failed to erase line %d\n", line->id);
@@ -1736,6 +1745,9 @@ int pblk_blk_erase_async(struct pblk *pblk, struct ppa_addr ppa)
rqd->end_io = pblk_end_io_erase;
rqd->private = pblk;

+ trace_pblk_chunk_reset(pblk_disk_name(pblk),
+ &ppa, PBLK_CHUNK_RESET_START);
+
/* The write thread schedules erases so that it minimizes disturbances
* with writes. Thus, there is no need to take the LUN semaphore.
*/
diff --git a/drivers/lightnvm/pblk-trace.h b/drivers/lightnvm/pblk-trace.h
index c171d0450c07..679e5c458ca6 100644
--- a/drivers/lightnvm/pblk-trace.h
+++ b/drivers/lightnvm/pblk-trace.h
@@ -31,6 +31,37 @@ struct ppa_addr;
{ PBLK_STATE_RECOVERING, "RECOVERING", }, \
{ PBLK_STATE_STOPPED, "STOPPED" })

+#define show_chunk_erase_state(state) __print_symbolic(state, \
+ { PBLK_CHUNK_RESET_START, "START", }, \
+ { PBLK_CHUNK_RESET_DONE, "OK", }, \
+ { PBLK_CHUNK_RESET_FAILED, "FAILED" })
+
+
+TRACE_EVENT(pblk_chunk_reset,
+
+ TP_PROTO(const char *name, struct ppa_addr *ppa, int state),
+
+ TP_ARGS(name, ppa, state),
+
+ TP_STRUCT__entry(
+ __string(name, name)
+ __field(u64, ppa)
+ __field(int, state);
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, name);
+ __entry->ppa = ppa->ppa;
+ __entry->state = state;
+ ),
+
+ TP_printk("dev=%s grp=%llu pu=%llu chk=%llu state=%s", __get_str(name),
+ (u64)(((struct ppa_addr *)(&__entry->ppa))->m.grp),
+ (u64)(((struct ppa_addr *)(&__entry->ppa))->m.pu),
+ (u64)(((struct ppa_addr *)(&__entry->ppa))->m.chk),
+ show_chunk_erase_state((int)__entry->state))
+
+);

TRACE_EVENT(pblk_chunk_state,

diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index ed17db2cae2c..6195e3f5d2e6 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -79,6 +79,12 @@ enum {
PBLK_BLK_ST_CLOSED = 0x2,
};

+enum {
+ PBLK_CHUNK_RESET_START,
+ PBLK_CHUNK_RESET_DONE,
+ PBLK_CHUNK_RESET_FAILED,
+};
+
struct pblk_sec_meta {
u64 reserved;
__le64 lba;
--
2.7.4


2018-08-29 12:33:09

by Hans Holmberg

[permalink] [raw]
Subject: [PATCH 3/4] lightnvm: pblk: add trace events for pblk state changes

From: Hans Holmberg <[email protected]>

Add trace events for tracking pblk state changes.

Signed-off-by: Hans Holmberg <[email protected]>
---
drivers/lightnvm/pblk-core.c | 3 +++
drivers/lightnvm/pblk-init.c | 1 +
drivers/lightnvm/pblk-trace.h | 28 ++++++++++++++++++++++++++++
3 files changed, 32 insertions(+)

diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index 05775a279b20..566a5d3165ee 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -1503,6 +1503,7 @@ static void pblk_stop_writes(struct pblk *pblk, struct pblk_line *line)

pblk_set_space_limit(pblk);
pblk->state = PBLK_STATE_STOPPING;
+ trace_pblk_state(pblk_disk_name(pblk), pblk->state);
}

static void pblk_line_close_meta_sync(struct pblk *pblk)
@@ -1552,6 +1553,7 @@ void __pblk_pipeline_flush(struct pblk *pblk)
return;
}
pblk->state = PBLK_STATE_RECOVERING;
+ trace_pblk_state(pblk_disk_name(pblk), pblk->state);
spin_unlock(&l_mg->free_lock);

pblk_flush_writer(pblk);
@@ -1573,6 +1575,7 @@ void __pblk_pipeline_stop(struct pblk *pblk)

spin_lock(&l_mg->free_lock);
pblk->state = PBLK_STATE_STOPPED;
+ trace_pblk_state(pblk_disk_name(pblk), pblk->state);
l_mg->data_line = NULL;
l_mg->data_next = NULL;
spin_unlock(&l_mg->free_lock);
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index ddbd91d80119..d0546213c64f 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -1093,6 +1093,7 @@ static void *pblk_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk,
pblk->dev = dev;
pblk->disk = tdisk;
pblk->state = PBLK_STATE_RUNNING;
+ trace_pblk_state(pblk_disk_name(pblk), pblk->state);
pblk->gc.gc_enabled = 0;

if (!(geo->version == NVM_OCSSD_SPEC_12 ||
diff --git a/drivers/lightnvm/pblk-trace.h b/drivers/lightnvm/pblk-trace.h
index f9aa9e25e428..c171d0450c07 100644
--- a/drivers/lightnvm/pblk-trace.h
+++ b/drivers/lightnvm/pblk-trace.h
@@ -25,6 +25,13 @@ struct ppa_addr;
{ PBLK_LINESTATE_CORRUPT, "CORRUPT" })


+#define show_pblk_state(state) __print_symbolic(state, \
+ { PBLK_STATE_RUNNING, "RUNNING", }, \
+ { PBLK_STATE_STOPPING, "STOPPING", }, \
+ { PBLK_STATE_RECOVERING, "RECOVERING", }, \
+ { PBLK_STATE_STOPPED, "STOPPED" })
+
+
TRACE_EVENT(pblk_chunk_state,

TP_PROTO(const char *name, struct ppa_addr *ppa, int state),
@@ -75,6 +82,27 @@ TRACE_EVENT(pblk_line_state,

);

+TRACE_EVENT(pblk_state,
+
+ TP_PROTO(const char *name, int state),
+
+ TP_ARGS(name, state),
+
+ TP_STRUCT__entry(
+ __string(name, name)
+ __field(int, state);
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, name);
+ __entry->state = state;
+ ),
+
+ TP_printk("dev=%s state=%s", __get_str(name),
+ show_pblk_state((int)__entry->state))
+
+);
+
#endif /* !defined(_TRACE_PBLK_H) || defined(TRACE_HEADER_MULTI_READ) */

/* This part must be outside protection */
--
2.7.4


2018-08-29 12:33:20

by Hans Holmberg

[permalink] [raw]
Subject: [PATCH 1/4] lightnvm: pblk: add trace events for chunk states

From: Hans Holmberg <[email protected]>

Introduce trace points for tracking chunk states in pblk - this is
useful for inspection of the entire state of the drive, and real handy
for both fw and pblk debugging.

Signed-off-by: Hans Holmberg <[email protected]>
---
drivers/lightnvm/pblk-core.c | 35 +++++++++++++++++++++++++++-
drivers/lightnvm/pblk-init.c | 4 ++++
drivers/lightnvm/pblk-trace.h | 53 +++++++++++++++++++++++++++++++++++++++++++
drivers/lightnvm/pblk-write.c | 10 ++++++--
drivers/lightnvm/pblk.h | 8 +++++++
5 files changed, 107 insertions(+), 3 deletions(-)
create mode 100644 drivers/lightnvm/pblk-trace.h

diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index f7bff3ae52ac..4da37e29bb06 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -16,7 +16,10 @@
*
*/

+#define CREATE_TRACE_POINTS
+
#include "pblk.h"
+#include "pblk-trace.h"

static void pblk_line_mark_bb(struct work_struct *work)
{
@@ -93,6 +96,9 @@ static void __pblk_end_io_erase(struct pblk *pblk, struct nvm_rq *rqd)
chunk->state = NVM_CHK_ST_FREE;
}

+ trace_pblk_chunk_state(pblk_disk_name(pblk), &rqd->ppa_addr,
+ chunk->state);
+
atomic_dec(&pblk->inflight_io);
}

@@ -477,9 +483,30 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd)
return nvm_submit_io(dev, rqd);
}

+void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd)
+{
+ struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd);
+
+ int i;
+
+ for (i = 0; i < rqd->nr_ppas; i++) {
+ struct ppa_addr *ppa = &ppa_list[i];
+ struct nvm_chk_meta *chunk = pblk_dev_ppa_to_chunk(pblk, *ppa);
+ u64 caddr = pblk_dev_ppa_to_chunk_addr(pblk, *ppa);
+
+ if (caddr == 0)
+ trace_pblk_chunk_state(pblk_disk_name(pblk),
+ ppa, NVM_CHK_ST_OPEN);
+ else if (caddr == chunk->cnlb)
+ trace_pblk_chunk_state(pblk_disk_name(pblk),
+ ppa, NVM_CHK_ST_CLOSED);
+ }
+}
+
int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
{
struct nvm_tgt_dev *dev = pblk->dev;
+ int ret;

atomic_inc(&pblk->inflight_io);

@@ -488,7 +515,13 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd)
return NVM_IO_ERR;
#endif

- return nvm_submit_io_sync(dev, rqd);
+ ret = nvm_submit_io_sync(dev, rqd);
+
+ if (trace_pblk_chunk_state_enabled() && !ret &&
+ rqd->opcode == NVM_OP_PWRITE)
+ pblk_check_chunk_state_update(pblk, rqd);
+
+ return ret;
}

static void pblk_bio_map_addr_endio(struct bio *bio)
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 0be64220b5d8..3f8bae9be852 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -19,6 +19,7 @@
*/

#include "pblk.h"
+#include "pblk-trace.h"

static unsigned int write_buffer_size;

@@ -650,6 +651,9 @@ static int pblk_setup_line_meta_chk(struct pblk *pblk, struct pblk_line *line,
chunk->cnlb = chunk_meta->cnlb;
chunk->wp = chunk_meta->wp;

+ trace_pblk_chunk_state(pblk_disk_name(pblk), &ppa,
+ chunk->state);
+
if (chunk->type & NVM_CHK_TP_SZ_SPEC) {
WARN_ONCE(1, "pblk: custom-sized chunks unsupported\n");
continue;
diff --git a/drivers/lightnvm/pblk-trace.h b/drivers/lightnvm/pblk-trace.h
new file mode 100644
index 000000000000..d985b729428f
--- /dev/null
+++ b/drivers/lightnvm/pblk-trace.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM pblk
+
+#if !defined(_TRACE_PBLK_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_PBLK_H
+
+#include <linux/tracepoint.h>
+
+struct ppa_addr;
+
+#define show_chunk_flags(state) __print_flags(state, "", \
+ { NVM_CHK_ST_FREE, "FREE", }, \
+ { NVM_CHK_ST_CLOSED, "CLOSED", }, \
+ { NVM_CHK_ST_OPEN, "OPEN", }, \
+ { NVM_CHK_ST_OFFLINE, "OFFLINE", })
+
+TRACE_EVENT(pblk_chunk_state,
+
+ TP_PROTO(const char *name, struct ppa_addr *ppa, int state),
+
+ TP_ARGS(name, ppa, state),
+
+ TP_STRUCT__entry(
+ __string(name, name)
+ __field(u64, ppa)
+ __field(int, state);
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, name);
+ __entry->ppa = ppa->ppa;
+ __entry->state = state;
+ ),
+
+ TP_printk("dev=%s grp=%llu pu=%llu chk=%llu state=%s", __get_str(name),
+ (u64)(((struct ppa_addr *)(&__entry->ppa))->m.grp),
+ (u64)(((struct ppa_addr *)(&__entry->ppa))->m.pu),
+ (u64)(((struct ppa_addr *)(&__entry->ppa))->m.chk),
+ show_chunk_flags((int)__entry->state))
+
+);
+
+
+#endif /* !defined(_TRACE_PBLK_H) || defined(TRACE_HEADER_MULTI_READ) */
+
+/* This part must be outside protection */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../../drivers/lightnvm
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE pblk-trace
+#include <trace/define_trace.h>
diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c
index 8aa4b9ee5092..bb656cbd5d3e 100644
--- a/drivers/lightnvm/pblk-write.c
+++ b/drivers/lightnvm/pblk-write.c
@@ -16,6 +16,7 @@
*/

#include "pblk.h"
+#include "pblk-trace.h"

static unsigned long pblk_end_w_bio(struct pblk *pblk, struct nvm_rq *rqd,
struct pblk_c_ctx *c_ctx)
@@ -278,11 +279,13 @@ static void pblk_end_io_write(struct nvm_rq *rqd)
if (rqd->error) {
pblk_end_w_fail(pblk, rqd);
return;
- }
+ } else {
+ if (trace_pblk_chunk_state_enabled())
+ pblk_check_chunk_state_update(pblk, rqd);
#ifdef CONFIG_NVM_PBLK_DEBUG
- else
WARN_ONCE(rqd->bio->bi_status, "pblk: corrupted write error\n");
#endif
+ }

pblk_complete_write(pblk, rqd, c_ctx);
atomic_dec(&pblk->inflight_io);
@@ -303,6 +306,9 @@ static void pblk_end_io_write_meta(struct nvm_rq *rqd)
pblk_log_write_err(pblk, rqd);
pblk_err(pblk, "metadata I/O failed. Line %d\n", line->id);
line->w_err_gc->has_write_err = 1;
+ } else {
+ if (trace_pblk_chunk_state_enabled())
+ pblk_check_chunk_state_update(pblk, rqd);
}

sync = atomic_add_return(rqd->nr_ppas, &emeta->sync);
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h
index 1bdac22e7897..ed17db2cae2c 100644
--- a/drivers/lightnvm/pblk.h
+++ b/drivers/lightnvm/pblk.h
@@ -785,6 +785,7 @@ void pblk_log_read_err(struct pblk *pblk, struct nvm_rq *rqd);
int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd);
int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd);
int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line);
+void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd);
struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data,
unsigned int nr_secs, unsigned int len,
int alloc_type, gfp_t gfp_mask);
@@ -1440,4 +1441,11 @@ static inline void pblk_setup_uuid(struct pblk *pblk)
uuid_le_gen(&uuid);
memcpy(pblk->instance_uuid, uuid.b, 16);
}
+
+static inline char *pblk_disk_name(struct pblk *pblk)
+{
+ struct gendisk *disk = pblk->disk;
+
+ return disk->disk_name;
+}
#endif /* PBLK_H_ */
--
2.7.4


2018-08-29 12:33:55

by Hans Holmberg

[permalink] [raw]
Subject: [PATCH 2/4] lightnvm: pblk: add trace events for line state changes

From: Hans Holmberg <[email protected]>

Add trace events for logging for line state changes.

Signed-off-by: Hans Holmberg <[email protected]>
---
drivers/lightnvm/pblk-core.c | 19 ++++++++++++++++++-
drivers/lightnvm/pblk-gc.c | 8 ++++++++
drivers/lightnvm/pblk-init.c | 3 +++
drivers/lightnvm/pblk-recovery.c | 6 ++++++
drivers/lightnvm/pblk-trace.h | 33 +++++++++++++++++++++++++++++++++
5 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index 4da37e29bb06..05775a279b20 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -413,6 +413,9 @@ struct list_head *pblk_line_gc_list(struct pblk *pblk, struct pblk_line *line)
}
} else {
line->state = PBLK_LINESTATE_CORRUPT;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
+
line->gc_group = PBLK_LINEGC_NONE;
move_list = &l_mg->corrupt_list;
pblk_err(pblk, "corrupted vsc for line %d, vsc:%d (%d/%d/%d)\n",
@@ -1019,6 +1022,8 @@ static int pblk_line_init_metadata(struct pblk *pblk, struct pblk_line *line,
spin_lock(&l_mg->free_lock);
spin_lock(&line->lock);
line->state = PBLK_LINESTATE_BAD;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
spin_unlock(&line->lock);

list_add_tail(&line->list, &l_mg->bad_list);
@@ -1166,6 +1171,8 @@ static int pblk_line_init_bb(struct pblk *pblk, struct pblk_line *line,
bitmap_weight(line->invalid_bitmap, lm->sec_per_line)) {
spin_lock(&line->lock);
line->state = PBLK_LINESTATE_BAD;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
spin_unlock(&line->lock);

list_add_tail(&line->list, &l_mg->bad_list);
@@ -1218,6 +1225,8 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
if (line->state == PBLK_LINESTATE_NEW) {
blk_to_erase = pblk_prepare_new_line(pblk, line);
line->state = PBLK_LINESTATE_FREE;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
} else {
blk_to_erase = blk_in_line;
}
@@ -1235,6 +1244,8 @@ static int pblk_line_prepare(struct pblk *pblk, struct pblk_line *line)
}

line->state = PBLK_LINESTATE_OPEN;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);

atomic_set(&line->left_eblks, blk_to_erase);
atomic_set(&line->left_seblks, blk_to_erase);
@@ -1331,6 +1342,8 @@ struct pblk_line *pblk_line_get(struct pblk *pblk)
if (unlikely(bit >= lm->blk_per_line)) {
spin_lock(&line->lock);
line->state = PBLK_LINESTATE_BAD;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
spin_unlock(&line->lock);

list_add_tail(&line->list, &l_mg->bad_list);
@@ -1650,6 +1663,8 @@ static void __pblk_line_put(struct pblk *pblk, struct pblk_line *line)
spin_lock(&line->lock);
WARN_ON(line->state != PBLK_LINESTATE_GC);
line->state = PBLK_LINESTATE_FREE;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
line->gc_group = PBLK_LINEGC_NONE;
pblk_line_free(line);

@@ -1779,7 +1794,6 @@ void pblk_line_close(struct pblk *pblk, struct pblk_line *line)
WARN_ON(line->state != PBLK_LINESTATE_OPEN);
line->state = PBLK_LINESTATE_CLOSED;
move_list = pblk_line_gc_list(pblk, line);
-
list_add_tail(&line->list, move_list);

mempool_free(line->map_bitmap, l_mg->bitmap_pool);
@@ -1798,6 +1812,9 @@ void pblk_line_close(struct pblk *pblk, struct pblk_line *line)

spin_unlock(&line->lock);
spin_unlock(&l_mg->gc_lock);
+
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
}

void pblk_line_close_meta(struct pblk *pblk, struct pblk_line *line)
diff --git a/drivers/lightnvm/pblk-gc.c b/drivers/lightnvm/pblk-gc.c
index 157c2567c9e8..b841d84c4342 100644
--- a/drivers/lightnvm/pblk-gc.c
+++ b/drivers/lightnvm/pblk-gc.c
@@ -16,8 +16,10 @@
*/

#include "pblk.h"
+#include "pblk-trace.h"
#include <linux/delay.h>

+
static void pblk_gc_free_gc_rq(struct pblk_gc_rq *gc_rq)
{
if (gc_rq->data)
@@ -64,6 +66,8 @@ static void pblk_put_line_back(struct pblk *pblk, struct pblk_line *line)
spin_lock(&line->lock);
WARN_ON(line->state != PBLK_LINESTATE_GC);
line->state = PBLK_LINESTATE_CLOSED;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
move_list = pblk_line_gc_list(pblk, line);
spin_unlock(&line->lock);

@@ -405,6 +409,8 @@ void pblk_gc_free_full_lines(struct pblk *pblk)
spin_lock(&line->lock);
WARN_ON(line->state != PBLK_LINESTATE_CLOSED);
line->state = PBLK_LINESTATE_GC;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
spin_unlock(&line->lock);

list_del(&line->list);
@@ -451,6 +457,8 @@ static void pblk_gc_run(struct pblk *pblk)
spin_lock(&line->lock);
WARN_ON(line->state != PBLK_LINESTATE_CLOSED);
line->state = PBLK_LINESTATE_GC;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
spin_unlock(&line->lock);

list_del(&line->list);
diff --git a/drivers/lightnvm/pblk-init.c b/drivers/lightnvm/pblk-init.c
index 3f8bae9be852..ddbd91d80119 100644
--- a/drivers/lightnvm/pblk-init.c
+++ b/drivers/lightnvm/pblk-init.c
@@ -971,6 +971,9 @@ static int pblk_lines_init(struct pblk *pblk)
goto fail_free_lines;

nr_free_chks += pblk_setup_line_meta(pblk, line, chunk_meta, i);
+
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
}

if (!nr_free_chks) {
diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c
index eea901d7cebc..f4c5318e99d7 100644
--- a/drivers/lightnvm/pblk-recovery.c
+++ b/drivers/lightnvm/pblk-recovery.c
@@ -15,6 +15,7 @@
*/

#include "pblk.h"
+#include "pblk-trace.h"

int pblk_recov_check_emeta(struct pblk *pblk, struct line_emeta *emeta_buf)
{
@@ -932,6 +933,8 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)

spin_lock(&line->lock);
line->state = PBLK_LINESTATE_CLOSED;
+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
move_list = pblk_line_gc_list(pblk, line);
spin_unlock(&line->lock);

@@ -947,6 +950,9 @@ struct pblk_line *pblk_recov_l2p(struct pblk *pblk)
if (open_lines > 1)
pblk_err(pblk, "failed to recover L2P\n");

+ trace_pblk_line_state(pblk_disk_name(pblk), line->id,
+ line->state);
+
open_lines++;
line->meta_line = meta_line;
data_line = line;
diff --git a/drivers/lightnvm/pblk-trace.h b/drivers/lightnvm/pblk-trace.h
index d985b729428f..f9aa9e25e428 100644
--- a/drivers/lightnvm/pblk-trace.h
+++ b/drivers/lightnvm/pblk-trace.h
@@ -15,6 +15,16 @@ struct ppa_addr;
{ NVM_CHK_ST_OPEN, "OPEN", }, \
{ NVM_CHK_ST_OFFLINE, "OFFLINE", })

+#define show_line_state(state) __print_symbolic(state, \
+ { PBLK_LINESTATE_NEW, "NEW", }, \
+ { PBLK_LINESTATE_FREE, "FREE", }, \
+ { PBLK_LINESTATE_OPEN, "OPEN", }, \
+ { PBLK_LINESTATE_CLOSED, "CLOSED", }, \
+ { PBLK_LINESTATE_GC, "GC", }, \
+ { PBLK_LINESTATE_BAD, "BAD", }, \
+ { PBLK_LINESTATE_CORRUPT, "CORRUPT" })
+
+
TRACE_EVENT(pblk_chunk_state,

TP_PROTO(const char *name, struct ppa_addr *ppa, int state),
@@ -41,6 +51,29 @@ TRACE_EVENT(pblk_chunk_state,

);

+TRACE_EVENT(pblk_line_state,
+
+ TP_PROTO(const char *name, int line, int state),
+
+ TP_ARGS(name, line, state),
+
+ TP_STRUCT__entry(
+ __string(name, name)
+ __field(int, line)
+ __field(int, state);
+ ),
+
+ TP_fast_assign(
+ __assign_str(name, name);
+ __entry->line = line;
+ __entry->state = state;
+ ),
+
+ TP_printk("dev=%s line=%d state=%s", __get_str(name),
+ (int)__entry->line,
+ show_line_state((int)__entry->state))
+
+);

#endif /* !defined(_TRACE_PBLK_H) || defined(TRACE_HEADER_MULTI_READ) */

--
2.7.4


2018-08-29 14:24:03

by Matias Bjørling

[permalink] [raw]
Subject: Re: [PATCH 0/4] Introduce trace events for pblk

On 08/29/2018 02:31 PM, Hans Holmberg wrote:
> From: Hans Holmberg <[email protected]>
>
> This patchset adds trace events for tracking the internal state of
> pblk. I've used the events extensively the last few months, and
> they have proven very useful.
>
> The patches depend on some of Javier's for-4.20 patches.
> For ordering, see:
>
> Branch: for-4.20/pblk
> Remote: ssh://github.com/OpenChannelSSD/linux
>
> Hans Holmberg (4):
> lightnvm: pblk: add trace events for chunk states
> lightnvm: pblk: add trace events for line state changes
> lightnvm: pblk: add trace events for pblk state changes
> lightnvm: pblk: add tracing for chunk resets
>
> drivers/lightnvm/pblk-core.c | 69 ++++++++++++++++++-
> drivers/lightnvm/pblk-gc.c | 8 +++
> drivers/lightnvm/pblk-init.c | 8 +++
> drivers/lightnvm/pblk-recovery.c | 6 ++
> drivers/lightnvm/pblk-trace.h | 145 +++++++++++++++++++++++++++++++++++++++
> drivers/lightnvm/pblk-write.c | 10 ++-
> drivers/lightnvm/pblk.h | 14 ++++
> 7 files changed, 256 insertions(+), 4 deletions(-)
> create mode 100644 drivers/lightnvm/pblk-trace.h
>

Thanks. Applied for 4.20.

2018-08-29 20:21:13

by Javier Gonzalez

[permalink] [raw]
Subject: Re: [PATCH 4/4] lightnvm: pblk: add tracing for chunk resets

> On 29 Aug 2018, at 14.31, Hans Holmberg <[email protected]> wrote:
>
> From: Hans Holmberg <[email protected]>
>
> Trace state of chunk resets.
>
> Signed-off-by: Hans Holmberg <[email protected]>
> ---
> drivers/lightnvm/pblk-core.c | 12 ++++++++++++
> drivers/lightnvm/pblk-trace.h | 31 +++++++++++++++++++++++++++++++
> drivers/lightnvm/pblk.h | 6 ++++++
> 3 files changed, 49 insertions(+)
>
> diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
> index 566a5d3165ee..b874001d1175 100644
> --- a/drivers/lightnvm/pblk-core.c
> +++ b/drivers/lightnvm/pblk-core.c
> @@ -90,9 +90,15 @@ static void __pblk_end_io_erase(struct pblk *pblk, struct nvm_rq *rqd)
> atomic_dec(&line->left_seblks);
>
> if (rqd->error) {
> + trace_pblk_chunk_reset(pblk_disk_name(pblk),
> + &rqd->ppa_addr, PBLK_CHUNK_RESET_FAILED);
> +
> chunk->state = NVM_CHK_ST_OFFLINE;
> pblk_mark_bb(pblk, line, rqd->ppa_addr);
> } else {
> + trace_pblk_chunk_reset(pblk_disk_name(pblk),
> + &rqd->ppa_addr, PBLK_CHUNK_RESET_DONE);
> +
> chunk->state = NVM_CHK_ST_FREE;
> }
>
> @@ -958,6 +964,9 @@ int pblk_line_erase(struct pblk *pblk, struct pblk_line *line)
> WARN_ON(test_and_set_bit(bit, line->erase_bitmap));
> spin_unlock(&line->lock);
>
> + trace_pblk_chunk_reset(pblk_disk_name(pblk),
> + &ppa, PBLK_CHUNK_RESET_START);
> +

Can you move this inside of pblk_blk_erase_sync() instead? I was looking
at the code now to implement a different thing and it is confusing to
see tracing inside erase_async and not in erase_sync.

Thanks,
Javier


Attachments:
signature.asc (849.00 B)
Message signed with OpenPGP

2018-09-04 10:41:34

by Hans Holmberg

[permalink] [raw]
Subject: Re: [PATCH 4/4] lightnvm: pblk: add tracing for chunk resets

On Wed, Aug 29, 2018 at 10:09 PM Javier Gonzalez <[email protected]> wrote:
>
> > On 29 Aug 2018, at 14.31, Hans Holmberg <[email protected]> wrote:
> >
> > From: Hans Holmberg <[email protected]>
> >
> > Trace state of chunk resets.
> >
> > Signed-off-by: Hans Holmberg <[email protected]>
> > ---
> > drivers/lightnvm/pblk-core.c | 12 ++++++++++++
> > drivers/lightnvm/pblk-trace.h | 31 +++++++++++++++++++++++++++++++
> > drivers/lightnvm/pblk.h | 6 ++++++
> > 3 files changed, 49 insertions(+)
> >
> > diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
> > index 566a5d3165ee..b874001d1175 100644
> > --- a/drivers/lightnvm/pblk-core.c
> > +++ b/drivers/lightnvm/pblk-core.c
> > @@ -90,9 +90,15 @@ static void __pblk_end_io_erase(struct pblk *pblk, struct nvm_rq *rqd)
> > atomic_dec(&line->left_seblks);
> >
> > if (rqd->error) {
> > + trace_pblk_chunk_reset(pblk_disk_name(pblk),
> > + &rqd->ppa_addr, PBLK_CHUNK_RESET_FAILED);
> > +
> > chunk->state = NVM_CHK_ST_OFFLINE;
> > pblk_mark_bb(pblk, line, rqd->ppa_addr);
> > } else {
> > + trace_pblk_chunk_reset(pblk_disk_name(pblk),
> > + &rqd->ppa_addr, PBLK_CHUNK_RESET_DONE);
> > +
> > chunk->state = NVM_CHK_ST_FREE;
> > }
> >
> > @@ -958,6 +964,9 @@ int pblk_line_erase(struct pblk *pblk, struct pblk_line *line)
> > WARN_ON(test_and_set_bit(bit, line->erase_bitmap));
> > spin_unlock(&line->lock);
> >
> > + trace_pblk_chunk_reset(pblk_disk_name(pblk),
> > + &ppa, PBLK_CHUNK_RESET_START);
> > +
>
> Can you move this inside of pblk_blk_erase_sync() instead? I was looking
> at the code now to implement a different thing and it is confusing to
> see tracing inside erase_async and not in erase_sync.
>

Fixed in a V2. Thanks.