xref: /spdk/lib/ftl/ftl_debug.c (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
192b5ebe0SKozlowski Mateusz /*   SPDX-License-Identifier: BSD-3-Clause
2*a6dbe372Spaul luse  *   Copyright (C) 2018 Intel Corporation.
392b5ebe0SKozlowski Mateusz  *   All rights reserved.
492b5ebe0SKozlowski Mateusz  */
592b5ebe0SKozlowski Mateusz 
692b5ebe0SKozlowski Mateusz #include "spdk/ftl.h"
792b5ebe0SKozlowski Mateusz #include "ftl_debug.h"
888d1c3a6SKozlowski Mateusz #include "ftl_band.h"
988d1c3a6SKozlowski Mateusz 
1088d1c3a6SKozlowski Mateusz /* TODO: Switch to INFOLOG instead, we can control the printing via spdk_log_get_flag */
1188d1c3a6SKozlowski Mateusz #if defined(DEBUG)
1288d1c3a6SKozlowski Mateusz 
1388d1c3a6SKozlowski Mateusz static const char *ftl_band_state_str[] = {
1488d1c3a6SKozlowski Mateusz 	"free",
1588d1c3a6SKozlowski Mateusz 	"prep",
1688d1c3a6SKozlowski Mateusz 	"opening",
1788d1c3a6SKozlowski Mateusz 	"open",
1888d1c3a6SKozlowski Mateusz 	"full",
1988d1c3a6SKozlowski Mateusz 	"closing",
2088d1c3a6SKozlowski Mateusz 	"closed",
2188d1c3a6SKozlowski Mateusz 	"max"
2288d1c3a6SKozlowski Mateusz };
2388d1c3a6SKozlowski Mateusz 
248fad5718SArtur Paszkiewicz struct ftl_band_validate_ctx {
258fad5718SArtur Paszkiewicz 	struct ftl_band *band;
268fad5718SArtur Paszkiewicz 	ftl_band_validate_md_cb cb;
278fad5718SArtur Paszkiewicz 	int remaining;
288fad5718SArtur Paszkiewicz 	uint64_t pin_cnt;
298fad5718SArtur Paszkiewicz 	uint64_t current_offset;
308fad5718SArtur Paszkiewicz 	struct ftl_l2p_pin_ctx l2p_pin_ctx[];
318fad5718SArtur Paszkiewicz };
328fad5718SArtur Paszkiewicz 
338fad5718SArtur Paszkiewicz static void ftl_band_validate_md_l2p_pin_cb(struct spdk_ftl_dev *dev, int status,
348fad5718SArtur Paszkiewicz 		struct ftl_l2p_pin_ctx *pin_ctx);
358fad5718SArtur Paszkiewicz 
368fad5718SArtur Paszkiewicz #define FTL_MD_VALIDATE_LBA_PER_ITERATION 128
378fad5718SArtur Paszkiewicz 
388fad5718SArtur Paszkiewicz static void
ftl_band_validate_md_pin(struct ftl_band_validate_ctx * ctx)398fad5718SArtur Paszkiewicz ftl_band_validate_md_pin(struct ftl_band_validate_ctx *ctx)
408fad5718SArtur Paszkiewicz {
418fad5718SArtur Paszkiewicz 	struct ftl_band *band = ctx->band;
428fad5718SArtur Paszkiewicz 	struct spdk_ftl_dev *dev = band->dev;
438fad5718SArtur Paszkiewicz 	struct ftl_p2l_map *p2l_map = &band->p2l_map;
448fad5718SArtur Paszkiewicz 	size_t i, size;
458fad5718SArtur Paszkiewicz 	struct ftl_l2p_pin_ctx tmp_pin_ctx = {
468fad5718SArtur Paszkiewicz 		.cb_ctx = ctx
478fad5718SArtur Paszkiewicz 	};
488fad5718SArtur Paszkiewicz 
498fad5718SArtur Paszkiewicz 	/* Since the first L2P page may already be pinned, the ftl_band_validate_md_l2p_pin_cb could be prematurely
508fad5718SArtur Paszkiewicz 	 * triggered. Initializing to 1 and then triggering the callback again manually prevents the issue.
518fad5718SArtur Paszkiewicz 	 */
528fad5718SArtur Paszkiewicz 	ctx->remaining = 1;
538fad5718SArtur Paszkiewicz 	size = spdk_min(FTL_MD_VALIDATE_LBA_PER_ITERATION,
548fad5718SArtur Paszkiewicz 			ftl_get_num_blocks_in_band(dev) - ctx->current_offset);
558fad5718SArtur Paszkiewicz 
568fad5718SArtur Paszkiewicz 	for (i = ctx->current_offset; i < ctx->current_offset + size; ++i) {
578fad5718SArtur Paszkiewicz 		if (!ftl_bitmap_get(p2l_map->valid, i)) {
588fad5718SArtur Paszkiewicz 			ctx->l2p_pin_ctx[i].lba = FTL_LBA_INVALID;
598fad5718SArtur Paszkiewicz 			continue;
608fad5718SArtur Paszkiewicz 		}
618fad5718SArtur Paszkiewicz 
6236049672SArtur Paszkiewicz 		assert(p2l_map->band_map[i].lba != FTL_LBA_INVALID);
638fad5718SArtur Paszkiewicz 		ctx->remaining++;
648fad5718SArtur Paszkiewicz 		ctx->pin_cnt++;
6536049672SArtur Paszkiewicz 		ftl_l2p_pin(dev, p2l_map->band_map[i].lba, 1, ftl_band_validate_md_l2p_pin_cb, ctx,
668fad5718SArtur Paszkiewicz 			    &ctx->l2p_pin_ctx[i]);
678fad5718SArtur Paszkiewicz 	}
688fad5718SArtur Paszkiewicz 
698fad5718SArtur Paszkiewicz 	ftl_band_validate_md_l2p_pin_cb(dev, 0, &tmp_pin_ctx);
708fad5718SArtur Paszkiewicz }
718fad5718SArtur Paszkiewicz 
728fad5718SArtur Paszkiewicz static void
_ftl_band_validate_md(void * _ctx)738fad5718SArtur Paszkiewicz _ftl_band_validate_md(void *_ctx)
748fad5718SArtur Paszkiewicz {
758fad5718SArtur Paszkiewicz 	struct ftl_band_validate_ctx *ctx = _ctx;
768fad5718SArtur Paszkiewicz 	struct ftl_band *band = ctx->band;
778fad5718SArtur Paszkiewicz 	struct spdk_ftl_dev *dev = band->dev;
788fad5718SArtur Paszkiewicz 	ftl_addr addr_l2p;
798fad5718SArtur Paszkiewicz 	size_t i, size;
808fad5718SArtur Paszkiewicz 	bool valid = true;
818fad5718SArtur Paszkiewicz 	uint64_t lba;
828fad5718SArtur Paszkiewicz 
838fad5718SArtur Paszkiewicz 	size = spdk_min(FTL_MD_VALIDATE_LBA_PER_ITERATION,
848fad5718SArtur Paszkiewicz 			ftl_get_num_blocks_in_band(dev) - ctx->current_offset);
858fad5718SArtur Paszkiewicz 
868fad5718SArtur Paszkiewicz 	for (i = ctx->current_offset; i < ctx->current_offset + size; ++i) {
878fad5718SArtur Paszkiewicz 		lba = ctx->l2p_pin_ctx[i].lba;
888fad5718SArtur Paszkiewicz 		if (lba == FTL_LBA_INVALID) {
898fad5718SArtur Paszkiewicz 			continue;
908fad5718SArtur Paszkiewicz 		}
918fad5718SArtur Paszkiewicz 
928fad5718SArtur Paszkiewicz 		if (ftl_bitmap_get(band->p2l_map.valid, i)) {
938fad5718SArtur Paszkiewicz 			addr_l2p = ftl_l2p_get(dev, lba);
948fad5718SArtur Paszkiewicz 
958fad5718SArtur Paszkiewicz 			if (addr_l2p != FTL_ADDR_INVALID && !ftl_addr_in_nvc(dev, addr_l2p) &&
968fad5718SArtur Paszkiewicz 			    addr_l2p != ftl_band_addr_from_block_offset(band, i)) {
978fad5718SArtur Paszkiewicz 				valid = false;
988fad5718SArtur Paszkiewicz 			}
998fad5718SArtur Paszkiewicz 		}
1008fad5718SArtur Paszkiewicz 
1018fad5718SArtur Paszkiewicz 		ctx->pin_cnt--;
1028fad5718SArtur Paszkiewicz 		ftl_l2p_unpin(dev, lba, 1);
1038fad5718SArtur Paszkiewicz 	}
1048fad5718SArtur Paszkiewicz 	assert(ctx->pin_cnt == 0);
1058fad5718SArtur Paszkiewicz 
1068fad5718SArtur Paszkiewicz 	ctx->current_offset += size;
1078fad5718SArtur Paszkiewicz 
1088fad5718SArtur Paszkiewicz 	if (ctx->current_offset == ftl_get_num_blocks_in_band(dev)) {
1098fad5718SArtur Paszkiewicz 		ctx->cb(band, valid);
1108fad5718SArtur Paszkiewicz 		free(ctx);
1118fad5718SArtur Paszkiewicz 		return;
1128fad5718SArtur Paszkiewicz 	}
1138fad5718SArtur Paszkiewicz 
1148fad5718SArtur Paszkiewicz 	ftl_band_validate_md_pin(ctx);
1158fad5718SArtur Paszkiewicz }
1168fad5718SArtur Paszkiewicz 
1178fad5718SArtur Paszkiewicz static void
ftl_band_validate_md_l2p_pin_cb(struct spdk_ftl_dev * dev,int status,struct ftl_l2p_pin_ctx * pin_ctx)1188fad5718SArtur Paszkiewicz ftl_band_validate_md_l2p_pin_cb(struct spdk_ftl_dev *dev, int status,
1198fad5718SArtur Paszkiewicz 				struct ftl_l2p_pin_ctx *pin_ctx)
1208fad5718SArtur Paszkiewicz {
1218fad5718SArtur Paszkiewicz 	struct ftl_band_validate_ctx *ctx = pin_ctx->cb_ctx;
1228fad5718SArtur Paszkiewicz 
1238fad5718SArtur Paszkiewicz 	assert(status == 0);
1248fad5718SArtur Paszkiewicz 
1258fad5718SArtur Paszkiewicz 	if (--ctx->remaining == 0) {
1268fad5718SArtur Paszkiewicz 		spdk_thread_send_msg(dev->core_thread, _ftl_band_validate_md, ctx);
1278fad5718SArtur Paszkiewicz 	}
1288fad5718SArtur Paszkiewicz }
1298fad5718SArtur Paszkiewicz 
1308fad5718SArtur Paszkiewicz void
ftl_band_validate_md(struct ftl_band * band,ftl_band_validate_md_cb cb)1318fad5718SArtur Paszkiewicz ftl_band_validate_md(struct ftl_band *band, ftl_band_validate_md_cb cb)
1328fad5718SArtur Paszkiewicz {
1338fad5718SArtur Paszkiewicz 	struct ftl_band_validate_ctx *ctx;
1348fad5718SArtur Paszkiewicz 	size_t size;
1358fad5718SArtur Paszkiewicz 
1368fad5718SArtur Paszkiewicz 	assert(cb);
1378fad5718SArtur Paszkiewicz 
1388fad5718SArtur Paszkiewicz 	size = ftl_get_num_blocks_in_band(band->dev);
1398fad5718SArtur Paszkiewicz 
1408fad5718SArtur Paszkiewicz 	ctx = malloc(sizeof(*ctx) + size * sizeof(*ctx->l2p_pin_ctx));
1418fad5718SArtur Paszkiewicz 
1428fad5718SArtur Paszkiewicz 	if (!ctx) {
1438fad5718SArtur Paszkiewicz 		FTL_ERRLOG(band->dev, "Failed to allocate memory for band validate context");
1448fad5718SArtur Paszkiewicz 		cb(band, false);
1458fad5718SArtur Paszkiewicz 		return;
1468fad5718SArtur Paszkiewicz 	}
1478fad5718SArtur Paszkiewicz 
1488fad5718SArtur Paszkiewicz 	ctx->band = band;
1498fad5718SArtur Paszkiewicz 	ctx->cb = cb;
1508fad5718SArtur Paszkiewicz 	ctx->pin_cnt = 0;
1518fad5718SArtur Paszkiewicz 	ctx->current_offset = 0;
1528fad5718SArtur Paszkiewicz 
1538fad5718SArtur Paszkiewicz 	ftl_band_validate_md_pin(ctx);
1548fad5718SArtur Paszkiewicz }
1558fad5718SArtur Paszkiewicz 
15688d1c3a6SKozlowski Mateusz void
ftl_dev_dump_bands(struct spdk_ftl_dev * dev)15788d1c3a6SKozlowski Mateusz ftl_dev_dump_bands(struct spdk_ftl_dev *dev)
15888d1c3a6SKozlowski Mateusz {
15988d1c3a6SKozlowski Mateusz 	uint64_t i;
16088d1c3a6SKozlowski Mateusz 
16188d1c3a6SKozlowski Mateusz 	if (!dev->bands) {
16288d1c3a6SKozlowski Mateusz 		return;
16388d1c3a6SKozlowski Mateusz 	}
16488d1c3a6SKozlowski Mateusz 
16588d1c3a6SKozlowski Mateusz 	FTL_NOTICELOG(dev, "Bands validity:\n");
16688d1c3a6SKozlowski Mateusz 	for (i = 0; i < ftl_get_num_bands(dev); ++i) {
16788d1c3a6SKozlowski Mateusz 		FTL_NOTICELOG(dev, " Band %3zu: %8zu / %zu \twr_cnt: %"PRIu64
16888d1c3a6SKozlowski Mateusz 			      "\tstate: %s\n",
16988d1c3a6SKozlowski Mateusz 			      i + 1, dev->bands[i].p2l_map.num_valid,
17088d1c3a6SKozlowski Mateusz 			      ftl_band_user_blocks(&dev->bands[i]),
17188d1c3a6SKozlowski Mateusz 			      dev->bands[i].md->wr_cnt,
17288d1c3a6SKozlowski Mateusz 			      ftl_band_state_str[dev->bands[i].md->state]);
17388d1c3a6SKozlowski Mateusz 	}
17488d1c3a6SKozlowski Mateusz }
17588d1c3a6SKozlowski Mateusz 
17688d1c3a6SKozlowski Mateusz #endif /* defined(DEBUG) */
17792b5ebe0SKozlowski Mateusz 
17892b5ebe0SKozlowski Mateusz void
ftl_dev_dump_stats(const struct spdk_ftl_dev * dev)17992b5ebe0SKozlowski Mateusz ftl_dev_dump_stats(const struct spdk_ftl_dev *dev)
18092b5ebe0SKozlowski Mateusz {
18188d1c3a6SKozlowski Mateusz 	uint64_t i, total = 0;
18292b5ebe0SKozlowski Mateusz 	char uuid[SPDK_UUID_STRING_LEN];
1831790ee8aSArtur Paszkiewicz 	double waf;
1841790ee8aSArtur Paszkiewicz 	uint64_t write_user, write_total;
1851790ee8aSArtur Paszkiewicz 	const char *limits[] = {
1861790ee8aSArtur Paszkiewicz 		[SPDK_FTL_LIMIT_CRIT]  = "crit",
1871790ee8aSArtur Paszkiewicz 		[SPDK_FTL_LIMIT_HIGH]  = "high",
1881790ee8aSArtur Paszkiewicz 		[SPDK_FTL_LIMIT_LOW]   = "low",
1891790ee8aSArtur Paszkiewicz 		[SPDK_FTL_LIMIT_START] = "start"
1901790ee8aSArtur Paszkiewicz 	};
1911790ee8aSArtur Paszkiewicz 
1921790ee8aSArtur Paszkiewicz 	(void)limits;
19392b5ebe0SKozlowski Mateusz 
19488d1c3a6SKozlowski Mateusz 	if (!dev->bands) {
19588d1c3a6SKozlowski Mateusz 		return;
19688d1c3a6SKozlowski Mateusz 	}
19788d1c3a6SKozlowski Mateusz 
19888d1c3a6SKozlowski Mateusz 	/* Count the number of valid LBAs */
19988d1c3a6SKozlowski Mateusz 	for (i = 0; i < ftl_get_num_bands(dev); ++i) {
20088d1c3a6SKozlowski Mateusz 		total += dev->bands[i].p2l_map.num_valid;
20188d1c3a6SKozlowski Mateusz 	}
20288d1c3a6SKozlowski Mateusz 
2031790ee8aSArtur Paszkiewicz 	write_user = dev->stats.entries[FTL_STATS_TYPE_CMP].write.blocks;
2041790ee8aSArtur Paszkiewicz 	write_total = write_user +
2051790ee8aSArtur Paszkiewicz 		      dev->stats.entries[FTL_STATS_TYPE_GC].write.blocks +
2061790ee8aSArtur Paszkiewicz 		      dev->stats.entries[FTL_STATS_TYPE_MD_BASE].write.blocks;
2071790ee8aSArtur Paszkiewicz 
2081790ee8aSArtur Paszkiewicz 	waf = (double)write_total / (double)write_user;
2091790ee8aSArtur Paszkiewicz 
21092b5ebe0SKozlowski Mateusz 	spdk_uuid_fmt_lower(uuid, sizeof(uuid), &dev->conf.uuid);
21192b5ebe0SKozlowski Mateusz 	FTL_NOTICELOG(dev, "\n");
21292b5ebe0SKozlowski Mateusz 	FTL_NOTICELOG(dev, "device UUID:         %s\n", uuid);
21392b5ebe0SKozlowski Mateusz 	FTL_NOTICELOG(dev, "total valid LBAs:    %zu\n", total);
2141790ee8aSArtur Paszkiewicz 	FTL_NOTICELOG(dev, "total writes:        %"PRIu64"\n", write_total);
2151790ee8aSArtur Paszkiewicz 	FTL_NOTICELOG(dev, "user writes:         %"PRIu64"\n", write_user);
2161790ee8aSArtur Paszkiewicz 	FTL_NOTICELOG(dev, "WAF:                 %.4lf\n", waf);
2171790ee8aSArtur Paszkiewicz #ifdef DEBUG
2181790ee8aSArtur Paszkiewicz 	FTL_NOTICELOG(dev, "limits:\n");
2191790ee8aSArtur Paszkiewicz 	for (i = 0; i < SPDK_FTL_LIMIT_MAX; ++i) {
2201790ee8aSArtur Paszkiewicz 		FTL_NOTICELOG(dev, " %5s: %"PRIu64"\n", limits[i], dev->stats.limits[i]);
2211790ee8aSArtur Paszkiewicz 	}
2221790ee8aSArtur Paszkiewicz #endif
22392b5ebe0SKozlowski Mateusz }
224