Commit 498c39be authored by Lukasz Lasek's avatar Lukasz Lasek Committed by Jim Harris
Browse files

lib/ftl: Add base device type.



Added a base device type.
Added an interface for FTL MD layout operations to base device.

With this change, FTL MD regions on base dev are created with
region_create().

Change-Id: I0f70c6c53baa5ffec16a6bb1cb7eda28468574d3
Signed-off-by: default avatarLukasz Lasek <lukasz.lasek@solidigm.com>
Signed-off-by: default avatarMariusz Barczak <Mariusz.Barczak@solidigmtechnology.com>
Signed-off-by: default avatarMateusz Kozlowski <mateusz.kozlowski@solidigm.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/19593


Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Reviewed-by: default avatarArtur Paszkiewicz <artur.paszkiewicz@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent 6394849a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ C_SRCS += utils/ftl_conf.c utils/ftl_md.c utils/ftl_mempool.c utils/ftl_bitmap.c
C_SRCS += upgrade/ftl_layout_upgrade.c upgrade/ftl_sb_upgrade.c upgrade/ftl_p2l_upgrade.c
C_SRCS += upgrade/ftl_band_upgrade.c upgrade/ftl_chunk_upgrade.c
C_SRCS += nvc/ftl_nvc_dev.c nvc/ftl_nvc_bdev_vss.c
C_SRCS += base/ftl_base_dev.c base/ftl_base_bdev.c

SPDK_MAP_FILE = $(abspath $(CURDIR)/spdk_ftl.map)

+75 −0
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright 2023 Solidigm All Rights Reserved
 */

#include "ftl_base_dev.h"
#include "ftl_core.h"
#include "ftl_layout.h"

static bool
is_bdev_compatible(struct spdk_ftl_dev *dev, struct spdk_bdev *bdev)
{
	return spdk_bdev_get_block_size(bdev) == FTL_BLOCK_SIZE;
}

static struct ftl_layout_region *
md_region_create(struct spdk_ftl_dev *dev, enum ftl_layout_region_type reg_type,
		 uint32_t reg_version, size_t entry_size, size_t entry_count)
{
	struct ftl_layout *layout = &dev->layout;
	struct ftl_layout_region *region;
	uint64_t reg_free_offs = 0, reg_current_end, reg_offs, data_base_alignment;
	const char *md_region_name;

	assert(reg_type < FTL_LAYOUT_REGION_TYPE_MAX);
	md_region_name = ftl_md_region_name(reg_type);

	/* As new MD regions are added one after another, find where all existing regions end on the device */
	region = layout->region;
	for (int reg_idx = 0; reg_idx < FTL_LAYOUT_REGION_TYPE_MAX; reg_idx++, region++) {
		if (region->bdev_desc == dev->base_bdev_desc) {
			reg_current_end = region->current.offset + region->current.blocks;
			reg_free_offs = spdk_max(reg_free_offs, reg_current_end);
		}
	}


	data_base_alignment = 8 * ftl_bitmap_buffer_alignment;
	/* Allocating a ftl_bitmap requires a 8B input buffer alignment, since we're reusing the global valid map md buffer
	 * this means that each band starting address needs to be aligned too - each device sector takes 1b in the valid map,
	 * so 64 sectors (8*8) is the needed alignment
	 */
	reg_offs = SPDK_ALIGN_CEIL(reg_free_offs, data_base_alignment);

	region = &layout->region[reg_type];
	region->type = reg_type;
	region->mirror_type = FTL_LAYOUT_REGION_TYPE_INVALID;
	region->name = md_region_name;
	region->current.version = region->prev.version = reg_version;
	region->current.offset = reg_offs;
	region->current.blocks = ftl_md_region_blocks(dev, entry_count * entry_size);
	region->entry_size = entry_size / FTL_BLOCK_SIZE;
	region->num_entries = entry_count;

	region->bdev_desc = dev->base_bdev_desc;
	region->ioch = dev->base_ioch;
	region->vss_blksz = 0;

	reg_offs += region->current.blocks;
	if (reg_offs > layout->base.total_blocks) {
		return NULL;
	}

	return region;
}

struct ftl_base_device_type base_bdev = {
	.name = "base_bdev",
	.ops = {
		.is_bdev_compatible = is_bdev_compatible,
		.md_layout_ops = {
			.region_create = md_region_create,
		},
	}
};
FTL_BASE_DEVICE_TYPE_REGISTER(base_bdev)
+75 −0
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright 2023 Solidigm All Rights Reserved
 */

#include "spdk/stdinc.h"
#include "spdk/queue.h"
#include "spdk/log.h"

#include "ftl_core.h"
#include "ftl_base_dev.h"
#include "utils/ftl_defs.h"

