aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Holmberg <hans.holmberg@cnexlabs.com>2018-10-09 07:11:52 -0400
committerJens Axboe <axboe@kernel.dk>2018-10-09 10:25:07 -0400
commit4c44abf43d00d81f5c648f376c436a9405980efc (patch)
tree667edc9d1354b56dd4b71755c298f5911fbac871 /drivers
parent43241cfe470850a590913a86e590fd4ad9939d59 (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.c35
-rw-r--r--drivers/lightnvm/pblk-init.c4
-rw-r--r--drivers/lightnvm/pblk-trace.h53
-rw-r--r--drivers/lightnvm/pblk-write.c10
-rw-r--r--drivers/lightnvm/pblk.h8
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
21static void pblk_line_mark_bb(struct work_struct *work) 24static 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
486void 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
480int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd) 506int 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
494static void pblk_bio_map_addr_endio(struct bio *bio) 527static 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
23static unsigned int write_buffer_size; 24static 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
10struct 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
18TRACE_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
20static unsigned long pblk_end_w_bio(struct pblk *pblk, struct nvm_rq *rqd, 21static 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);
785int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd); 785int pblk_submit_io(struct pblk *pblk, struct nvm_rq *rqd);
786int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd); 786int pblk_submit_io_sync(struct pblk *pblk, struct nvm_rq *rqd);
787int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line); 787int pblk_submit_meta_io(struct pblk *pblk, struct pblk_line *meta_line);
788void pblk_check_chunk_state_update(struct pblk *pblk, struct nvm_rq *rqd);
788struct bio *pblk_bio_map_addr(struct pblk *pblk, void *data, 789struct 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
1432static 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_ */