1*1d57628fSDongsheng Yang // SPDX-License-Identifier: GPL-2.0-or-later 2*1d57628fSDongsheng Yang 3*1d57628fSDongsheng Yang #include "cache_dev.h" 4*1d57628fSDongsheng Yang #include "cache.h" 5*1d57628fSDongsheng Yang #include "backing_dev.h" 6*1d57628fSDongsheng Yang #include "dm_pcache.h" 7*1d57628fSDongsheng Yang 8*1d57628fSDongsheng Yang static inline struct pcache_segment_info *get_seg_info_addr(struct pcache_cache_segment *cache_seg) 9*1d57628fSDongsheng Yang { 10*1d57628fSDongsheng Yang struct pcache_segment_info *seg_info_addr; 11*1d57628fSDongsheng Yang u32 seg_id = cache_seg->segment.seg_id; 12*1d57628fSDongsheng Yang void *seg_addr; 13*1d57628fSDongsheng Yang 14*1d57628fSDongsheng Yang seg_addr = CACHE_DEV_SEGMENT(cache_seg->cache->cache_dev, seg_id); 15*1d57628fSDongsheng Yang seg_info_addr = seg_addr + PCACHE_SEG_INFO_SIZE * cache_seg->info_index; 16*1d57628fSDongsheng Yang 17*1d57628fSDongsheng Yang return seg_info_addr; 18*1d57628fSDongsheng Yang } 19*1d57628fSDongsheng Yang 20*1d57628fSDongsheng Yang static void cache_seg_info_write(struct pcache_cache_segment *cache_seg) 21*1d57628fSDongsheng Yang { 22*1d57628fSDongsheng Yang struct pcache_segment_info *seg_info_addr; 23*1d57628fSDongsheng Yang struct pcache_segment_info *seg_info = &cache_seg->cache_seg_info; 24*1d57628fSDongsheng Yang 25*1d57628fSDongsheng Yang mutex_lock(&cache_seg->info_lock); 26*1d57628fSDongsheng Yang seg_info->header.seq++; 27*1d57628fSDongsheng Yang seg_info->header.crc = pcache_meta_crc(&seg_info->header, sizeof(struct pcache_segment_info)); 28*1d57628fSDongsheng Yang 29*1d57628fSDongsheng Yang seg_info_addr = get_seg_info_addr(cache_seg); 30*1d57628fSDongsheng Yang memcpy_flushcache(seg_info_addr, seg_info, sizeof(struct pcache_segment_info)); 31*1d57628fSDongsheng Yang pmem_wmb(); 32*1d57628fSDongsheng Yang 33*1d57628fSDongsheng Yang cache_seg->info_index = (cache_seg->info_index + 1) % PCACHE_META_INDEX_MAX; 34*1d57628fSDongsheng Yang mutex_unlock(&cache_seg->info_lock); 35*1d57628fSDongsheng Yang } 36*1d57628fSDongsheng Yang 37*1d57628fSDongsheng Yang static int cache_seg_info_load(struct pcache_cache_segment *cache_seg) 38*1d57628fSDongsheng Yang { 39*1d57628fSDongsheng Yang struct pcache_segment_info *cache_seg_info_addr_base, *cache_seg_info_addr; 40*1d57628fSDongsheng Yang struct pcache_cache_dev *cache_dev = cache_seg->cache->cache_dev; 41*1d57628fSDongsheng Yang struct dm_pcache *pcache = CACHE_DEV_TO_PCACHE(cache_dev); 42*1d57628fSDongsheng Yang u32 seg_id = cache_seg->segment.seg_id; 43*1d57628fSDongsheng Yang int ret = 0; 44*1d57628fSDongsheng Yang 45*1d57628fSDongsheng Yang cache_seg_info_addr_base = CACHE_DEV_SEGMENT(cache_dev, seg_id); 46*1d57628fSDongsheng Yang 47*1d57628fSDongsheng Yang mutex_lock(&cache_seg->info_lock); 48*1d57628fSDongsheng Yang cache_seg_info_addr = pcache_meta_find_latest(&cache_seg_info_addr_base->header, 49*1d57628fSDongsheng Yang sizeof(struct pcache_segment_info), 50*1d57628fSDongsheng Yang PCACHE_SEG_INFO_SIZE, 51*1d57628fSDongsheng Yang &cache_seg->cache_seg_info); 52*1d57628fSDongsheng Yang if (IS_ERR(cache_seg_info_addr)) { 53*1d57628fSDongsheng Yang ret = PTR_ERR(cache_seg_info_addr); 54*1d57628fSDongsheng Yang goto out; 55*1d57628fSDongsheng Yang } else if (!cache_seg_info_addr) { 56*1d57628fSDongsheng Yang ret = -EIO; 57*1d57628fSDongsheng Yang goto out; 58*1d57628fSDongsheng Yang } 59*1d57628fSDongsheng Yang cache_seg->info_index = cache_seg_info_addr - cache_seg_info_addr_base; 60*1d57628fSDongsheng Yang out: 61*1d57628fSDongsheng Yang mutex_unlock(&cache_seg->info_lock); 62*1d57628fSDongsheng Yang 63*1d57628fSDongsheng Yang if (ret) 64*1d57628fSDongsheng Yang pcache_dev_err(pcache, "can't read segment info of segment: %u, ret: %d\n", 65*1d57628fSDongsheng Yang cache_seg->segment.seg_id, ret); 66*1d57628fSDongsheng Yang return ret; 67*1d57628fSDongsheng Yang } 68*1d57628fSDongsheng Yang 69*1d57628fSDongsheng Yang static int cache_seg_ctrl_load(struct pcache_cache_segment *cache_seg) 70*1d57628fSDongsheng Yang { 71*1d57628fSDongsheng Yang struct pcache_cache_seg_ctrl *cache_seg_ctrl = cache_seg->cache_seg_ctrl; 72*1d57628fSDongsheng Yang struct pcache_cache_seg_gen cache_seg_gen, *cache_seg_gen_addr; 73*1d57628fSDongsheng Yang int ret = 0; 74*1d57628fSDongsheng Yang 75*1d57628fSDongsheng Yang mutex_lock(&cache_seg->ctrl_lock); 76*1d57628fSDongsheng Yang cache_seg_gen_addr = pcache_meta_find_latest(&cache_seg_ctrl->gen->header, 77*1d57628fSDongsheng Yang sizeof(struct pcache_cache_seg_gen), 78*1d57628fSDongsheng Yang sizeof(struct pcache_cache_seg_gen), 79*1d57628fSDongsheng Yang &cache_seg_gen); 80*1d57628fSDongsheng Yang if (IS_ERR(cache_seg_gen_addr)) { 81*1d57628fSDongsheng Yang ret = PTR_ERR(cache_seg_gen_addr); 82*1d57628fSDongsheng Yang goto out; 83*1d57628fSDongsheng Yang } 84*1d57628fSDongsheng Yang 85*1d57628fSDongsheng Yang if (!cache_seg_gen_addr) { 86*1d57628fSDongsheng Yang cache_seg->gen = 0; 87*1d57628fSDongsheng Yang cache_seg->gen_seq = 0; 88*1d57628fSDongsheng Yang cache_seg->gen_index = 0; 89*1d57628fSDongsheng Yang goto out; 90*1d57628fSDongsheng Yang } 91*1d57628fSDongsheng Yang 92*1d57628fSDongsheng Yang cache_seg->gen = cache_seg_gen.gen; 93*1d57628fSDongsheng Yang cache_seg->gen_seq = cache_seg_gen.header.seq; 94*1d57628fSDongsheng Yang cache_seg->gen_index = (cache_seg_gen_addr - cache_seg_ctrl->gen); 95*1d57628fSDongsheng Yang out: 96*1d57628fSDongsheng Yang mutex_unlock(&cache_seg->ctrl_lock); 97*1d57628fSDongsheng Yang 98*1d57628fSDongsheng Yang return ret; 99*1d57628fSDongsheng Yang } 100*1d57628fSDongsheng Yang 101*1d57628fSDongsheng Yang static inline struct pcache_cache_seg_gen *get_cache_seg_gen_addr(struct pcache_cache_segment *cache_seg) 102*1d57628fSDongsheng Yang { 103*1d57628fSDongsheng Yang struct pcache_cache_seg_ctrl *cache_seg_ctrl = cache_seg->cache_seg_ctrl; 104*1d57628fSDongsheng Yang 105*1d57628fSDongsheng Yang return (cache_seg_ctrl->gen + cache_seg->gen_index); 106*1d57628fSDongsheng Yang } 107*1d57628fSDongsheng Yang 108*1d57628fSDongsheng Yang static void cache_seg_ctrl_write(struct pcache_cache_segment *cache_seg) 109*1d57628fSDongsheng Yang { 110*1d57628fSDongsheng Yang struct pcache_cache_seg_gen cache_seg_gen; 111*1d57628fSDongsheng Yang 112*1d57628fSDongsheng Yang mutex_lock(&cache_seg->ctrl_lock); 113*1d57628fSDongsheng Yang cache_seg_gen.gen = cache_seg->gen; 114*1d57628fSDongsheng Yang cache_seg_gen.header.seq = ++cache_seg->gen_seq; 115*1d57628fSDongsheng Yang cache_seg_gen.header.crc = pcache_meta_crc(&cache_seg_gen.header, 116*1d57628fSDongsheng Yang sizeof(struct pcache_cache_seg_gen)); 117*1d57628fSDongsheng Yang 118*1d57628fSDongsheng Yang memcpy_flushcache(get_cache_seg_gen_addr(cache_seg), &cache_seg_gen, sizeof(struct pcache_cache_seg_gen)); 119*1d57628fSDongsheng Yang pmem_wmb(); 120*1d57628fSDongsheng Yang 121*1d57628fSDongsheng Yang cache_seg->gen_index = (cache_seg->gen_index + 1) % PCACHE_META_INDEX_MAX; 122*1d57628fSDongsheng Yang mutex_unlock(&cache_seg->ctrl_lock); 123*1d57628fSDongsheng Yang } 124*1d57628fSDongsheng Yang 125*1d57628fSDongsheng Yang static void cache_seg_ctrl_init(struct pcache_cache_segment *cache_seg) 126*1d57628fSDongsheng Yang { 127*1d57628fSDongsheng Yang cache_seg->gen = 0; 128*1d57628fSDongsheng Yang cache_seg->gen_seq = 0; 129*1d57628fSDongsheng Yang cache_seg->gen_index = 0; 130*1d57628fSDongsheng Yang cache_seg_ctrl_write(cache_seg); 131*1d57628fSDongsheng Yang } 132*1d57628fSDongsheng Yang 133*1d57628fSDongsheng Yang static int cache_seg_meta_load(struct pcache_cache_segment *cache_seg) 134*1d57628fSDongsheng Yang { 135*1d57628fSDongsheng Yang int ret; 136*1d57628fSDongsheng Yang 137*1d57628fSDongsheng Yang ret = cache_seg_info_load(cache_seg); 138*1d57628fSDongsheng Yang if (ret) 139*1d57628fSDongsheng Yang goto err; 140*1d57628fSDongsheng Yang 141*1d57628fSDongsheng Yang ret = cache_seg_ctrl_load(cache_seg); 142*1d57628fSDongsheng Yang if (ret) 143*1d57628fSDongsheng Yang goto err; 144*1d57628fSDongsheng Yang 145*1d57628fSDongsheng Yang return 0; 146*1d57628fSDongsheng Yang err: 147*1d57628fSDongsheng Yang return ret; 148*1d57628fSDongsheng Yang } 149*1d57628fSDongsheng Yang 150*1d57628fSDongsheng Yang /** 151*1d57628fSDongsheng Yang * cache_seg_set_next_seg - Sets the ID of the next segment 152*1d57628fSDongsheng Yang * @cache_seg: Pointer to the cache segment structure. 153*1d57628fSDongsheng Yang * @seg_id: The segment ID to set as the next segment. 154*1d57628fSDongsheng Yang * 155*1d57628fSDongsheng Yang * A pcache_cache allocates multiple cache segments, which are linked together 156*1d57628fSDongsheng Yang * through next_seg. When loading a pcache_cache, the first cache segment can 157*1d57628fSDongsheng Yang * be found using cache->seg_id, which allows access to all the cache segments. 158*1d57628fSDongsheng Yang */ 159*1d57628fSDongsheng Yang void cache_seg_set_next_seg(struct pcache_cache_segment *cache_seg, u32 seg_id) 160*1d57628fSDongsheng Yang { 161*1d57628fSDongsheng Yang cache_seg->cache_seg_info.flags |= PCACHE_SEG_INFO_FLAGS_HAS_NEXT; 162*1d57628fSDongsheng Yang cache_seg->cache_seg_info.next_seg = seg_id; 163*1d57628fSDongsheng Yang cache_seg_info_write(cache_seg); 164*1d57628fSDongsheng Yang } 165*1d57628fSDongsheng Yang 166*1d57628fSDongsheng Yang int cache_seg_init(struct pcache_cache *cache, u32 seg_id, u32 cache_seg_id, 167*1d57628fSDongsheng Yang bool new_cache) 168*1d57628fSDongsheng Yang { 169*1d57628fSDongsheng Yang struct pcache_cache_dev *cache_dev = cache->cache_dev; 170*1d57628fSDongsheng Yang struct pcache_cache_segment *cache_seg = &cache->segments[cache_seg_id]; 171*1d57628fSDongsheng Yang struct pcache_segment_init_options seg_options = { 0 }; 172*1d57628fSDongsheng Yang struct pcache_segment *segment = &cache_seg->segment; 173*1d57628fSDongsheng Yang int ret; 174*1d57628fSDongsheng Yang 175*1d57628fSDongsheng Yang cache_seg->cache = cache; 176*1d57628fSDongsheng Yang cache_seg->cache_seg_id = cache_seg_id; 177*1d57628fSDongsheng Yang spin_lock_init(&cache_seg->gen_lock); 178*1d57628fSDongsheng Yang atomic_set(&cache_seg->refs, 0); 179*1d57628fSDongsheng Yang mutex_init(&cache_seg->info_lock); 180*1d57628fSDongsheng Yang mutex_init(&cache_seg->ctrl_lock); 181*1d57628fSDongsheng Yang 182*1d57628fSDongsheng Yang /* init pcache_segment */ 183*1d57628fSDongsheng Yang seg_options.type = PCACHE_SEGMENT_TYPE_CACHE_DATA; 184*1d57628fSDongsheng Yang seg_options.data_off = PCACHE_CACHE_SEG_CTRL_OFF + PCACHE_CACHE_SEG_CTRL_SIZE; 185*1d57628fSDongsheng Yang seg_options.seg_id = seg_id; 186*1d57628fSDongsheng Yang seg_options.seg_info = &cache_seg->cache_seg_info; 187*1d57628fSDongsheng Yang pcache_segment_init(cache_dev, segment, &seg_options); 188*1d57628fSDongsheng Yang 189*1d57628fSDongsheng Yang cache_seg->cache_seg_ctrl = CACHE_DEV_SEGMENT(cache_dev, seg_id) + PCACHE_CACHE_SEG_CTRL_OFF; 190*1d57628fSDongsheng Yang 191*1d57628fSDongsheng Yang if (new_cache) { 192*1d57628fSDongsheng Yang cache_dev_zero_range(cache_dev, CACHE_DEV_SEGMENT(cache_dev, seg_id), 193*1d57628fSDongsheng Yang PCACHE_SEG_INFO_SIZE * PCACHE_META_INDEX_MAX + 194*1d57628fSDongsheng Yang PCACHE_CACHE_SEG_CTRL_SIZE); 195*1d57628fSDongsheng Yang 196*1d57628fSDongsheng Yang cache_seg_ctrl_init(cache_seg); 197*1d57628fSDongsheng Yang 198*1d57628fSDongsheng Yang cache_seg->info_index = 0; 199*1d57628fSDongsheng Yang cache_seg_info_write(cache_seg); 200*1d57628fSDongsheng Yang 201*1d57628fSDongsheng Yang /* clear outdated kset in segment */ 202*1d57628fSDongsheng Yang memcpy_flushcache(segment->data, &pcache_empty_kset, sizeof(struct pcache_cache_kset_onmedia)); 203*1d57628fSDongsheng Yang pmem_wmb(); 204*1d57628fSDongsheng Yang } else { 205*1d57628fSDongsheng Yang ret = cache_seg_meta_load(cache_seg); 206*1d57628fSDongsheng Yang if (ret) 207*1d57628fSDongsheng Yang goto err; 208*1d57628fSDongsheng Yang } 209*1d57628fSDongsheng Yang 210*1d57628fSDongsheng Yang return 0; 211*1d57628fSDongsheng Yang err: 212*1d57628fSDongsheng Yang return ret; 213*1d57628fSDongsheng Yang } 214*1d57628fSDongsheng Yang 215*1d57628fSDongsheng Yang /** 216*1d57628fSDongsheng Yang * get_cache_segment - Retrieves a free cache segment from the cache. 217*1d57628fSDongsheng Yang * @cache: Pointer to the cache structure. 218*1d57628fSDongsheng Yang * 219*1d57628fSDongsheng Yang * This function attempts to find a free cache segment that can be used. 220*1d57628fSDongsheng Yang * It locks the segment map and checks for the next available segment ID. 221*1d57628fSDongsheng Yang * If a free segment is found, it initializes it and returns a pointer to the 222*1d57628fSDongsheng Yang * cache segment structure. Returns NULL if no segments are available. 223*1d57628fSDongsheng Yang */ 224*1d57628fSDongsheng Yang struct pcache_cache_segment *get_cache_segment(struct pcache_cache *cache) 225*1d57628fSDongsheng Yang { 226*1d57628fSDongsheng Yang struct pcache_cache_segment *cache_seg; 227*1d57628fSDongsheng Yang u32 seg_id; 228*1d57628fSDongsheng Yang 229*1d57628fSDongsheng Yang spin_lock(&cache->seg_map_lock); 230*1d57628fSDongsheng Yang again: 231*1d57628fSDongsheng Yang seg_id = find_next_zero_bit(cache->seg_map, cache->n_segs, cache->last_cache_seg); 232*1d57628fSDongsheng Yang if (seg_id == cache->n_segs) { 233*1d57628fSDongsheng Yang /* reset the hint of ->last_cache_seg and retry */ 234*1d57628fSDongsheng Yang if (cache->last_cache_seg) { 235*1d57628fSDongsheng Yang cache->last_cache_seg = 0; 236*1d57628fSDongsheng Yang goto again; 237*1d57628fSDongsheng Yang } 238*1d57628fSDongsheng Yang cache->cache_full = true; 239*1d57628fSDongsheng Yang spin_unlock(&cache->seg_map_lock); 240*1d57628fSDongsheng Yang return NULL; 241*1d57628fSDongsheng Yang } 242*1d57628fSDongsheng Yang 243*1d57628fSDongsheng Yang /* 244*1d57628fSDongsheng Yang * found an available cache_seg, mark it used in seg_map 245*1d57628fSDongsheng Yang * and update the search hint ->last_cache_seg 246*1d57628fSDongsheng Yang */ 247*1d57628fSDongsheng Yang __set_bit(seg_id, cache->seg_map); 248*1d57628fSDongsheng Yang cache->last_cache_seg = seg_id; 249*1d57628fSDongsheng Yang spin_unlock(&cache->seg_map_lock); 250*1d57628fSDongsheng Yang 251*1d57628fSDongsheng Yang cache_seg = &cache->segments[seg_id]; 252*1d57628fSDongsheng Yang cache_seg->cache_seg_id = seg_id; 253*1d57628fSDongsheng Yang 254*1d57628fSDongsheng Yang return cache_seg; 255*1d57628fSDongsheng Yang } 256*1d57628fSDongsheng Yang 257*1d57628fSDongsheng Yang static void cache_seg_gen_increase(struct pcache_cache_segment *cache_seg) 258*1d57628fSDongsheng Yang { 259*1d57628fSDongsheng Yang spin_lock(&cache_seg->gen_lock); 260*1d57628fSDongsheng Yang cache_seg->gen++; 261*1d57628fSDongsheng Yang spin_unlock(&cache_seg->gen_lock); 262*1d57628fSDongsheng Yang 263*1d57628fSDongsheng Yang cache_seg_ctrl_write(cache_seg); 264*1d57628fSDongsheng Yang } 265*1d57628fSDongsheng Yang 266*1d57628fSDongsheng Yang void cache_seg_get(struct pcache_cache_segment *cache_seg) 267*1d57628fSDongsheng Yang { 268*1d57628fSDongsheng Yang atomic_inc(&cache_seg->refs); 269*1d57628fSDongsheng Yang } 270*1d57628fSDongsheng Yang 271*1d57628fSDongsheng Yang static void cache_seg_invalidate(struct pcache_cache_segment *cache_seg) 272*1d57628fSDongsheng Yang { 273*1d57628fSDongsheng Yang struct pcache_cache *cache; 274*1d57628fSDongsheng Yang 275*1d57628fSDongsheng Yang cache = cache_seg->cache; 276*1d57628fSDongsheng Yang cache_seg_gen_increase(cache_seg); 277*1d57628fSDongsheng Yang 278*1d57628fSDongsheng Yang spin_lock(&cache->seg_map_lock); 279*1d57628fSDongsheng Yang if (cache->cache_full) 280*1d57628fSDongsheng Yang cache->cache_full = false; 281*1d57628fSDongsheng Yang __clear_bit(cache_seg->cache_seg_id, cache->seg_map); 282*1d57628fSDongsheng Yang spin_unlock(&cache->seg_map_lock); 283*1d57628fSDongsheng Yang 284*1d57628fSDongsheng Yang pcache_defer_reqs_kick(CACHE_TO_PCACHE(cache)); 285*1d57628fSDongsheng Yang /* clean_work will clean the bad key in key_tree*/ 286*1d57628fSDongsheng Yang queue_work(cache_get_wq(cache), &cache->clean_work); 287*1d57628fSDongsheng Yang } 288*1d57628fSDongsheng Yang 289*1d57628fSDongsheng Yang void cache_seg_put(struct pcache_cache_segment *cache_seg) 290*1d57628fSDongsheng Yang { 291*1d57628fSDongsheng Yang if (atomic_dec_and_test(&cache_seg->refs)) 292*1d57628fSDongsheng Yang cache_seg_invalidate(cache_seg); 293*1d57628fSDongsheng Yang } 294