Commit c3d044cb authored by Vitaliy Mysak's avatar Vitaliy Mysak Committed by Darek Stojaczyk
Browse files

ocf: use vbdev_ocf_mngt_ interface in register path



This patch is a preparation for adopting ocf_cache_trylock() function.
Register OCF bdev path uses vbdev_ocf_mngt_ interface now
Register stays synchronous blocking operation in this patch,
 but with adoption of ocf_cache_trylock() function,
 register will be asynchronous, in which case we
 want to use mngt_ interface.

This series of OCF patches will enable WriteBack support for OCF bdev.
There is a lot of preparation before we will be able
 to actually implement WriteBack.
Dependencies look like this:
- WriteBack
  - Cleaner
    - trylock
  - Persistent metadata
    - asynchronous management API

Cleaner is a background agent that does synchronization
 of data between cache and its cores.
 Cleaner usually runs every ~30 seconds to perform cleaning.
 The synchronization is a simmilar operation to OCF management flushes.
We need cleaner for WriteBack because only WriteBack mode
 produces dirty data that cleaner needs to deal with.
Cleaner requires adopting trylock() because in current version
 cleaner uses management lock when performs cleaning,
 which may lead to deadlocks if cleaner runs on
 the same thread as management operations.

Peristent metadata is functionality of OCF
 that allows to restore cache state after shutdown
We need persistent metadata in context of shutdown
 with some data being dirty which may only happen
 when using WriteBack mode
Support for persistent metadata requieres
 asynchronous OCF API because in current version
 we will have a deadlock during metadata initialization
 because it is required to be done on different thread
 than cache initialization.

Change-Id: I45d84a5fa0c96581d522050dad186b06d489226e
Signed-off-by: default avatarVitaliy Mysak <vitaliy.mysak@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/455225


Reviewed-by: default avatarDarek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-by: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
parent bdbd32b4
Loading
Loading
Loading
Loading
+47 −34
Original line number Diff line number Diff line
@@ -729,37 +729,42 @@ io_device_destroy_cb(void *io_device, void *ctx_buf)
}

/* Add core for existing OCF cache instance */
static int
static void
add_core(struct vbdev_ocf *vbdev)
{
	int rc;

	rc = ocf_mngt_cache_lock(vbdev->ocf_cache);
	if (rc) {
		return rc;
		vbdev->mngt_ctx.status = rc;
		vbdev_ocf_mngt_stop(vbdev);
		return;
	}

	rc = ocf_mngt_cache_add_core(vbdev->ocf_cache, &vbdev->ocf_core, &vbdev->cfg.core);
	ocf_mngt_cache_unlock(vbdev->ocf_cache);
	if (rc) {
		SPDK_ERRLOG("Failed to add core device to cache instance\n");
		return rc;
		vbdev->mngt_ctx.status = rc;
		vbdev_ocf_mngt_stop(vbdev);
		return;
	}

	vbdev->core.id = ocf_core_get_id(vbdev->ocf_core);

	return 0;
	vbdev_ocf_mngt_continue(vbdev, 0);
}

/* Start OCF cache, attach caching device */
static int
static void
start_cache(struct vbdev_ocf *vbdev)
{
	ocf_cache_t existing;
	int rc;

	if (vbdev->ocf_cache) {
		return -EALREADY;
		vbdev->mngt_ctx.status = -EALREADY;
		vbdev_ocf_mngt_stop(vbdev);
		return;
	}

	existing = get_other_cache_instance(vbdev);
@@ -767,13 +772,16 @@ start_cache(struct vbdev_ocf *vbdev)
		SPDK_NOTICELOG("OCF bdev %s connects to existing cache device %s\n",
			       vbdev->name, vbdev->cache.name);
		vbdev->ocf_cache = existing;
		return 0;
		vbdev_ocf_mngt_continue(vbdev, 0);
		return;
	}

	rc = ocf_mngt_cache_start(vbdev_ocf_ctx, &vbdev->ocf_cache, &vbdev->cfg.cache);
	if (rc) {
		SPDK_ERRLOG("Failed to start cache instance\n");
		return rc;
		vbdev->mngt_ctx.status = rc;
		vbdev_ocf_mngt_stop(vbdev);
		return;
	}
	vbdev->cache.id = ocf_cache_get_id(vbdev->ocf_cache);

@@ -781,37 +789,20 @@ start_cache(struct vbdev_ocf *vbdev)
	ocf_mngt_cache_unlock(vbdev->ocf_cache);
	if (rc) {
		SPDK_ERRLOG("Failed to attach cache device\n");
		return rc;
		vbdev->mngt_ctx.status = rc;
		vbdev_ocf_mngt_stop(vbdev);
		return;
	}

	return 0;
	vbdev_ocf_mngt_continue(vbdev, 0);
}

/* Start OCF cache and register vbdev_ocf at bdev layer */
static void
register_vbdev(struct vbdev_ocf *vbdev, void (*cb)(int, struct vbdev_ocf *, void *), void *cb_arg)
finish_register(struct vbdev_ocf *vbdev)
{
	int result;

	if (!vbdev->cache.attached || !vbdev->core.attached || vbdev->state.started) {
		result = -EPERM;
		goto callback;
	}

	result = start_cache(vbdev);
	if (result) {
		SPDK_ERRLOG("Failed to start cache instance\n");
		goto callback;
	}

	result = add_core(vbdev);
	if (result) {
		SPDK_ERRLOG("Failed to add core to cache instance\n");
		goto callback;
	}

	/* Create exported spdk object */

	/* Copy properties of the base bdev */
	vbdev->exp_bdev.blocklen = vbdev->core.bdev->blocklen;
	vbdev->exp_bdev.write_cache = vbdev->core.bdev->write_cache;
@@ -831,13 +822,35 @@ register_vbdev(struct vbdev_ocf *vbdev, void (*cb)(int, struct vbdev_ocf *, void
	result = spdk_bdev_register(&vbdev->exp_bdev);
	if (result) {
		SPDK_ERRLOG("Could not register exposed bdev\n");
		goto callback;
	}

	vbdev->state.started = true;
	vbdev_ocf_mngt_continue(vbdev, result);
}

callback:
	cb(result, vbdev, cb_arg);
/* Procedures called during register operation */
vbdev_ocf_mngt_fn register_path[] = {
	start_cache,
	add_core,
	finish_register,
	NULL
};

/* Start register procedure */
static void
register_vbdev(struct vbdev_ocf *vbdev, vbdev_ocf_mngt_callback cb, void *cb_arg)
{
	int rc;

	if (!(vbdev->core.attached && vbdev->cache.attached) || vbdev->state.started) {
		cb(-EPERM, vbdev, cb_arg);
		return;
	}

	rc = vbdev_ocf_mngt_start(vbdev, register_path, cb, cb_arg);
	if (rc) {
		cb(rc, vbdev, cb_arg);
	}
}

/* Init OCF configuration options