Commit 82b7b4aa authored by Wojciech Malikowski's avatar Wojciech Malikowski Committed by Jim Harris
Browse files

lib/ftl: Media management events



Adding support for handling media management events.

Change-Id: I1b87143ddd360e314385e8dc70359aeb0d526b5a
Signed-off-by: default avatarWojciech Malikowski <wojciech.malikowski@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/481691


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent 4d122a35
Loading
Loading
Loading
Loading
+63 −0
Original line number Diff line number Diff line
@@ -2157,6 +2157,69 @@ ftl_addr_is_written(struct ftl_band *band, struct ftl_addr addr)
	return addr.offset < zone->info.write_pointer;
}

static void ftl_process_media_event(struct spdk_ftl_dev *dev, struct spdk_bdev_media_event event);

static void
_ftl_process_media_event(void *ctx)
{
	struct ftl_media_event *event = ctx;
	struct spdk_ftl_dev *dev = event->dev;

	ftl_process_media_event(dev, event->event);
	spdk_mempool_put(dev->media_events_pool, event);
}

static void
ftl_process_media_event(struct spdk_ftl_dev *dev, struct spdk_bdev_media_event event)
{
	struct ftl_band *band;
	struct ftl_addr addr = { .offset = event.offset };
	size_t block_off;

	if (!ftl_check_core_thread(dev)) {
		struct ftl_media_event *media_event;

		media_event = spdk_mempool_get(dev->media_events_pool);
		if (!media_event) {
			SPDK_ERRLOG("Media event lost due to lack of memory");
			return;
		}

		media_event->dev = dev;
		media_event->event = event;
		spdk_thread_send_msg(ftl_get_core_thread(dev), _ftl_process_media_event,
				     media_event);
		return;
	}

	band = ftl_band_from_addr(dev, addr);
	block_off = ftl_band_block_offset_from_addr(band, addr);

	ftl_reloc_add(dev->reloc, band, block_off, event.num_blocks, 0, false);
}

void
ftl_get_media_events(struct spdk_ftl_dev *dev)
{
#define FTL_MAX_MEDIA_EVENTS 128
	struct spdk_bdev_media_event events[FTL_MAX_MEDIA_EVENTS];
	size_t num_events, i;

	if (!dev->initialized) {
		return;
	}

	do {
		num_events = spdk_bdev_get_media_events(dev->base_bdev_desc,
							events, FTL_MAX_MEDIA_EVENTS);

		for (i = 0; i < num_events; ++i) {
			ftl_process_media_event(dev, events[i]);
		}

	} while (num_events);
}

static void
ftl_process_retry_queue(struct spdk_ftl_dev *dev)
{
+11 −0
Original line number Diff line number Diff line
@@ -167,6 +167,9 @@ struct spdk_ftl_dev {
	/* LBA map requests pool */
	struct spdk_mempool			*lba_request_pool;

	/* Media management events pool */
	struct spdk_mempool			*media_events_pool;

	/* Statistics */
	struct ftl_stats			stats;

@@ -247,6 +250,13 @@ struct ftl_nv_cache_header {
	uint32_t				checksum;
} __attribute__((packed));

struct ftl_media_event {
	/* Owner */
	struct spdk_ftl_dev			*dev;
	/* Media event */
	struct spdk_bdev_media_event		event;
};

typedef void (*ftl_restore_fn)(struct spdk_ftl_dev *, struct ftl_restore *, int);

void	ftl_apply_limits(struct spdk_ftl_dev *dev);
@@ -274,6 +284,7 @@ int ftl_nv_cache_write_header(struct ftl_nv_cache *nv_cache, bool shutdown,
				  spdk_bdev_io_completion_cb cb_fn, void *cb_arg);
int	ftl_nv_cache_scrub(struct ftl_nv_cache *nv_cache, spdk_bdev_io_completion_cb cb_fn,
			   void *cb_arg);
void	ftl_get_media_events(struct spdk_ftl_dev *dev);

struct spdk_io_channel *
ftl_get_io_channel(const struct spdk_ftl_dev *dev);
+35 −0
Original line number Diff line number Diff line
@@ -216,10 +216,15 @@ ftl_dev_init_bands(struct spdk_ftl_dev *dev)
static void
ftl_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *event_ctx)
{
	struct spdk_ftl_dev *dev = event_ctx;

	switch (type) {
	case SPDK_BDEV_EVENT_REMOVE:
		assert(0);
		break;
	case SPDK_BDEV_EVENT_MEDIA_MANAGEMENT:
		assert(bdev == spdk_bdev_desc_get_bdev(dev->base_bdev_desc));
		ftl_get_media_events(dev);
	default:
		break;
	}
@@ -345,6 +350,30 @@ ftl_lba_map_request_ctor(struct spdk_mempool *mp, void *opaque, void *obj, unsig
				    ftl_get_num_blocks_in_band(dev), FTL_NUM_LBA_IN_BLOCK));
}

static int
ftl_init_media_events_pool(struct spdk_ftl_dev *dev)
{
	char pool_name[128];
	int rc;

	rc = snprintf(pool_name, sizeof(pool_name), "ftl-media-%p", dev);
	if (rc < 0 || rc >= (int)sizeof(pool_name)) {
		SPDK_ERRLOG("Failed to create media pool name\n");
		return -1;
	}

	dev->media_events_pool = spdk_mempool_create(pool_name, 1024,
				 sizeof(struct ftl_media_event),
				 SPDK_MEMPOOL_DEFAULT_CACHE_SIZE,
				 SPDK_ENV_SOCKET_ID_ANY);
	if (!dev->media_events_pool) {
		SPDK_ERRLOG("Failed to create media events pool\n");
		return -1;
	}

	return 0;
}

static int
ftl_init_lba_map_pools(struct spdk_ftl_dev *dev)
{
@@ -1112,6 +1141,7 @@ ftl_dev_free_sync(struct spdk_ftl_dev *dev)

	spdk_mempool_free(dev->lba_pool);
	spdk_mempool_free(dev->nv_cache.md_pool);
	spdk_mempool_free(dev->media_events_pool);
	if (dev->lba_request_pool) {
		spdk_mempool_obj_iter(dev->lba_request_pool, ftl_lba_map_request_dtor, NULL);
	}
@@ -1190,6 +1220,11 @@ spdk_ftl_dev_init(const struct spdk_ftl_dev_init_opts *_opts, spdk_ftl_init_fn c
		goto fail_sync;
	}

	if (ftl_init_media_events_pool(dev)) {
		SPDK_ERRLOG("Unable to init media events pools\n");
		goto fail_sync;
	}

	ftl_init_wptr_list(dev);

	if (ftl_dev_init_bands(dev)) {