1*1d57628fSDongsheng Yang /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*1d57628fSDongsheng Yang #ifndef _PCACHE_CACHE_H 3*1d57628fSDongsheng Yang #define _PCACHE_CACHE_H 4*1d57628fSDongsheng Yang 5*1d57628fSDongsheng Yang #include "segment.h" 6*1d57628fSDongsheng Yang 7*1d57628fSDongsheng Yang /* Garbage collection thresholds */ 8*1d57628fSDongsheng Yang #define PCACHE_CACHE_GC_PERCENT_MIN 0 /* Minimum GC percentage */ 9*1d57628fSDongsheng Yang #define PCACHE_CACHE_GC_PERCENT_MAX 90 /* Maximum GC percentage */ 10*1d57628fSDongsheng Yang #define PCACHE_CACHE_GC_PERCENT_DEFAULT 70 /* Default GC percentage */ 11*1d57628fSDongsheng Yang 12*1d57628fSDongsheng Yang #define PCACHE_CACHE_SUBTREE_SIZE (4 * PCACHE_MB) /* 4MB total tree size */ 13*1d57628fSDongsheng Yang #define PCACHE_CACHE_SUBTREE_SIZE_MASK 0x3FFFFF /* Mask for tree size */ 14*1d57628fSDongsheng Yang #define PCACHE_CACHE_SUBTREE_SIZE_SHIFT 22 /* Bit shift for tree size */ 15*1d57628fSDongsheng Yang 16*1d57628fSDongsheng Yang /* Maximum number of keys per key set */ 17*1d57628fSDongsheng Yang #define PCACHE_KSET_KEYS_MAX 128 18*1d57628fSDongsheng Yang #define PCACHE_CACHE_SEGS_MAX (1024 * 1024) /* maximum cache size for each device is 16T */ 19*1d57628fSDongsheng Yang #define PCACHE_KSET_ONMEDIA_SIZE_MAX struct_size_t(struct pcache_cache_kset_onmedia, data, PCACHE_KSET_KEYS_MAX) 20*1d57628fSDongsheng Yang #define PCACHE_KSET_SIZE (sizeof(struct pcache_cache_kset) + sizeof(struct pcache_cache_key_onmedia) * PCACHE_KSET_KEYS_MAX) 21*1d57628fSDongsheng Yang 22*1d57628fSDongsheng Yang /* Maximum number of keys to clean in one round of clean_work */ 23*1d57628fSDongsheng Yang #define PCACHE_CLEAN_KEYS_MAX 10 24*1d57628fSDongsheng Yang 25*1d57628fSDongsheng Yang /* Writeback and garbage collection intervals in jiffies */ 26*1d57628fSDongsheng Yang #define PCACHE_CACHE_WRITEBACK_INTERVAL (5 * HZ) 27*1d57628fSDongsheng Yang #define PCACHE_CACHE_GC_INTERVAL (5 * HZ) 28*1d57628fSDongsheng Yang 29*1d57628fSDongsheng Yang /* Macro to get the cache key structure from an rb_node pointer */ 30*1d57628fSDongsheng Yang #define CACHE_KEY(node) (container_of(node, struct pcache_cache_key, rb_node)) 31*1d57628fSDongsheng Yang 32*1d57628fSDongsheng Yang struct pcache_cache_pos_onmedia { 33*1d57628fSDongsheng Yang struct pcache_meta_header header; 34*1d57628fSDongsheng Yang __u32 cache_seg_id; 35*1d57628fSDongsheng Yang __u32 seg_off; 36*1d57628fSDongsheng Yang }; 37*1d57628fSDongsheng Yang 38*1d57628fSDongsheng Yang /* Offset and size definitions for cache segment control */ 39*1d57628fSDongsheng Yang #define PCACHE_CACHE_SEG_CTRL_OFF (PCACHE_SEG_INFO_SIZE * PCACHE_META_INDEX_MAX) 40*1d57628fSDongsheng Yang #define PCACHE_CACHE_SEG_CTRL_SIZE (4 * PCACHE_KB) 41*1d57628fSDongsheng Yang 42*1d57628fSDongsheng Yang struct pcache_cache_seg_gen { 43*1d57628fSDongsheng Yang struct pcache_meta_header header; 44*1d57628fSDongsheng Yang __u64 gen; 45*1d57628fSDongsheng Yang }; 46*1d57628fSDongsheng Yang 47*1d57628fSDongsheng Yang /* Control structure for cache segments */ 48*1d57628fSDongsheng Yang struct pcache_cache_seg_ctrl { 49*1d57628fSDongsheng Yang struct pcache_cache_seg_gen gen[PCACHE_META_INDEX_MAX]; 50*1d57628fSDongsheng Yang __u64 res[64]; 51*1d57628fSDongsheng Yang }; 52*1d57628fSDongsheng Yang 53*1d57628fSDongsheng Yang #define PCACHE_CACHE_FLAGS_DATA_CRC BIT(0) 54*1d57628fSDongsheng Yang #define PCACHE_CACHE_FLAGS_INIT_DONE BIT(1) 55*1d57628fSDongsheng Yang 56*1d57628fSDongsheng Yang #define PCACHE_CACHE_FLAGS_CACHE_MODE_MASK GENMASK(5, 2) 57*1d57628fSDongsheng Yang #define PCACHE_CACHE_MODE_WRITEBACK 0 58*1d57628fSDongsheng Yang #define PCACHE_CACHE_MODE_WRITETHROUGH 1 59*1d57628fSDongsheng Yang #define PCACHE_CACHE_MODE_WRITEAROUND 2 60*1d57628fSDongsheng Yang #define PCACHE_CACHE_MODE_WRITEONLY 3 61*1d57628fSDongsheng Yang 62*1d57628fSDongsheng Yang #define PCACHE_CACHE_FLAGS_GC_PERCENT_MASK GENMASK(12, 6) 63*1d57628fSDongsheng Yang 64*1d57628fSDongsheng Yang struct pcache_cache_info { 65*1d57628fSDongsheng Yang struct pcache_meta_header header; 66*1d57628fSDongsheng Yang __u32 seg_id; 67*1d57628fSDongsheng Yang __u32 n_segs; 68*1d57628fSDongsheng Yang __u32 flags; 69*1d57628fSDongsheng Yang __u32 reserved; 70*1d57628fSDongsheng Yang }; 71*1d57628fSDongsheng Yang 72*1d57628fSDongsheng Yang struct pcache_cache_pos { 73*1d57628fSDongsheng Yang struct pcache_cache_segment *cache_seg; 74*1d57628fSDongsheng Yang u32 seg_off; 75*1d57628fSDongsheng Yang }; 76*1d57628fSDongsheng Yang 77*1d57628fSDongsheng Yang struct pcache_cache_segment { 78*1d57628fSDongsheng Yang struct pcache_cache *cache; 79*1d57628fSDongsheng Yang u32 cache_seg_id; /* Index in cache->segments */ 80*1d57628fSDongsheng Yang struct pcache_segment segment; 81*1d57628fSDongsheng Yang atomic_t refs; 82*1d57628fSDongsheng Yang 83*1d57628fSDongsheng Yang struct pcache_segment_info cache_seg_info; 84*1d57628fSDongsheng Yang struct mutex info_lock; 85*1d57628fSDongsheng Yang u32 info_index; 86*1d57628fSDongsheng Yang 87*1d57628fSDongsheng Yang spinlock_t gen_lock; 88*1d57628fSDongsheng Yang u64 gen; 89*1d57628fSDongsheng Yang u64 gen_seq; 90*1d57628fSDongsheng Yang u32 gen_index; 91*1d57628fSDongsheng Yang 92*1d57628fSDongsheng Yang struct pcache_cache_seg_ctrl *cache_seg_ctrl; 93*1d57628fSDongsheng Yang struct mutex ctrl_lock; 94*1d57628fSDongsheng Yang }; 95*1d57628fSDongsheng Yang 96*1d57628fSDongsheng Yang /* rbtree for cache entries */ 97*1d57628fSDongsheng Yang struct pcache_cache_subtree { 98*1d57628fSDongsheng Yang struct rb_root root; 99*1d57628fSDongsheng Yang spinlock_t tree_lock; 100*1d57628fSDongsheng Yang }; 101*1d57628fSDongsheng Yang 102*1d57628fSDongsheng Yang struct pcache_cache_tree { 103*1d57628fSDongsheng Yang struct pcache_cache *cache; 104*1d57628fSDongsheng Yang u32 n_subtrees; 105*1d57628fSDongsheng Yang mempool_t key_pool; 106*1d57628fSDongsheng Yang struct pcache_cache_subtree *subtrees; 107*1d57628fSDongsheng Yang }; 108*1d57628fSDongsheng Yang 109*1d57628fSDongsheng Yang extern struct kmem_cache *key_cache; 110*1d57628fSDongsheng Yang 111*1d57628fSDongsheng Yang struct pcache_cache_key { 112*1d57628fSDongsheng Yang struct pcache_cache_tree *cache_tree; 113*1d57628fSDongsheng Yang struct pcache_cache_subtree *cache_subtree; 114*1d57628fSDongsheng Yang struct kref ref; 115*1d57628fSDongsheng Yang struct rb_node rb_node; 116*1d57628fSDongsheng Yang struct list_head list_node; 117*1d57628fSDongsheng Yang u64 off; 118*1d57628fSDongsheng Yang u32 len; 119*1d57628fSDongsheng Yang u32 flags; 120*1d57628fSDongsheng Yang struct pcache_cache_pos cache_pos; 121*1d57628fSDongsheng Yang u64 seg_gen; 122*1d57628fSDongsheng Yang }; 123*1d57628fSDongsheng Yang 124*1d57628fSDongsheng Yang #define PCACHE_CACHE_KEY_FLAGS_EMPTY BIT(0) 125*1d57628fSDongsheng Yang #define PCACHE_CACHE_KEY_FLAGS_CLEAN BIT(1) 126*1d57628fSDongsheng Yang 127*1d57628fSDongsheng Yang struct pcache_cache_key_onmedia { 128*1d57628fSDongsheng Yang __u64 off; 129*1d57628fSDongsheng Yang __u32 len; 130*1d57628fSDongsheng Yang __u32 flags; 131*1d57628fSDongsheng Yang __u32 cache_seg_id; 132*1d57628fSDongsheng Yang __u32 cache_seg_off; 133*1d57628fSDongsheng Yang __u64 seg_gen; 134*1d57628fSDongsheng Yang __u32 data_crc; 135*1d57628fSDongsheng Yang __u32 reserved; 136*1d57628fSDongsheng Yang }; 137*1d57628fSDongsheng Yang 138*1d57628fSDongsheng Yang struct pcache_cache_kset_onmedia { 139*1d57628fSDongsheng Yang __u32 crc; 140*1d57628fSDongsheng Yang union { 141*1d57628fSDongsheng Yang __u32 key_num; 142*1d57628fSDongsheng Yang __u32 next_cache_seg_id; 143*1d57628fSDongsheng Yang }; 144*1d57628fSDongsheng Yang __u64 magic; 145*1d57628fSDongsheng Yang __u64 flags; 146*1d57628fSDongsheng Yang struct pcache_cache_key_onmedia data[]; 147*1d57628fSDongsheng Yang }; 148*1d57628fSDongsheng Yang 149*1d57628fSDongsheng Yang struct pcache_cache { 150*1d57628fSDongsheng Yang struct pcache_backing_dev *backing_dev; 151*1d57628fSDongsheng Yang struct pcache_cache_dev *cache_dev; 152*1d57628fSDongsheng Yang struct pcache_cache_ctrl *cache_ctrl; 153*1d57628fSDongsheng Yang u64 dev_size; 154*1d57628fSDongsheng Yang 155*1d57628fSDongsheng Yang struct pcache_cache_data_head __percpu *data_heads; 156*1d57628fSDongsheng Yang 157*1d57628fSDongsheng Yang spinlock_t key_head_lock; 158*1d57628fSDongsheng Yang struct pcache_cache_pos key_head; 159*1d57628fSDongsheng Yang u32 n_ksets; 160*1d57628fSDongsheng Yang struct pcache_cache_kset *ksets; 161*1d57628fSDongsheng Yang 162*1d57628fSDongsheng Yang struct mutex key_tail_lock; 163*1d57628fSDongsheng Yang struct pcache_cache_pos key_tail; 164*1d57628fSDongsheng Yang u64 key_tail_seq; 165*1d57628fSDongsheng Yang u32 key_tail_index; 166*1d57628fSDongsheng Yang 167*1d57628fSDongsheng Yang struct mutex dirty_tail_lock; 168*1d57628fSDongsheng Yang struct pcache_cache_pos dirty_tail; 169*1d57628fSDongsheng Yang u64 dirty_tail_seq; 170*1d57628fSDongsheng Yang u32 dirty_tail_index; 171*1d57628fSDongsheng Yang 172*1d57628fSDongsheng Yang struct pcache_cache_tree req_key_tree; 173*1d57628fSDongsheng Yang struct work_struct clean_work; 174*1d57628fSDongsheng Yang 175*1d57628fSDongsheng Yang struct mutex writeback_lock; 176*1d57628fSDongsheng Yang char wb_kset_onmedia_buf[PCACHE_KSET_ONMEDIA_SIZE_MAX]; 177*1d57628fSDongsheng Yang struct pcache_cache_tree writeback_key_tree; 178*1d57628fSDongsheng Yang struct delayed_work writeback_work; 179*1d57628fSDongsheng Yang struct { 180*1d57628fSDongsheng Yang atomic_t pending; 181*1d57628fSDongsheng Yang u32 advance; 182*1d57628fSDongsheng Yang int ret; 183*1d57628fSDongsheng Yang } writeback_ctx; 184*1d57628fSDongsheng Yang 185*1d57628fSDongsheng Yang char gc_kset_onmedia_buf[PCACHE_KSET_ONMEDIA_SIZE_MAX]; 186*1d57628fSDongsheng Yang struct delayed_work gc_work; 187*1d57628fSDongsheng Yang atomic_t gc_errors; 188*1d57628fSDongsheng Yang 189*1d57628fSDongsheng Yang struct mutex cache_info_lock; 190*1d57628fSDongsheng Yang struct pcache_cache_info cache_info; 191*1d57628fSDongsheng Yang struct pcache_cache_info *cache_info_addr; 192*1d57628fSDongsheng Yang u32 info_index; 193*1d57628fSDongsheng Yang 194*1d57628fSDongsheng Yang u32 n_segs; 195*1d57628fSDongsheng Yang unsigned long *seg_map; 196*1d57628fSDongsheng Yang u32 last_cache_seg; 197*1d57628fSDongsheng Yang bool cache_full; 198*1d57628fSDongsheng Yang spinlock_t seg_map_lock; 199*1d57628fSDongsheng Yang struct pcache_cache_segment *segments; 200*1d57628fSDongsheng Yang }; 201*1d57628fSDongsheng Yang 202*1d57628fSDongsheng Yang struct workqueue_struct *cache_get_wq(struct pcache_cache *cache); 203*1d57628fSDongsheng Yang 204*1d57628fSDongsheng Yang struct dm_pcache; 205*1d57628fSDongsheng Yang struct pcache_cache_options { 206*1d57628fSDongsheng Yang u32 cache_mode:4; 207*1d57628fSDongsheng Yang u32 data_crc:1; 208*1d57628fSDongsheng Yang }; 209*1d57628fSDongsheng Yang int pcache_cache_start(struct dm_pcache *pcache); 210*1d57628fSDongsheng Yang void pcache_cache_stop(struct dm_pcache *pcache); 211*1d57628fSDongsheng Yang 212*1d57628fSDongsheng Yang struct pcache_cache_ctrl { 213*1d57628fSDongsheng Yang /* Updated by gc_thread */ 214*1d57628fSDongsheng Yang struct pcache_cache_pos_onmedia key_tail_pos[PCACHE_META_INDEX_MAX]; 215*1d57628fSDongsheng Yang 216*1d57628fSDongsheng Yang /* Updated by writeback_thread */ 217*1d57628fSDongsheng Yang struct pcache_cache_pos_onmedia dirty_tail_pos[PCACHE_META_INDEX_MAX]; 218*1d57628fSDongsheng Yang }; 219*1d57628fSDongsheng Yang 220*1d57628fSDongsheng Yang struct pcache_cache_data_head { 221*1d57628fSDongsheng Yang struct pcache_cache_pos head_pos; 222*1d57628fSDongsheng Yang }; 223*1d57628fSDongsheng Yang 224*1d57628fSDongsheng Yang static inline u16 pcache_cache_get_gc_percent(struct pcache_cache *cache) 225*1d57628fSDongsheng Yang { 226*1d57628fSDongsheng Yang return FIELD_GET(PCACHE_CACHE_FLAGS_GC_PERCENT_MASK, cache->cache_info.flags); 227*1d57628fSDongsheng Yang } 228*1d57628fSDongsheng Yang 229*1d57628fSDongsheng Yang int pcache_cache_set_gc_percent(struct pcache_cache *cache, u8 percent); 230*1d57628fSDongsheng Yang 231*1d57628fSDongsheng Yang /* cache key */ 232*1d57628fSDongsheng Yang struct pcache_cache_key *cache_key_alloc(struct pcache_cache_tree *cache_tree, gfp_t gfp_mask); 233*1d57628fSDongsheng Yang void cache_key_init(struct pcache_cache_tree *cache_tree, struct pcache_cache_key *key); 234*1d57628fSDongsheng Yang void cache_key_get(struct pcache_cache_key *key); 235*1d57628fSDongsheng Yang void cache_key_put(struct pcache_cache_key *key); 236*1d57628fSDongsheng Yang int cache_key_append(struct pcache_cache *cache, struct pcache_cache_key *key, bool force_close); 237*1d57628fSDongsheng Yang void cache_key_insert(struct pcache_cache_tree *cache_tree, struct pcache_cache_key *key, bool fixup); 238*1d57628fSDongsheng Yang int cache_key_decode(struct pcache_cache *cache, 239*1d57628fSDongsheng Yang struct pcache_cache_key_onmedia *key_onmedia, 240*1d57628fSDongsheng Yang struct pcache_cache_key *key); 241*1d57628fSDongsheng Yang void cache_pos_advance(struct pcache_cache_pos *pos, u32 len); 242*1d57628fSDongsheng Yang 243*1d57628fSDongsheng Yang #define PCACHE_KSET_FLAGS_LAST BIT(0) 244*1d57628fSDongsheng Yang #define PCACHE_KSET_MAGIC 0x676894a64e164f1aULL 245*1d57628fSDongsheng Yang 246*1d57628fSDongsheng Yang struct pcache_cache_kset { 247*1d57628fSDongsheng Yang struct pcache_cache *cache; 248*1d57628fSDongsheng Yang spinlock_t kset_lock; 249*1d57628fSDongsheng Yang struct delayed_work flush_work; 250*1d57628fSDongsheng Yang struct pcache_cache_kset_onmedia kset_onmedia; 251*1d57628fSDongsheng Yang }; 252*1d57628fSDongsheng Yang 253*1d57628fSDongsheng Yang extern struct pcache_cache_kset_onmedia pcache_empty_kset; 254*1d57628fSDongsheng Yang 255*1d57628fSDongsheng Yang #define SUBTREE_WALK_RET_OK 0 256*1d57628fSDongsheng Yang #define SUBTREE_WALK_RET_ERR 1 257*1d57628fSDongsheng Yang #define SUBTREE_WALK_RET_NEED_KEY 2 258*1d57628fSDongsheng Yang #define SUBTREE_WALK_RET_NEED_REQ 3 259*1d57628fSDongsheng Yang #define SUBTREE_WALK_RET_RESEARCH 4 260*1d57628fSDongsheng Yang 261*1d57628fSDongsheng Yang struct pcache_cache_subtree_walk_ctx { 262*1d57628fSDongsheng Yang struct pcache_cache_tree *cache_tree; 263*1d57628fSDongsheng Yang struct rb_node *start_node; 264*1d57628fSDongsheng Yang struct pcache_request *pcache_req; 265*1d57628fSDongsheng Yang struct pcache_cache_key *key; 266*1d57628fSDongsheng Yang u32 req_done; 267*1d57628fSDongsheng Yang int ret; 268*1d57628fSDongsheng Yang 269*1d57628fSDongsheng Yang /* pre-allocated key and backing_dev_req */ 270*1d57628fSDongsheng Yang struct pcache_cache_key *pre_alloc_key; 271*1d57628fSDongsheng Yang struct pcache_backing_dev_req *pre_alloc_req; 272*1d57628fSDongsheng Yang 273*1d57628fSDongsheng Yang struct list_head *delete_key_list; 274*1d57628fSDongsheng Yang struct list_head *submit_req_list; 275*1d57628fSDongsheng Yang 276*1d57628fSDongsheng Yang /* 277*1d57628fSDongsheng Yang * |--------| key_tmp 278*1d57628fSDongsheng Yang * |====| key 279*1d57628fSDongsheng Yang */ 280*1d57628fSDongsheng Yang int (*before)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp, 281*1d57628fSDongsheng Yang struct pcache_cache_subtree_walk_ctx *ctx); 282*1d57628fSDongsheng Yang 283*1d57628fSDongsheng Yang /* 284*1d57628fSDongsheng Yang * |----------| key_tmp 285*1d57628fSDongsheng Yang * |=====| key 286*1d57628fSDongsheng Yang */ 287*1d57628fSDongsheng Yang int (*after)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp, 288*1d57628fSDongsheng Yang struct pcache_cache_subtree_walk_ctx *ctx); 289*1d57628fSDongsheng Yang 290*1d57628fSDongsheng Yang /* 291*1d57628fSDongsheng Yang * |----------------| key_tmp 292*1d57628fSDongsheng Yang * |===========| key 293*1d57628fSDongsheng Yang */ 294*1d57628fSDongsheng Yang int (*overlap_tail)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp, 295*1d57628fSDongsheng Yang struct pcache_cache_subtree_walk_ctx *ctx); 296*1d57628fSDongsheng Yang 297*1d57628fSDongsheng Yang /* 298*1d57628fSDongsheng Yang * |--------| key_tmp 299*1d57628fSDongsheng Yang * |==========| key 300*1d57628fSDongsheng Yang */ 301*1d57628fSDongsheng Yang int (*overlap_head)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp, 302*1d57628fSDongsheng Yang struct pcache_cache_subtree_walk_ctx *ctx); 303*1d57628fSDongsheng Yang 304*1d57628fSDongsheng Yang /* 305*1d57628fSDongsheng Yang * |----| key_tmp 306*1d57628fSDongsheng Yang * |==========| key 307*1d57628fSDongsheng Yang */ 308*1d57628fSDongsheng Yang int (*overlap_contain)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp, 309*1d57628fSDongsheng Yang struct pcache_cache_subtree_walk_ctx *ctx); 310*1d57628fSDongsheng Yang 311*1d57628fSDongsheng Yang /* 312*1d57628fSDongsheng Yang * |-----------| key_tmp 313*1d57628fSDongsheng Yang * |====| key 314*1d57628fSDongsheng Yang */ 315*1d57628fSDongsheng Yang int (*overlap_contained)(struct pcache_cache_key *key, struct pcache_cache_key *key_tmp, 316*1d57628fSDongsheng Yang struct pcache_cache_subtree_walk_ctx *ctx); 317*1d57628fSDongsheng Yang 318*1d57628fSDongsheng Yang int (*walk_finally)(struct pcache_cache_subtree_walk_ctx *ctx, int ret); 319*1d57628fSDongsheng Yang bool (*walk_done)(struct pcache_cache_subtree_walk_ctx *ctx); 320*1d57628fSDongsheng Yang }; 321*1d57628fSDongsheng Yang 322*1d57628fSDongsheng Yang int cache_subtree_walk(struct pcache_cache_subtree_walk_ctx *ctx); 323*1d57628fSDongsheng Yang struct rb_node *cache_subtree_search(struct pcache_cache_subtree *cache_subtree, struct pcache_cache_key *key, 324*1d57628fSDongsheng Yang struct rb_node **parentp, struct rb_node ***newp, 325*1d57628fSDongsheng Yang struct list_head *delete_key_list); 326*1d57628fSDongsheng Yang int cache_kset_close(struct pcache_cache *cache, struct pcache_cache_kset *kset); 327*1d57628fSDongsheng Yang void clean_fn(struct work_struct *work); 328*1d57628fSDongsheng Yang void kset_flush_fn(struct work_struct *work); 329*1d57628fSDongsheng Yang int cache_replay(struct pcache_cache *cache); 330*1d57628fSDongsheng Yang int cache_tree_init(struct pcache_cache *cache, struct pcache_cache_tree *cache_tree, u32 n_subtrees); 331*1d57628fSDongsheng Yang void cache_tree_clear(struct pcache_cache_tree *cache_tree); 332*1d57628fSDongsheng Yang void cache_tree_exit(struct pcache_cache_tree *cache_tree); 333*1d57628fSDongsheng Yang 334*1d57628fSDongsheng Yang /* cache segments */ 335*1d57628fSDongsheng Yang struct pcache_cache_segment *get_cache_segment(struct pcache_cache *cache); 336*1d57628fSDongsheng Yang int cache_seg_init(struct pcache_cache *cache, u32 seg_id, u32 cache_seg_id, 337*1d57628fSDongsheng Yang bool new_cache); 338*1d57628fSDongsheng Yang void cache_seg_get(struct pcache_cache_segment *cache_seg); 339*1d57628fSDongsheng Yang void cache_seg_put(struct pcache_cache_segment *cache_seg); 340*1d57628fSDongsheng Yang void cache_seg_set_next_seg(struct pcache_cache_segment *cache_seg, u32 seg_id); 341*1d57628fSDongsheng Yang 342*1d57628fSDongsheng Yang /* cache request*/ 343*1d57628fSDongsheng Yang int cache_flush(struct pcache_cache *cache); 344*1d57628fSDongsheng Yang void miss_read_end_work_fn(struct work_struct *work); 345*1d57628fSDongsheng Yang int pcache_cache_handle_req(struct pcache_cache *cache, struct pcache_request *pcache_req); 346*1d57628fSDongsheng Yang 347*1d57628fSDongsheng Yang /* gc */ 348*1d57628fSDongsheng Yang void pcache_cache_gc_fn(struct work_struct *work); 349*1d57628fSDongsheng Yang 350*1d57628fSDongsheng Yang /* writeback */ 351*1d57628fSDongsheng Yang void cache_writeback_exit(struct pcache_cache *cache); 352*1d57628fSDongsheng Yang int cache_writeback_init(struct pcache_cache *cache); 353*1d57628fSDongsheng Yang void cache_writeback_fn(struct work_struct *work); 354*1d57628fSDongsheng Yang 355*1d57628fSDongsheng Yang /* inline functions */ 356*1d57628fSDongsheng Yang static inline struct pcache_cache_subtree *get_subtree(struct pcache_cache_tree *cache_tree, u64 off) 357*1d57628fSDongsheng Yang { 358*1d57628fSDongsheng Yang if (cache_tree->n_subtrees == 1) 359*1d57628fSDongsheng Yang return &cache_tree->subtrees[0]; 360*1d57628fSDongsheng Yang 361*1d57628fSDongsheng Yang return &cache_tree->subtrees[off >> PCACHE_CACHE_SUBTREE_SIZE_SHIFT]; 362*1d57628fSDongsheng Yang } 363*1d57628fSDongsheng Yang 364*1d57628fSDongsheng Yang static inline void *cache_pos_addr(struct pcache_cache_pos *pos) 365*1d57628fSDongsheng Yang { 366*1d57628fSDongsheng Yang return (pos->cache_seg->segment.data + pos->seg_off); 367*1d57628fSDongsheng Yang } 368*1d57628fSDongsheng Yang 369*1d57628fSDongsheng Yang static inline void *get_key_head_addr(struct pcache_cache *cache) 370*1d57628fSDongsheng Yang { 371*1d57628fSDongsheng Yang return cache_pos_addr(&cache->key_head); 372*1d57628fSDongsheng Yang } 373*1d57628fSDongsheng Yang 374*1d57628fSDongsheng Yang static inline u32 get_kset_id(struct pcache_cache *cache, u64 off) 375*1d57628fSDongsheng Yang { 376*1d57628fSDongsheng Yang u32 rem; 377*1d57628fSDongsheng Yang div_u64_rem(off >> PCACHE_CACHE_SUBTREE_SIZE_SHIFT, cache->n_ksets, &rem); 378*1d57628fSDongsheng Yang return rem; 379*1d57628fSDongsheng Yang } 380*1d57628fSDongsheng Yang 381*1d57628fSDongsheng Yang static inline struct pcache_cache_kset *get_kset(struct pcache_cache *cache, u32 kset_id) 382*1d57628fSDongsheng Yang { 383*1d57628fSDongsheng Yang return (void *)cache->ksets + PCACHE_KSET_SIZE * kset_id; 384*1d57628fSDongsheng Yang } 385*1d57628fSDongsheng Yang 386*1d57628fSDongsheng Yang static inline struct pcache_cache_data_head *get_data_head(struct pcache_cache *cache) 387*1d57628fSDongsheng Yang { 388*1d57628fSDongsheng Yang return this_cpu_ptr(cache->data_heads); 389*1d57628fSDongsheng Yang } 390*1d57628fSDongsheng Yang 391*1d57628fSDongsheng Yang static inline bool cache_key_empty(struct pcache_cache_key *key) 392*1d57628fSDongsheng Yang { 393*1d57628fSDongsheng Yang return key->flags & PCACHE_CACHE_KEY_FLAGS_EMPTY; 394*1d57628fSDongsheng Yang } 395*1d57628fSDongsheng Yang 396*1d57628fSDongsheng Yang static inline bool cache_key_clean(struct pcache_cache_key *key) 397*1d57628fSDongsheng Yang { 398*1d57628fSDongsheng Yang return key->flags & PCACHE_CACHE_KEY_FLAGS_CLEAN; 399*1d57628fSDongsheng Yang } 400*1d57628fSDongsheng Yang 401*1d57628fSDongsheng Yang static inline void cache_pos_copy(struct pcache_cache_pos *dst, struct pcache_cache_pos *src) 402*1d57628fSDongsheng Yang { 403*1d57628fSDongsheng Yang memcpy(dst, src, sizeof(struct pcache_cache_pos)); 404*1d57628fSDongsheng Yang } 405*1d57628fSDongsheng Yang 406*1d57628fSDongsheng Yang /** 407*1d57628fSDongsheng Yang * cache_seg_is_ctrl_seg - Checks if a cache segment is a cache ctrl segment. 408*1d57628fSDongsheng Yang * @cache_seg_id: ID of the cache segment. 409*1d57628fSDongsheng Yang * 410*1d57628fSDongsheng Yang * Returns true if the cache segment ID corresponds to a cache ctrl segment. 411*1d57628fSDongsheng Yang * 412*1d57628fSDongsheng Yang * Note: We extend the segment control of the first cache segment 413*1d57628fSDongsheng Yang * (cache segment ID 0) to serve as the cache control (pcache_cache_ctrl) 414*1d57628fSDongsheng Yang * for the entire PCACHE cache. This function determines whether the given 415*1d57628fSDongsheng Yang * cache segment is the one storing the pcache_cache_ctrl information. 416*1d57628fSDongsheng Yang */ 417*1d57628fSDongsheng Yang static inline bool cache_seg_is_ctrl_seg(u32 cache_seg_id) 418*1d57628fSDongsheng Yang { 419*1d57628fSDongsheng Yang return (cache_seg_id == 0); 420*1d57628fSDongsheng Yang } 421*1d57628fSDongsheng Yang 422*1d57628fSDongsheng Yang /** 423*1d57628fSDongsheng Yang * cache_key_cutfront - Cuts a specified length from the front of a cache key. 424*1d57628fSDongsheng Yang * @key: Pointer to pcache_cache_key structure. 425*1d57628fSDongsheng Yang * @cut_len: Length to cut from the front. 426*1d57628fSDongsheng Yang * 427*1d57628fSDongsheng Yang * Advances the cache key position by cut_len and adjusts offset and length accordingly. 428*1d57628fSDongsheng Yang */ 429*1d57628fSDongsheng Yang static inline void cache_key_cutfront(struct pcache_cache_key *key, u32 cut_len) 430*1d57628fSDongsheng Yang { 431*1d57628fSDongsheng Yang if (key->cache_pos.cache_seg) 432*1d57628fSDongsheng Yang cache_pos_advance(&key->cache_pos, cut_len); 433*1d57628fSDongsheng Yang 434*1d57628fSDongsheng Yang key->off += cut_len; 435*1d57628fSDongsheng Yang key->len -= cut_len; 436*1d57628fSDongsheng Yang } 437*1d57628fSDongsheng Yang 438*1d57628fSDongsheng Yang /** 439*1d57628fSDongsheng Yang * cache_key_cutback - Cuts a specified length from the back of a cache key. 440*1d57628fSDongsheng Yang * @key: Pointer to pcache_cache_key structure. 441*1d57628fSDongsheng Yang * @cut_len: Length to cut from the back. 442*1d57628fSDongsheng Yang * 443*1d57628fSDongsheng Yang * Reduces the length of the cache key by cut_len. 444*1d57628fSDongsheng Yang */ 445*1d57628fSDongsheng Yang static inline void cache_key_cutback(struct pcache_cache_key *key, u32 cut_len) 446*1d57628fSDongsheng Yang { 447*1d57628fSDongsheng Yang key->len -= cut_len; 448*1d57628fSDongsheng Yang } 449*1d57628fSDongsheng Yang 450*1d57628fSDongsheng Yang static inline void cache_key_delete(struct pcache_cache_key *key) 451*1d57628fSDongsheng Yang { 452*1d57628fSDongsheng Yang struct pcache_cache_subtree *cache_subtree; 453*1d57628fSDongsheng Yang 454*1d57628fSDongsheng Yang cache_subtree = key->cache_subtree; 455*1d57628fSDongsheng Yang BUG_ON(!cache_subtree); 456*1d57628fSDongsheng Yang 457*1d57628fSDongsheng Yang rb_erase(&key->rb_node, &cache_subtree->root); 458*1d57628fSDongsheng Yang key->flags = 0; 459*1d57628fSDongsheng Yang cache_key_put(key); 460*1d57628fSDongsheng Yang } 461*1d57628fSDongsheng Yang 462*1d57628fSDongsheng Yang static inline bool cache_data_crc_on(struct pcache_cache *cache) 463*1d57628fSDongsheng Yang { 464*1d57628fSDongsheng Yang return (cache->cache_info.flags & PCACHE_CACHE_FLAGS_DATA_CRC); 465*1d57628fSDongsheng Yang } 466*1d57628fSDongsheng Yang 467*1d57628fSDongsheng Yang static inline u32 cache_mode_get(struct pcache_cache *cache) 468*1d57628fSDongsheng Yang { 469*1d57628fSDongsheng Yang return FIELD_GET(PCACHE_CACHE_FLAGS_CACHE_MODE_MASK, cache->cache_info.flags); 470*1d57628fSDongsheng Yang } 471*1d57628fSDongsheng Yang 472*1d57628fSDongsheng Yang static inline void cache_mode_set(struct pcache_cache *cache, u32 cache_mode) 473*1d57628fSDongsheng Yang { 474*1d57628fSDongsheng Yang cache->cache_info.flags &= ~PCACHE_CACHE_FLAGS_CACHE_MODE_MASK; 475*1d57628fSDongsheng Yang cache->cache_info.flags |= FIELD_PREP(PCACHE_CACHE_FLAGS_CACHE_MODE_MASK, cache_mode); 476*1d57628fSDongsheng Yang } 477*1d57628fSDongsheng Yang 478*1d57628fSDongsheng Yang /** 479*1d57628fSDongsheng Yang * cache_key_data_crc - Calculates CRC for data in a cache key. 480*1d57628fSDongsheng Yang * @key: Pointer to the pcache_cache_key structure. 481*1d57628fSDongsheng Yang * 482*1d57628fSDongsheng Yang * Returns the CRC-32 checksum of the data within the cache key's position. 483*1d57628fSDongsheng Yang */ 484*1d57628fSDongsheng Yang static inline u32 cache_key_data_crc(struct pcache_cache_key *key) 485*1d57628fSDongsheng Yang { 486*1d57628fSDongsheng Yang void *data; 487*1d57628fSDongsheng Yang 488*1d57628fSDongsheng Yang data = cache_pos_addr(&key->cache_pos); 489*1d57628fSDongsheng Yang 490*1d57628fSDongsheng Yang return crc32c(PCACHE_CRC_SEED, data, key->len); 491*1d57628fSDongsheng Yang } 492*1d57628fSDongsheng Yang 493*1d57628fSDongsheng Yang static inline u32 cache_kset_crc(struct pcache_cache_kset_onmedia *kset_onmedia) 494*1d57628fSDongsheng Yang { 495*1d57628fSDongsheng Yang u32 crc_size; 496*1d57628fSDongsheng Yang 497*1d57628fSDongsheng Yang if (kset_onmedia->flags & PCACHE_KSET_FLAGS_LAST) 498*1d57628fSDongsheng Yang crc_size = sizeof(struct pcache_cache_kset_onmedia) - 4; 499*1d57628fSDongsheng Yang else 500*1d57628fSDongsheng Yang crc_size = struct_size(kset_onmedia, data, kset_onmedia->key_num) - 4; 501*1d57628fSDongsheng Yang 502*1d57628fSDongsheng Yang return crc32c(PCACHE_CRC_SEED, (void *)kset_onmedia + 4, crc_size); 503*1d57628fSDongsheng Yang } 504*1d57628fSDongsheng Yang 505*1d57628fSDongsheng Yang static inline u32 get_kset_onmedia_size(struct pcache_cache_kset_onmedia *kset_onmedia) 506*1d57628fSDongsheng Yang { 507*1d57628fSDongsheng Yang return struct_size_t(struct pcache_cache_kset_onmedia, data, kset_onmedia->key_num); 508*1d57628fSDongsheng Yang } 509*1d57628fSDongsheng Yang 510*1d57628fSDongsheng Yang /** 511*1d57628fSDongsheng Yang * cache_seg_remain - Computes remaining space in a cache segment. 512*1d57628fSDongsheng Yang * @pos: Pointer to pcache_cache_pos structure. 513*1d57628fSDongsheng Yang * 514*1d57628fSDongsheng Yang * Returns the amount of remaining space in the segment data starting from 515*1d57628fSDongsheng Yang * the current position offset. 516*1d57628fSDongsheng Yang */ 517*1d57628fSDongsheng Yang static inline u32 cache_seg_remain(struct pcache_cache_pos *pos) 518*1d57628fSDongsheng Yang { 519*1d57628fSDongsheng Yang struct pcache_cache_segment *cache_seg; 520*1d57628fSDongsheng Yang struct pcache_segment *segment; 521*1d57628fSDongsheng Yang u32 seg_remain; 522*1d57628fSDongsheng Yang 523*1d57628fSDongsheng Yang cache_seg = pos->cache_seg; 524*1d57628fSDongsheng Yang segment = &cache_seg->segment; 525*1d57628fSDongsheng Yang seg_remain = segment->data_size - pos->seg_off; 526*1d57628fSDongsheng Yang 527*1d57628fSDongsheng Yang return seg_remain; 528*1d57628fSDongsheng Yang } 529*1d57628fSDongsheng Yang 530*1d57628fSDongsheng Yang /** 531*1d57628fSDongsheng Yang * cache_key_invalid - Checks if a cache key is invalid. 532*1d57628fSDongsheng Yang * @key: Pointer to pcache_cache_key structure. 533*1d57628fSDongsheng Yang * 534*1d57628fSDongsheng Yang * Returns true if the cache key is invalid due to its generation being 535*1d57628fSDongsheng Yang * less than the generation of its segment; otherwise returns false. 536*1d57628fSDongsheng Yang * 537*1d57628fSDongsheng Yang * When the GC (garbage collection) thread identifies a segment 538*1d57628fSDongsheng Yang * as reclaimable, it increments the segment's generation (gen). However, 539*1d57628fSDongsheng Yang * it does not immediately remove all related cache keys. When accessing 540*1d57628fSDongsheng Yang * such a cache key, this function can be used to determine if the cache 541*1d57628fSDongsheng Yang * key has already become invalid. 542*1d57628fSDongsheng Yang */ 543*1d57628fSDongsheng Yang static inline bool cache_key_invalid(struct pcache_cache_key *key) 544*1d57628fSDongsheng Yang { 545*1d57628fSDongsheng Yang if (cache_key_empty(key)) 546*1d57628fSDongsheng Yang return false; 547*1d57628fSDongsheng Yang 548*1d57628fSDongsheng Yang return (key->seg_gen < key->cache_pos.cache_seg->gen); 549*1d57628fSDongsheng Yang } 550*1d57628fSDongsheng Yang 551*1d57628fSDongsheng Yang /** 552*1d57628fSDongsheng Yang * cache_key_lstart - Retrieves the logical start offset of a cache key. 553*1d57628fSDongsheng Yang * @key: Pointer to pcache_cache_key structure. 554*1d57628fSDongsheng Yang * 555*1d57628fSDongsheng Yang * Returns the logical start offset for the cache key. 556*1d57628fSDongsheng Yang */ 557*1d57628fSDongsheng Yang static inline u64 cache_key_lstart(struct pcache_cache_key *key) 558*1d57628fSDongsheng Yang { 559*1d57628fSDongsheng Yang return key->off; 560*1d57628fSDongsheng Yang } 561*1d57628fSDongsheng Yang 562*1d57628fSDongsheng Yang /** 563*1d57628fSDongsheng Yang * cache_key_lend - Retrieves the logical end offset of a cache key. 564*1d57628fSDongsheng Yang * @key: Pointer to pcache_cache_key structure. 565*1d57628fSDongsheng Yang * 566*1d57628fSDongsheng Yang * Returns the logical end offset for the cache key. 567*1d57628fSDongsheng Yang */ 568*1d57628fSDongsheng Yang static inline u64 cache_key_lend(struct pcache_cache_key *key) 569*1d57628fSDongsheng Yang { 570*1d57628fSDongsheng Yang return key->off + key->len; 571*1d57628fSDongsheng Yang } 572*1d57628fSDongsheng Yang 573*1d57628fSDongsheng Yang static inline void cache_key_copy(struct pcache_cache_key *key_dst, struct pcache_cache_key *key_src) 574*1d57628fSDongsheng Yang { 575*1d57628fSDongsheng Yang key_dst->off = key_src->off; 576*1d57628fSDongsheng Yang key_dst->len = key_src->len; 577*1d57628fSDongsheng Yang key_dst->seg_gen = key_src->seg_gen; 578*1d57628fSDongsheng Yang key_dst->cache_tree = key_src->cache_tree; 579*1d57628fSDongsheng Yang key_dst->cache_subtree = key_src->cache_subtree; 580*1d57628fSDongsheng Yang key_dst->flags = key_src->flags; 581*1d57628fSDongsheng Yang 582*1d57628fSDongsheng Yang cache_pos_copy(&key_dst->cache_pos, &key_src->cache_pos); 583*1d57628fSDongsheng Yang } 584*1d57628fSDongsheng Yang 585*1d57628fSDongsheng Yang /** 586*1d57628fSDongsheng Yang * cache_pos_onmedia_crc - Calculates the CRC for an on-media cache position. 587*1d57628fSDongsheng Yang * @pos_om: Pointer to pcache_cache_pos_onmedia structure. 588*1d57628fSDongsheng Yang * 589*1d57628fSDongsheng Yang * Calculates the CRC-32 checksum of the position, excluding the first 4 bytes. 590*1d57628fSDongsheng Yang * Returns the computed CRC value. 591*1d57628fSDongsheng Yang */ 592*1d57628fSDongsheng Yang static inline u32 cache_pos_onmedia_crc(struct pcache_cache_pos_onmedia *pos_om) 593*1d57628fSDongsheng Yang { 594*1d57628fSDongsheng Yang return pcache_meta_crc(&pos_om->header, sizeof(struct pcache_cache_pos_onmedia)); 595*1d57628fSDongsheng Yang } 596*1d57628fSDongsheng Yang 597*1d57628fSDongsheng Yang void cache_pos_encode(struct pcache_cache *cache, 598*1d57628fSDongsheng Yang struct pcache_cache_pos_onmedia *pos_onmedia, 599*1d57628fSDongsheng Yang struct pcache_cache_pos *pos, u64 seq, u32 *index); 600*1d57628fSDongsheng Yang int cache_pos_decode(struct pcache_cache *cache, 601*1d57628fSDongsheng Yang struct pcache_cache_pos_onmedia *pos_onmedia, 602*1d57628fSDongsheng Yang struct pcache_cache_pos *pos, u64 *seq, u32 *index); 603*1d57628fSDongsheng Yang 604*1d57628fSDongsheng Yang static inline void cache_encode_key_tail(struct pcache_cache *cache) 605*1d57628fSDongsheng Yang { 606*1d57628fSDongsheng Yang cache_pos_encode(cache, cache->cache_ctrl->key_tail_pos, 607*1d57628fSDongsheng Yang &cache->key_tail, ++cache->key_tail_seq, 608*1d57628fSDongsheng Yang &cache->key_tail_index); 609*1d57628fSDongsheng Yang } 610*1d57628fSDongsheng Yang 611*1d57628fSDongsheng Yang static inline int cache_decode_key_tail(struct pcache_cache *cache) 612*1d57628fSDongsheng Yang { 613*1d57628fSDongsheng Yang return cache_pos_decode(cache, cache->cache_ctrl->key_tail_pos, 614*1d57628fSDongsheng Yang &cache->key_tail, &cache->key_tail_seq, 615*1d57628fSDongsheng Yang &cache->key_tail_index); 616*1d57628fSDongsheng Yang } 617*1d57628fSDongsheng Yang 618*1d57628fSDongsheng Yang static inline void cache_encode_dirty_tail(struct pcache_cache *cache) 619*1d57628fSDongsheng Yang { 620*1d57628fSDongsheng Yang cache_pos_encode(cache, cache->cache_ctrl->dirty_tail_pos, 621*1d57628fSDongsheng Yang &cache->dirty_tail, ++cache->dirty_tail_seq, 622*1d57628fSDongsheng Yang &cache->dirty_tail_index); 623*1d57628fSDongsheng Yang } 624*1d57628fSDongsheng Yang 625*1d57628fSDongsheng Yang static inline int cache_decode_dirty_tail(struct pcache_cache *cache) 626*1d57628fSDongsheng Yang { 627*1d57628fSDongsheng Yang return cache_pos_decode(cache, cache->cache_ctrl->dirty_tail_pos, 628*1d57628fSDongsheng Yang &cache->dirty_tail, &cache->dirty_tail_seq, 629*1d57628fSDongsheng Yang &cache->dirty_tail_index); 630*1d57628fSDongsheng Yang } 631*1d57628fSDongsheng Yang 632*1d57628fSDongsheng Yang int pcache_cache_init(void); 633*1d57628fSDongsheng Yang void pcache_cache_exit(void); 634*1d57628fSDongsheng Yang #endif /* _PCACHE_CACHE_H */ 635