xref: /spdk/lib/ftl/ftl_debug.c (revision 488570ebd418ba07c9e69e65106dcc964f3bb41b)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (c) Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "spdk/log.h"
7 #include "spdk/ftl.h"
8 #include "ftl_debug.h"
9 #include "ftl_band.h"
10 
11 #if defined(DEBUG)
12 #if defined(FTL_META_DEBUG)
13 
14 static const char *ftl_band_state_str[] = {
15 	"free",
16 	"prep",
17 	"opening",
18 	"open",
19 	"full",
20 	"closing",
21 	"closed",
22 	"max"
23 };
24 
25 bool
26 ftl_band_validate_md(struct ftl_band *band)
27 {
28 	struct spdk_ftl_dev *dev = band->dev;
29 	struct ftl_lba_map *lba_map = &band->lba_map;
30 	struct ftl_addr addr_md, addr_l2p;
31 	size_t i, size, seg_off;
32 	bool valid = true;
33 
34 	size = ftl_get_num_blocks_in_band(dev);
35 
36 	pthread_spin_lock(&lba_map->lock);
37 	for (i = 0; i < size; ++i) {
38 		if (!spdk_bit_array_get(lba_map->vld, i)) {
39 			continue;
40 		}
41 
42 		seg_off = i / FTL_NUM_LBA_IN_BLOCK;
43 		if (lba_map->segments[seg_off] != FTL_LBA_MAP_SEG_CACHED) {
44 			continue;
45 		}
46 
47 		addr_md = ftl_band_addr_from_block_offset(band, i);
48 		addr_l2p = ftl_l2p_get(dev, lba_map->map[i]);
49 
50 		if (addr_l2p.cached) {
51 			continue;
52 		}
53 
54 		if (addr_l2p.offset != addr_md.offset) {
55 			valid = false;
56 			break;
57 		}
58 
59 	}
60 
61 	pthread_spin_unlock(&lba_map->lock);
62 
63 	return valid;
64 }
65 
66 void
67 ftl_dev_dump_bands(struct spdk_ftl_dev *dev)
68 {
69 	size_t i;
70 
71 	if (!dev->bands) {
72 		return;
73 	}
74 
75 	ftl_debug("Bands validity:\n");
76 	for (i = 0; i < ftl_get_num_bands(dev); ++i) {
77 		if (dev->bands[i].state == FTL_BAND_STATE_FREE &&
78 		    dev->bands[i].wr_cnt == 0) {
79 			continue;
80 		}
81 
82 		if (!dev->bands[i].num_zones) {
83 			ftl_debug(" Band %3zu: all zones are offline\n", i + 1);
84 			continue;
85 		}
86 
87 		ftl_debug(" Band %3zu: %8zu / %zu \tnum_zones: %zu \twr_cnt: %"PRIu64"\tmerit:"
88 			  "%10.3f\tstate: %s\n",
89 			  i + 1, dev->bands[i].lba_map.num_vld,
90 			  ftl_band_user_blocks(&dev->bands[i]),
91 			  dev->bands[i].num_zones,
92 			  dev->bands[i].wr_cnt,
93 			  dev->bands[i].merit,
94 			  ftl_band_state_str[dev->bands[i].state]);
95 	}
96 }
97 
98 #endif /* defined(FTL_META_DEBUG) */
99 
100 #if defined(FTL_DUMP_STATS)
101 
102 void
103 ftl_dev_dump_stats(const struct spdk_ftl_dev *dev)
104 {
105 	size_t i, total = 0;
106 	char uuid[SPDK_UUID_STRING_LEN];
107 	double waf;
108 	const char *limits[] = {
109 		[SPDK_FTL_LIMIT_CRIT]  = "crit",
110 		[SPDK_FTL_LIMIT_HIGH]  = "high",
111 		[SPDK_FTL_LIMIT_LOW]   = "low",
112 		[SPDK_FTL_LIMIT_START] = "start"
113 	};
114 
115 	if (!dev->bands) {
116 		return;
117 	}
118 
119 	/* Count the number of valid LBAs */
120 	for (i = 0; i < ftl_get_num_bands(dev); ++i) {
121 		total += dev->bands[i].lba_map.num_vld;
122 	}
123 
124 	waf = (double)dev->stats.write_total / (double)dev->stats.write_user;
125 
126 	spdk_uuid_fmt_lower(uuid, sizeof(uuid), &dev->uuid);
127 	ftl_debug("\n");
128 	ftl_debug("device UUID:         %s\n", uuid);
129 	ftl_debug("total valid LBAs:    %zu\n", total);
130 	ftl_debug("total writes:        %"PRIu64"\n", dev->stats.write_total);
131 	ftl_debug("user writes:         %"PRIu64"\n", dev->stats.write_user);
132 	ftl_debug("WAF:                 %.4lf\n", waf);
133 	ftl_debug("limits:\n");
134 	for (i = 0; i < SPDK_FTL_LIMIT_MAX; ++i) {
135 		ftl_debug(" %5s: %"PRIu64"\n", limits[i], dev->stats.limits[i]);
136 	}
137 }
138 
139 #endif /* defined(FTL_DUMP_STATS) */
140 #endif /* defined(DEBUG) */
141