static TAILQ_HEAD(, ftl_base_device_type) g_devs = TAILQ_HEAD_INITIALIZER(g_devs);
static pthread_mutex_t g_devs_mutex = PTHREAD_MUTEX_INITIALIZER;

static const struct ftl_base_device_type *
ftl_base_device_type_get_desc(const char *name)
{
	struct ftl_base_device_type *entry;

	TAILQ_FOREACH(entry, &g_devs, base_devs_entry) {
		if (0 == strcmp(entry->name, name)) {
			return entry;
		}
	}

	return NULL;
}

static bool
ftl_base_device_valid(const struct ftl_base_device_type *type)
{
	return type && type->name && strlen(type->name);
}

void
ftl_base_device_register(struct ftl_base_device_type *type)
{
	if (!ftl_base_device_valid(type)) {
		SPDK_ERRLOG("[FTL] Base device type is invalid\n");
		ftl_abort();
	}

	pthread_mutex_lock(&g_devs_mutex);
	if (!ftl_base_device_type_get_desc(type->name)) {
		TAILQ_INSERT_TAIL(&g_devs, type, base_devs_entry);

		SPDK_NOTICELOG("[FTL] Registered base device, name: %s\n", type->name);
	} else {
		SPDK_ERRLOG("[FTL] Cannot register base device, already exist, name: %s\n", type->name);
		ftl_abort();
	}

	pthread_mutex_unlock(&g_devs_mutex);
}

const struct ftl_base_device_type *
ftl_base_device_get_type_by_bdev(struct spdk_ftl_dev *dev, struct spdk_bdev *bdev)
{
	struct ftl_base_device_type *type;

	pthread_mutex_lock(&g_devs_mutex);

	TAILQ_FOREACH(type, &g_devs, base_devs_entry) {
		if (type->ops.is_bdev_compatible) {
			if (type->ops.is_bdev_compatible(dev, bdev)) {
				break;
			}
		}
	}

	pthread_mutex_unlock(&g_devs_mutex);

	return type;
}
+82 −0
Original line number Diff line number Diff line
/*   SPDX-License-Identifier: BSD-3-Clause
 *   Copyright 2023 Solidigm All Rights Reserved
  */

#ifndef FTL_BASE_DEVICE_H
#define FTL_BASE_DEVICE_H

#include "spdk/stdinc.h"
#include "spdk/bdev_module.h"
#include "spdk/queue.h"
#include "ftl_layout.h"

struct spdk_ftl_dev;
struct ftl_mngt_process;

/**
 * @brief Base device operations interface
 */
struct ftl_base_device_ops {
	/**
	 * @brief Check if block device is valid for base device
	 *
	 * @param dev ftl device
	 * @param bdev bdev to be checked
	 *
	 * @retval true if bdev is valid for base device
	 * @retval false if bdev is not valid for base device
	 */
	bool (*is_bdev_compatible)(struct spdk_ftl_dev *dev, struct spdk_bdev *bdev);

	struct ftl_md_layout_ops md_layout_ops;
};

/**
 * @brief Base device type
 */
struct ftl_base_device_type {
	/**
	 * The name of the base device type
	 */
	const char *name;

	/**
	 * The base device operations
	 */
	const struct ftl_base_device_ops ops;

	/**
	 * Queue entry for FTL base devices
	 */
	TAILQ_ENTRY(ftl_base_device_type) base_devs_entry;
};

/**
 * @brief Macro to register base device type when the module is loaded
 *
 * @param desc Base device type descriptor
 */
#define FTL_BASE_DEVICE_TYPE_REGISTER(desc) \
static void __attribute__((constructor)) ftl_base_device_register_##desc(void) \
{ \
	ftl_base_device_register(&desc); \
}

/**
 * @brief Register base device type
 *
 * @param desc Base device type type
 */
void ftl_base_device_register(struct ftl_base_device_type *desc);

/**
 * @brief Get base device type by bdev
 *
 * @param bdev bdev for which base device type is requested
 *
 * @return Base device type descriptor
 */
const struct ftl_base_device_type *ftl_base_device_get_type_by_bdev(
	struct spdk_ftl_dev *dev, struct spdk_bdev *bdev);

#endif /* FTL_BASE_DEVICE_H */
+4 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include "ftl_layout.h"
#include "ftl_sb.h"
#include "ftl_l2p.h"
#include "base/ftl_base_dev.h"
#include "utils/ftl_bitmap.h"
#include "utils/ftl_log.h"
#include "utils/ftl_property.h"
@@ -60,6 +61,9 @@ struct spdk_ftl_dev {
	/* Underlying device */
	struct spdk_bdev_desc		*base_bdev_desc;

	/* Base device type */
	const struct ftl_base_device_type *base_type;

	/* Cached properties of the underlying device */
	uint64_t			num_blocks_in_band;
	bool				is_zoned;
Loading