1488570ebSJim Harris /* SPDX-License-Identifier: BSD-3-Clause 2a6dbe372Spaul luse * Copyright (C) 2018 Intel Corporation. 307fe6a43SSeth Howell * All rights reserved. 407fe6a43SSeth Howell */ 507fe6a43SSeth Howell 607fe6a43SSeth Howell #ifndef SPDK_VBDEV_OCF_H 707fe6a43SSeth Howell #define SPDK_VBDEV_OCF_H 807fe6a43SSeth Howell 907fe6a43SSeth Howell #include <ocf/ocf.h> 1007fe6a43SSeth Howell 1107fe6a43SSeth Howell #include "spdk/bdev.h" 1207fe6a43SSeth Howell #include "spdk/bdev_module.h" 1307fe6a43SSeth Howell 1407fe6a43SSeth Howell #define VBDEV_OCF_MD_MAX_LEN 4096 1507fe6a43SSeth Howell 1607fe6a43SSeth Howell struct vbdev_ocf; 1707fe6a43SSeth Howell 1807fe6a43SSeth Howell /* Context for OCF queue poller 1907fe6a43SSeth Howell * Used for mapping SPDK threads to OCF queues */ 20af039a7aSyidong0635 struct vbdev_ocf_qctx { 2107fe6a43SSeth Howell /* OCF queue. Contains OCF requests */ 2207fe6a43SSeth Howell struct ocf_queue *queue; 2307fe6a43SSeth Howell /* Poller for OCF queue. Runs OCF requests */ 2407fe6a43SSeth Howell struct spdk_poller *poller; 2507fe6a43SSeth Howell /* Reference to parent vbdev */ 2607fe6a43SSeth Howell struct vbdev_ocf *vbdev; 2707fe6a43SSeth Howell /* Base devices channels */ 2807fe6a43SSeth Howell struct spdk_io_channel *cache_ch; 2907fe6a43SSeth Howell struct spdk_io_channel *core_ch; 305817a1cfSMarcin Dziegielewski /* If true, we have to free this context on queue stop */ 315817a1cfSMarcin Dziegielewski bool allocated; 3207fe6a43SSeth Howell /* Link to per-bdev list of queue contexts */ 33af039a7aSyidong0635 TAILQ_ENTRY(vbdev_ocf_qctx) tailq; 3407fe6a43SSeth Howell }; 3507fe6a43SSeth Howell 3607fe6a43SSeth Howell /* Important states */ 3707fe6a43SSeth Howell struct vbdev_ocf_state { 381ee2e81bSMarcin Dziegielewski /* From the moment when clean delete started */ 391ee2e81bSMarcin Dziegielewski bool doing_clean_delete; 4007fe6a43SSeth Howell /* From the moment when finish started */ 4107fe6a43SSeth Howell bool doing_finish; 421960ef16SJosh Soref /* From the moment when reset IO received, until it is completed */ 4307fe6a43SSeth Howell bool doing_reset; 4407fe6a43SSeth Howell /* From the moment when exp_bdev is registered */ 4507fe6a43SSeth Howell bool started; 46d1c9e2f7SMarcin Dziegielewski /* From the moment when register path started */ 47d1c9e2f7SMarcin Dziegielewski bool starting; 4807fe6a43SSeth Howell /* Status of last attempt for stopping this device */ 4907fe6a43SSeth Howell int stop_status; 5007fe6a43SSeth Howell }; 5107fe6a43SSeth Howell 5207fe6a43SSeth Howell /* 5307fe6a43SSeth Howell * OCF cache configuration options 5407fe6a43SSeth Howell */ 5507fe6a43SSeth Howell struct vbdev_ocf_config { 5607fe6a43SSeth Howell /* Initial cache configuration */ 5707fe6a43SSeth Howell struct ocf_mngt_cache_config cache; 5807fe6a43SSeth Howell 5907fe6a43SSeth Howell /* Cache device config */ 60*37975647SAmir Haroush struct ocf_mngt_cache_attach_config attach; 6107fe6a43SSeth Howell 6207fe6a43SSeth Howell /* Core initial config */ 6307fe6a43SSeth Howell struct ocf_mngt_core_config core; 6407fe6a43SSeth Howell 6507fe6a43SSeth Howell /* Load flag, if set to true, then we will try load cache instance from disk, 6607fe6a43SSeth Howell * otherwise we will create new cache on that disk */ 6707fe6a43SSeth Howell bool loadq; 6807fe6a43SSeth Howell }; 6907fe6a43SSeth Howell 7007fe6a43SSeth Howell /* Types for management operations */ 7107fe6a43SSeth Howell typedef void (*vbdev_ocf_mngt_fn)(struct vbdev_ocf *); 7207fe6a43SSeth Howell typedef void (*vbdev_ocf_mngt_callback)(int, struct vbdev_ocf *, void *); 7307fe6a43SSeth Howell 7407fe6a43SSeth Howell /* Context for asynchronous management operations 7507fe6a43SSeth Howell * Single management operation usually contains a list of sub procedures, 7607fe6a43SSeth Howell * this structure handles sharing between those sub procedures */ 7707fe6a43SSeth Howell struct vbdev_ocf_mngt_ctx { 7807fe6a43SSeth Howell /* Pointer to function that is currently being executed 7907fe6a43SSeth Howell * It gets incremented on each step until it dereferences to NULL */ 8007fe6a43SSeth Howell vbdev_ocf_mngt_fn *current_step; 8107fe6a43SSeth Howell 8207fe6a43SSeth Howell /* Function that gets invoked by poller on each iteration */ 8307fe6a43SSeth Howell vbdev_ocf_mngt_fn poller_fn; 8407fe6a43SSeth Howell /* Poller timeout time stamp - when the poller should stop with error */ 8507fe6a43SSeth Howell uint64_t timeout_ts; 8607fe6a43SSeth Howell 8707fe6a43SSeth Howell /* Status of management operation */ 8807fe6a43SSeth Howell int status; 8907fe6a43SSeth Howell 9007fe6a43SSeth Howell /* External callback and its argument */ 9107fe6a43SSeth Howell vbdev_ocf_mngt_callback cb; 9207fe6a43SSeth Howell void *cb_arg; 9307fe6a43SSeth Howell }; 9407fe6a43SSeth Howell 9507fe6a43SSeth Howell /* Base device info */ 9607fe6a43SSeth Howell struct vbdev_ocf_base { 9707fe6a43SSeth Howell /* OCF internal name */ 9807fe6a43SSeth Howell char *name; 9907fe6a43SSeth Howell 10007fe6a43SSeth Howell /* True if this is a caching device */ 10107fe6a43SSeth Howell bool is_cache; 10207fe6a43SSeth Howell 10307fe6a43SSeth Howell /* Connected SPDK block device */ 10407fe6a43SSeth Howell struct spdk_bdev *bdev; 10507fe6a43SSeth Howell 10607fe6a43SSeth Howell /* SPDK device io handle */ 10707fe6a43SSeth Howell struct spdk_bdev_desc *desc; 10807fe6a43SSeth Howell 10907fe6a43SSeth Howell /* True if SPDK bdev has been claimed and opened for writing */ 11007fe6a43SSeth Howell bool attached; 11107fe6a43SSeth Howell 11207fe6a43SSeth Howell /* Channel for cleaner operations */ 11307fe6a43SSeth Howell struct spdk_io_channel *management_channel; 11407fe6a43SSeth Howell 11507fe6a43SSeth Howell /* Reference to main vbdev */ 11607fe6a43SSeth Howell struct vbdev_ocf *parent; 117b3be320dSGangCao 118b3be320dSGangCao /* thread where base device is opened */ 119b3be320dSGangCao struct spdk_thread *thread; 12007fe6a43SSeth Howell }; 12107fe6a43SSeth Howell 12207fe6a43SSeth Howell /* 12307fe6a43SSeth Howell * The main information provider 12407fe6a43SSeth Howell * It's also registered as io_device 12507fe6a43SSeth Howell */ 12607fe6a43SSeth Howell struct vbdev_ocf { 12707fe6a43SSeth Howell /* Exposed unique name */ 12807fe6a43SSeth Howell char *name; 12907fe6a43SSeth Howell 13007fe6a43SSeth Howell /* Base bdevs */ 13107fe6a43SSeth Howell struct vbdev_ocf_base cache; 13207fe6a43SSeth Howell struct vbdev_ocf_base core; 13307fe6a43SSeth Howell 13407fe6a43SSeth Howell /* Base bdevs OCF objects */ 13507fe6a43SSeth Howell ocf_cache_t ocf_cache; 13607fe6a43SSeth Howell ocf_core_t ocf_core; 13707fe6a43SSeth Howell 13807fe6a43SSeth Howell /* Parameters */ 13907fe6a43SSeth Howell struct vbdev_ocf_config cfg; 14007fe6a43SSeth Howell struct vbdev_ocf_state state; 14107fe6a43SSeth Howell 14207fe6a43SSeth Howell /* Management context */ 14307fe6a43SSeth Howell struct vbdev_ocf_mngt_ctx mngt_ctx; 1448000cedbSRafal Stefanowski 1458000cedbSRafal Stefanowski /* Cache context */ 14607fe6a43SSeth Howell struct vbdev_ocf_cache_ctx *cache_ctx; 14707fe6a43SSeth Howell 1488000cedbSRafal Stefanowski /* Status of flushing operation */ 1498000cedbSRafal Stefanowski struct { 1508000cedbSRafal Stefanowski bool in_progress; 1518000cedbSRafal Stefanowski int status; 1528000cedbSRafal Stefanowski } flush; 1538000cedbSRafal Stefanowski 15407fe6a43SSeth Howell /* Exposed SPDK bdev. Registered in bdev layer */ 15507fe6a43SSeth Howell struct spdk_bdev exp_bdev; 15607fe6a43SSeth Howell 15707fe6a43SSeth Howell /* OCF uuid for core device of this vbdev */ 15807fe6a43SSeth Howell char uuid[VBDEV_OCF_MD_MAX_LEN]; 15907fe6a43SSeth Howell 16007fe6a43SSeth Howell /* Link to global list of this type structures */ 16107fe6a43SSeth Howell TAILQ_ENTRY(vbdev_ocf) tailq; 16207fe6a43SSeth Howell }; 16307fe6a43SSeth Howell 16407fe6a43SSeth Howell void vbdev_ocf_construct( 16507fe6a43SSeth Howell const char *vbdev_name, 16607fe6a43SSeth Howell const char *cache_mode_name, 1674d91b4efSrafalste const uint64_t cache_line_size, 16807fe6a43SSeth Howell const char *cache_name, 16907fe6a43SSeth Howell const char *core_name, 17007fe6a43SSeth Howell bool loadq, 17107fe6a43SSeth Howell void (*cb)(int, struct vbdev_ocf *, void *), 17207fe6a43SSeth Howell void *cb_arg); 17307fe6a43SSeth Howell 17407fe6a43SSeth Howell /* If vbdev is online, return its object */ 17507fe6a43SSeth Howell struct vbdev_ocf *vbdev_ocf_get_by_name(const char *name); 17607fe6a43SSeth Howell 17707fe6a43SSeth Howell /* Return matching base if parent vbdev is online */ 17807fe6a43SSeth Howell struct vbdev_ocf_base *vbdev_ocf_get_base_by_name(const char *name); 17907fe6a43SSeth Howell 18007fe6a43SSeth Howell /* Stop OCF cache and unregister SPDK bdev */ 18107fe6a43SSeth Howell int vbdev_ocf_delete(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_arg); 18207fe6a43SSeth Howell 1831ee2e81bSMarcin Dziegielewski int vbdev_ocf_delete_clean(struct vbdev_ocf *vbdev, void (*cb)(void *, int), void *cb_arg); 1841ee2e81bSMarcin Dziegielewski 1855bdaec63SRafal Stefanowski /* Set new cache mode on OCF cache */ 1865bdaec63SRafal Stefanowski void vbdev_ocf_set_cache_mode( 1875bdaec63SRafal Stefanowski struct vbdev_ocf *vbdev, 1885bdaec63SRafal Stefanowski const char *cache_mode_name, 1895bdaec63SRafal Stefanowski void (*cb)(int, struct vbdev_ocf *, void *), 1905bdaec63SRafal Stefanowski void *cb_arg); 1915bdaec63SRafal Stefanowski 192494b1ba8SRafal Stefanowski /* Set sequential cutoff parameters on OCF cache */ 193494b1ba8SRafal Stefanowski void vbdev_ocf_set_seqcutoff( 194494b1ba8SRafal Stefanowski struct vbdev_ocf *vbdev, 195494b1ba8SRafal Stefanowski const char *policy_name, 196494b1ba8SRafal Stefanowski uint32_t threshold, 197494b1ba8SRafal Stefanowski uint32_t promotion_count, 198494b1ba8SRafal Stefanowski void (*cb)(int, void *), 199494b1ba8SRafal Stefanowski void *cb_arg); 200494b1ba8SRafal Stefanowski 20107fe6a43SSeth Howell typedef void (*vbdev_ocf_foreach_fn)(struct vbdev_ocf *, void *); 20207fe6a43SSeth Howell 20307fe6a43SSeth Howell /* Execute fn for each OCF device that is online or waits for base devices */ 20407fe6a43SSeth Howell void vbdev_ocf_foreach(vbdev_ocf_foreach_fn fn, void *ctx); 20507fe6a43SSeth Howell 20607fe6a43SSeth Howell #endif 207