lib/ftl: Media management events
Adding support for handling media management events. Change-Id: I1b87143ddd360e314385e8dc70359aeb0d526b5a Signed-off-by: Wojciech Malikowski <wojciech.malikowski@intel.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/481691 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Konrad Sztyber <konrad.sztyber@intel.com>
This commit is contained in:
parent
4d122a3559
commit
82b7b4aad5
@ -2157,6 +2157,69 @@ ftl_addr_is_written(struct ftl_band *band, struct ftl_addr addr)
|
|||||||
return addr.offset < zone->info.write_pointer;
|
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
|
static void
|
||||||
ftl_process_retry_queue(struct spdk_ftl_dev *dev)
|
ftl_process_retry_queue(struct spdk_ftl_dev *dev)
|
||||||
{
|
{
|
||||||
|
@ -167,6 +167,9 @@ struct spdk_ftl_dev {
|
|||||||
/* LBA map requests pool */
|
/* LBA map requests pool */
|
||||||
struct spdk_mempool *lba_request_pool;
|
struct spdk_mempool *lba_request_pool;
|
||||||
|
|
||||||
|
/* Media management events pool */
|
||||||
|
struct spdk_mempool *media_events_pool;
|
||||||
|
|
||||||
/* Statistics */
|
/* Statistics */
|
||||||
struct ftl_stats stats;
|
struct ftl_stats stats;
|
||||||
|
|
||||||
@ -247,6 +250,13 @@ struct ftl_nv_cache_header {
|
|||||||
uint32_t checksum;
|
uint32_t checksum;
|
||||||
} __attribute__((packed));
|
} __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);
|
typedef void (*ftl_restore_fn)(struct spdk_ftl_dev *, struct ftl_restore *, int);
|
||||||
|
|
||||||
void ftl_apply_limits(struct spdk_ftl_dev *dev);
|
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);
|
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,
|
int ftl_nv_cache_scrub(struct ftl_nv_cache *nv_cache, spdk_bdev_io_completion_cb cb_fn,
|
||||||
void *cb_arg);
|
void *cb_arg);
|
||||||
|
void ftl_get_media_events(struct spdk_ftl_dev *dev);
|
||||||
|
|
||||||
struct spdk_io_channel *
|
struct spdk_io_channel *
|
||||||
ftl_get_io_channel(const struct spdk_ftl_dev *dev);
|
ftl_get_io_channel(const struct spdk_ftl_dev *dev);
|
||||||
|
@ -216,10 +216,15 @@ ftl_dev_init_bands(struct spdk_ftl_dev *dev)
|
|||||||
static void
|
static void
|
||||||
ftl_bdev_event_cb(enum spdk_bdev_event_type type, struct spdk_bdev *bdev, void *event_ctx)
|
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) {
|
switch (type) {
|
||||||
case SPDK_BDEV_EVENT_REMOVE:
|
case SPDK_BDEV_EVENT_REMOVE:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
|
case SPDK_BDEV_EVENT_MEDIA_MANAGEMENT:
|
||||||
|
assert(bdev == spdk_bdev_desc_get_bdev(dev->base_bdev_desc));
|
||||||
|
ftl_get_media_events(dev);
|
||||||
default:
|
default:
|
||||||
break;
|
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));
|
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
|
static int
|
||||||
ftl_init_lba_map_pools(struct spdk_ftl_dev *dev)
|
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->lba_pool);
|
||||||
spdk_mempool_free(dev->nv_cache.md_pool);
|
spdk_mempool_free(dev->nv_cache.md_pool);
|
||||||
|
spdk_mempool_free(dev->media_events_pool);
|
||||||
if (dev->lba_request_pool) {
|
if (dev->lba_request_pool) {
|
||||||
spdk_mempool_obj_iter(dev->lba_request_pool, ftl_lba_map_request_dtor, NULL);
|
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;
|
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);
|
ftl_init_wptr_list(dev);
|
||||||
|
|
||||||
if (ftl_dev_init_bands(dev)) {
|
if (ftl_dev_init_bands(dev)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user