diff options
author | Hans Holmberg <hans.holmberg@cnexlabs.com> | 2018-10-09 07:11:52 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-10-09 10:25:07 -0400 |
commit | 4c44abf43d00d81f5c648f376c436a9405980efc (patch) | |
tree | 667edc9d1354b56dd4b71755c298f5911fbac871 /drivers | |
parent | 43241cfe470850a590913a86e590fd4ad9939d59 (diff) |
lightnvm: pblk: add trace events for chunk states
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 <hans.holmberg@cnexlabs.com>
Signed-off-by: Matias Bjørling <mb@lightnvm.io>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/lightnvm/pblk-core.c | 35 | ||||
-rw-r--r-- | drivers/lightnvm/pblk-init.c | 4 | ||||
-rw-r--r-- | drivers/lightnvm/pblk-trace.h | 53 | ||||
-rw-r--r-- | drivers/lightnvm/pblk-write.c | 10 | ||||
-rw-r--r-- | drivers/lightnvm/pblk.h | 8 |
5 files changed, 107 insertions, 3 deletions
diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c index 968597d10cc2..8a5158607467 100644 --- a/drivers/lightnvm/pblk-core.c +++ b/drivers/lightnvm/pblk-core.c | |||
@@ -16,7 +16,10 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define CREATE_TRACE_POINTS | ||
20 | |||
19 | #include "pblk.h" | 21 | #include "pblk.h" |
22 | #include "pblk-trace.h" | ||
20 | 23 | ||
21 | static void pblk_line_mark_bb(struct work_struct *work) | 24 | static void pblk_line_mark_bb(struct work_struct *work) |
22 | { | 25 | { |
@@ -93,6 +96,9 @@ static void __pblk_end_io_erase(struct pblk *pblk, struct nvm_rq *rqd) | |||
93 | chunk->state = NVM_CHK_ST_FREE; | 96 | chunk->state = NVM_CHK_ST_FREE; |
94 | } | 97 | } |
95 | 98 | ||
99 | trace_pblk_chunk_state(pblk_disk_name(pblk), &rqd->ppa_addr, | ||
100 | chunk->state); | ||
101 | |||
96 | atomic_dec(&pblk->inflight_io); | 102 | atomic_dec(&pblk->inflight_io); |
97 | } | 103 | } |
98 | 104 | ||
@@ -477,9 +483,30 @@ int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd) | |||
477 | return nvm_submit_io(dev, rqd); | 483 | return nvm_submit_io(dev, rqd); |
478 | } | 484 | } |
479 | 485 | ||
486 | void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd) | ||
487 | { | ||
488 | struct ppa_addr *ppa_list = nvm_rq_to_ppa_list(rqd); | ||
489 | |||
490 | int i; | ||
491 | |||
492 | for (i = 0; i < rqd->nr_ppas; i++) { | ||
493 | struct ppa_addr *ppa = &ppa_list[i]; | ||
494 | struct nvm_chk_meta *chunk = pblk_dev_ppa_to_chunk(pblk, *ppa); | ||
495 | u64 caddr = pblk_dev_ppa_to_chunk_addr(pblk, *ppa); | ||
496 | |||
497 | if (caddr == 0) | ||
498 | trace_pblk_chunk_state(pblk_disk_name(pblk), | ||
499 | ppa, NVM_CHK_ST_OPEN); | ||
500 | else if (caddr == chunk->cnlb) | ||
501 | trace_pblk_chunk_state(pblk_disk_name(pblk), | ||
502 | ppa, NVM_CHK_ST_CLOSED); | ||
503 | } | ||
504 | } | ||
505 | |||
480 | int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd) | 506 | int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd) |
481 | { | 507 | { |
482 | struct nvm_tgt_dev *dev = pblk->dev; | 508 | struct nvm_tgt_dev *dev = pblk->dev; |
509 | int ret; | ||
483 | 510 | ||
484 | atomic_inc(&pblk->inflight_io); | 511 | atomic_inc(&pblk->inflight_io); |
485 | 512 | ||
@@ -488,7 +515,13 @@ int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd) | |||
488 | return NVM_IO_ERR; | 515 | return NVM_IO_ERR; |
489 | #endif | 516 | #endif |
490 | 517 | ||
491 | return nvm_submit_io_sync(dev, rqd); | 518 | ret = nvm_submit_io_sync(dev, rqd); |
519 | |||
520 | if (trace_pblk_chunk_state_enabled() && !ret && | ||
521 | rqd->opcode == NVM_OP_PWRITE) | ||
522 | pblk_check_chunk_state_update(pblk, rqd); | ||
523 | |||
524 | return ret; | ||
492 | } | 525 | } |
493 | 526 | ||
494 | static void pblk_bio_map_addr_endio(struct bio *bio) | 527 | 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 76a4a271b9cf..4f2d9b502028 100644 --- a/drivers/lightnvm/pblk-init.c +++ b/drivers/lightnvm/pblk-init.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include "pblk.h" | 21 | #include "pblk.h" |
22 | #include "pblk-trace.h" | ||
22 | 23 | ||
23 | static unsigned int write_buffer_size; | 24 | static unsigned int write_buffer_size; |
24 | 25 | ||
@@ -664,6 +665,9 @@ static int pblk_setup_line_meta_chk(struct pblk *pblk, struct pblk_line *line, | |||
664 | chunk->cnlb = chunk_meta->cnlb; | 665 | chunk->cnlb = chunk_meta->cnlb; |
665 | chunk->wp = chunk_meta->wp; | 666 | chunk->wp = chunk_meta->wp; |
666 | 667 | ||
668 | trace_pblk_chunk_state(pblk_disk_name(pblk), &ppa, | ||
669 | chunk->state); | ||
670 | |||
667 | if (chunk->type & NVM_CHK_TP_SZ_SPEC) { | 671 | if (chunk->type & NVM_CHK_TP_SZ_SPEC) { |
668 | WARN_ONCE(1, "pblk: custom-sized chunks unsupported\n"); | 672 | WARN_ONCE(1, "pblk: custom-sized chunks unsupported\n"); |
669 | continue; | 673 | 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 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #undef TRACE_SYSTEM | ||
3 | #define TRACE_SYSTEM pblk | ||
4 | |||
5 | #if !defined(_TRACE_PBLK_H) || defined(TRACE_HEADER_MULTI_READ) | ||
6 | #define _TRACE_PBLK_H | ||
7 | |||
8 | #include <linux/tracepoint.h> | ||
9 | |||
10 | struct ppa_addr; | ||
11 | |||
12 | #define show_chunk_flags(state) __print_flags(state, "", \ | ||
13 | { NVM_CHK_ST_FREE, "FREE", }, \ | ||
14 | { NVM_CHK_ST_CLOSED, "CLOSED", }, \ | ||
15 | { NVM_CHK_ST_OPEN, "OPEN", }, \ | ||
16 | { NVM_CHK_ST_OFFLINE, "OFFLINE", }) | ||
17 | |||
18 | TRACE_EVENT(pblk_chunk_state, | ||
19 | |||
20 | TP_PROTO(const char *name, struct ppa_addr *ppa, int state), | ||
21 | |||
22 | TP_ARGS(name, ppa, state), | ||
23 | |||
24 | TP_STRUCT__entry( | ||
25 | __string(name, name) | ||
26 | __field(u64, ppa) | ||
27 | __field(int, state); | ||
28 | ), | ||
29 | |||
30 | TP_fast_assign( | ||
31 | __assign_str(name, name); | ||
32 | __entry->ppa = ppa->ppa; | ||
33 | __entry->state = state; | ||
34 | ), | ||
35 | |||
36 | TP_printk("dev=%s grp=%llu pu=%llu chk=%llu state=%s", __get_str(name), | ||
37 | (u64)(((struct ppa_addr *)(&__entry->ppa))->m.grp), | ||
38 | (u64)(((struct ppa_addr *)(&__entry->ppa))->m.pu), | ||
39 | (u64)(((struct ppa_addr *)(&__entry->ppa))->m.chk), | ||
40 | show_chunk_flags((int)__entry->state)) | ||
41 | |||
42 | ); | ||
43 | |||
44 | |||
45 | #endif /* !defined(_TRACE_PBLK_H) || defined(TRACE_HEADER_MULTI_READ) */ | ||
46 | |||
47 | /* This part must be outside protection */ | ||
48 | |||
49 | #undef TRACE_INCLUDE_PATH | ||
50 | #define TRACE_INCLUDE_PATH ../../../drivers/lightnvm | ||
51 | #undef TRACE_INCLUDE_FILE | ||
52 | #define TRACE_INCLUDE_FILE pblk-trace | ||
53 | #include <trace/define_trace.h> | ||
diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c index 674ba4d1a9f4..61fe22ccc7a1 100644 --- a/drivers/lightnvm/pblk-write.c +++ b/drivers/lightnvm/pblk-write.c | |||
@@ -16,6 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include "pblk.h" | 18 | #include "pblk.h" |
19 | #include "pblk-trace.h" | ||
19 | 20 | ||
20 | static unsigned long pblk_end_w_bio(struct pblk *pblk, struct nvm_rq *rqd, | 21 | static unsigned long pblk_end_w_bio(struct pblk *pblk, struct nvm_rq *rqd, |
21 | struct pblk_c_ctx *c_ctx) | 22 | struct pblk_c_ctx *c_ctx) |
@@ -251,11 +252,13 @@ static void pblk_end_io_write(struct nvm_rq *rqd) | |||
251 | if (rqd->error) { | 252 | if (rqd->error) { |
252 | pblk_end_w_fail(pblk, rqd); | 253 | pblk_end_w_fail(pblk, rqd); |
253 | return; | 254 | return; |
254 | } | 255 | } else { |
256 | if (trace_pblk_chunk_state_enabled()) | ||
257 | pblk_check_chunk_state_update(pblk, rqd); | ||
255 | #ifdef CONFIG_NVM_PBLK_DEBUG | 258 | #ifdef CONFIG_NVM_PBLK_DEBUG |
256 | else | ||
257 | WARN_ONCE(rqd->bio->bi_status, "pblk: corrupted write error\n"); | 259 | WARN_ONCE(rqd->bio->bi_status, "pblk: corrupted write error\n"); |
258 | #endif | 260 | #endif |
261 | } | ||
259 | 262 | ||
260 | pblk_complete_write(pblk, rqd, c_ctx); | 263 | pblk_complete_write(pblk, rqd, c_ctx); |
261 | atomic_dec(&pblk->inflight_io); | 264 | atomic_dec(&pblk->inflight_io); |
@@ -276,6 +279,9 @@ static void pblk_end_io_write_meta(struct nvm_rq *rqd) | |||
276 | pblk_log_write_err(pblk, rqd); | 279 | pblk_log_write_err(pblk, rqd); |
277 | pblk_err(pblk, "metadata I/O failed. Line %d\n", line->id); | 280 | pblk_err(pblk, "metadata I/O failed. Line %d\n", line->id); |
278 | line->w_err_gc->has_write_err = 1; | 281 | line->w_err_gc->has_write_err = 1; |
282 | } else { | ||
283 | if (trace_pblk_chunk_state_enabled()) | ||
284 | pblk_check_chunk_state_update(pblk, rqd); | ||
279 | } | 285 | } |
280 | 286 | ||
281 | sync = atomic_add_return(rqd->nr_ppas, &emeta->sync); | 287 | sync = atomic_add_return(rqd->nr_ppas, &emeta->sync); |
diff --git a/drivers/lightnvm/pblk.h b/drivers/lightnvm/pblk.h index 429347bcd1fa..b2746099ca1d 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); | |||
785 | int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd); | 785 | int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd); |
786 | int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd); | 786 | int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd); |
787 | int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line); | 787 | int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line); |
788 | void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd); | ||
788 | struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data, | 789 | struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data, |
789 | unsigned int nr_secs, unsigned int len, | 790 | unsigned int nr_secs, unsigned int len, |
790 | int alloc_type, gfp_t gfp_mask); | 791 | int alloc_type, gfp_t gfp_mask); |
@@ -1427,4 +1428,11 @@ static inline void pblk_setup_uuid(struct pblk *pblk) | |||
1427 | uuid_le_gen(&uuid); | 1428 | uuid_le_gen(&uuid); |
1428 | memcpy(pblk->instance_uuid, uuid.b, 16); | 1429 | memcpy(pblk->instance_uuid, uuid.b, 16); |
1429 | } | 1430 | } |
1431 | |||
1432 | static inline char *pblk_disk_name(struct pblk *pblk) | ||
1433 | { | ||
1434 | struct gendisk *disk = pblk->disk; | ||
1435 | |||
1436 | return disk->disk_name; | ||
1437 | } | ||
1430 | #endif /* PBLK_H_ */ | 1438 | #endif /* PBLK_H_ */ |