xref: /spdk/lib/ftl/ftl_debug.c (revision 7506a7aa53d239f533af3bc768f0d2af55e735fe)
1 /*-
2  *   BSD LICENSE
3  *
4  *   Copyright (c) Intel Corporation.
5  *   All rights reserved.
6  *
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  *
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include "spdk/log.h"
35 #include "spdk/ftl.h"
36 #include "ftl_debug.h"
37 #include "ftl_band.h"
38 
39 #if defined(DEBUG)
40 #if defined(FTL_META_DEBUG)
41 
42 static const char *ftl_band_state_str[] = {
43 	"free",
44 	"prep",
45 	"opening",
46 	"open",
47 	"full",
48 	"closing",
49 	"closed",
50 	"max"
51 };
52 
53 bool
54 ftl_band_validate_md(struct ftl_band *band)
55 {
56 	struct spdk_ftl_dev *dev = band->dev;
57 	struct ftl_lba_map *lba_map = &band->lba_map;
58 	struct ftl_addr addr_md, addr_l2p;
59 	size_t i, size, seg_off;
60 	bool valid = true;
61 
62 	size = ftl_get_num_blocks_in_band(dev);
63 
64 	pthread_spin_lock(&lba_map->lock);
65 	for (i = 0; i < size; ++i) {
66 		if (!spdk_bit_array_get(lba_map->vld, i)) {
67 			continue;
68 		}
69 
70 		seg_off = i / FTL_NUM_LBA_IN_BLOCK;
71 		if (lba_map->segments[seg_off] != FTL_LBA_MAP_SEG_CACHED) {
72 			continue;
73 		}
74 
75 		addr_md = ftl_band_addr_from_block_offset(band, i);
76 		addr_l2p = ftl_l2p_get(dev, lba_map->map[i]);
77 
78 		if (addr_l2p.cached) {
79 			continue;
80 		}
81 
82 		if (addr_l2p.offset != addr_md.offset) {
83 			valid = false;
84 			break;
85 		}
86 
87 	}
88 
89 	pthread_spin_unlock(&lba_map->lock);
90 
91 	return valid;
92 }
93 
94 void
95 ftl_dev_dump_bands(struct spdk_ftl_dev *dev)
96 {
97 	size_t i;
98 
99 	if (!dev->bands) {
100 		return;
101 	}
102 
103 	ftl_debug("Bands validity:\n");
104 	for (i = 0; i < ftl_get_num_bands(dev); ++i) {
105 		if (dev->bands[i].state == FTL_BAND_STATE_FREE &&
106 		    dev->bands[i].wr_cnt == 0) {
107 			continue;
108 		}
109 
110 		if (!dev->bands[i].num_zones) {
111 			ftl_debug(" Band %3zu: all zones are offline\n", i + 1);
112 			continue;
113 		}
114 
115 		ftl_debug(" Band %3zu: %8zu / %zu \tnum_zones: %zu \twr_cnt: %"PRIu64"\tmerit:"
116 			  "%10.3f\tstate: %s\n",
117 			  i + 1, dev->bands[i].lba_map.num_vld,
118 			  ftl_band_user_blocks(&dev->bands[i]),
119 			  dev->bands[i].num_zones,
120 			  dev->bands[i].wr_cnt,
121 			  dev->bands[i].merit,
122 			  ftl_band_state_str[dev->bands[i].state]);
123 	}
124 }
125 
126 #endif /* defined(FTL_META_DEBUG) */
127 
128 #if defined(FTL_DUMP_STATS)
129 
130 void
131 ftl_dev_dump_stats(const struct spdk_ftl_dev *dev)
132 {
133 	size_t i, total = 0;
134 	char uuid[SPDK_UUID_STRING_LEN];
135 	double waf;
136 	const char *limits[] = {
137 		[SPDK_FTL_LIMIT_CRIT]  = "crit",
138 		[SPDK_FTL_LIMIT_HIGH]  = "high",
139 		[SPDK_FTL_LIMIT_LOW]   = "low",
140 		[SPDK_FTL_LIMIT_START] = "start"
141 	};
142 
143 	if (!dev->bands) {
144 		return;
145 	}
146 
147 	/* Count the number of valid LBAs */
148 	for (i = 0; i < ftl_get_num_bands(dev); ++i) {
149 		total += dev->bands[i].lba_map.num_vld;
150 	}
151 
152 	waf = (double)dev->stats.write_total / (double)dev->stats.write_user;
153 
154 	spdk_uuid_fmt_lower(uuid, sizeof(uuid), &dev->uuid);
155 	ftl_debug("\n");
156 	ftl_debug("device UUID:         %s\n", uuid);
157 	ftl_debug("total valid LBAs:    %zu\n", total);
158 	ftl_debug("total writes:        %"PRIu64"\n", dev->stats.write_total);
159 	ftl_debug("user writes:         %"PRIu64"\n", dev->stats.write_user);
160 	ftl_debug("WAF:                 %.4lf\n", waf);
161 	ftl_debug("limits:\n");
162 	for (i = 0; i < SPDK_FTL_LIMIT_MAX; ++i) {
163 		ftl_debug(" %5s: %"PRIu64"\n", limits[i], dev->stats.limits[i]);
164 	}
165 }
166 
167 #endif /* defined(FTL_DUMP_STATS) */
168 #endif /* defined(DEBUG) */
169