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