LCOV - code coverage report
Current view: top level - dm-pcache - cache.c (source / functions) Coverage Total Hit
Test: dm_pcache.info Lines: 85.5 % 249 213
Test Date: 2025-08-04 03:13:17 Functions: 100.0 % 18 18
Legend: Lines: hit not hit

            Line data    Source code
       1              : // SPDX-License-Identifier: GPL-2.0-or-later
       2              : #include <linux/blk_types.h>
       3              : 
       4              : #include "cache.h"
       5              : #include "cache_dev.h"
       6              : #include "backing_dev.h"
       7              : #include "dm_pcache.h"
       8              : 
       9              : struct kmem_cache *key_cache;
      10              : 
      11          383 : static inline struct pcache_cache_info *get_cache_info_addr(struct pcache_cache *cache)
      12              : {
      13          383 :         return cache->cache_info_addr + cache->info_index;
      14              : }
      15              : 
      16          383 : static void cache_info_write(struct pcache_cache *cache)
      17              : {
      18          383 :         struct pcache_cache_info *cache_info = &cache->cache_info;
      19              : 
      20          383 :         cache_info->header.seq++;
      21          383 :         cache_info->header.crc = pcache_meta_crc(&cache_info->header,
      22              :                                                 sizeof(struct pcache_cache_info));
      23              : 
      24          383 :         memcpy_flushcache(get_cache_info_addr(cache), cache_info,
      25              :                         sizeof(struct pcache_cache_info));
      26              : 
      27          383 :         cache->info_index = (cache->info_index + 1) % PCACHE_META_INDEX_MAX;
      28          383 : }
      29              : 
      30              : static void cache_info_init_default(struct pcache_cache *cache);
      31          308 : static int cache_info_init(struct pcache_cache *cache, struct pcache_cache_options *opts)
      32              : {
      33          308 :         struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
      34          308 :         struct pcache_cache_info *cache_info_addr;
      35              : 
      36          616 :         cache_info_addr = pcache_meta_find_latest(&cache->cache_info_addr->header,
      37              :                                                 sizeof(struct pcache_cache_info),
      38              :                                                 PCACHE_CACHE_INFO_SIZE,
      39          308 :                                                 &cache->cache_info);
      40          308 :         if (IS_ERR(cache_info_addr))
      41            0 :                 return PTR_ERR(cache_info_addr);
      42              : 
      43          308 :         if (cache_info_addr) {
      44           55 :                 if (opts->data_crc !=
      45           55 :                                 (cache->cache_info.flags & PCACHE_CACHE_FLAGS_DATA_CRC)) {
      46            7 :                         pcache_dev_err(pcache, "invalid option for data_crc: %s, expected: %s",
      47              :                                         opts->data_crc ? "true" : "false",
      48              :                                         cache->cache_info.flags & PCACHE_CACHE_FLAGS_DATA_CRC ? "true" : "false");
      49            5 :                         return -EINVAL;
      50              :                 }
      51              : 
      52              :                 return 0;
      53              :         }
      54              : 
      55              :         /* init cache_info for new cache */
      56          253 :         cache_info_init_default(cache);
      57          253 :         cache_mode_set(cache, opts->cache_mode);
      58          253 :         if (opts->data_crc)
      59          121 :                 cache->cache_info.flags |= PCACHE_CACHE_FLAGS_DATA_CRC;
      60              : 
      61              :         return 0;
      62              : }
      63              : 
      64          333 : static void cache_info_set_gc_percent(struct pcache_cache_info *cache_info, u8 percent)
      65              : {
      66          333 :         cache_info->flags &= ~PCACHE_CACHE_FLAGS_GC_PERCENT_MASK;
      67           80 :         cache_info->flags |= FIELD_PREP(PCACHE_CACHE_FLAGS_GC_PERCENT_MASK, percent);
      68           80 : }
      69              : 
      70           86 : int pcache_cache_set_gc_percent(struct pcache_cache *cache, u8 percent)
      71              : {
      72           86 :         if (percent > PCACHE_CACHE_GC_PERCENT_MAX || percent < PCACHE_CACHE_GC_PERCENT_MIN)
      73              :                 return -EINVAL;
      74              : 
      75           80 :         mutex_lock(&cache->cache_info_lock);
      76           80 :         cache_info_set_gc_percent(&cache->cache_info, percent);
      77              : 
      78           80 :         cache_info_write(cache);
      79           80 :         mutex_unlock(&cache->cache_info_lock);
      80              : 
      81           80 :         return 0;
      82              : }
      83              : 
      84     10372457 : void cache_pos_encode(struct pcache_cache *cache,
      85              :                              struct pcache_cache_pos_onmedia *pos_onmedia_base,
      86              :                              struct pcache_cache_pos *pos, u64 seq, u32 *index)
      87              : {
      88     10372457 :         struct pcache_cache_pos_onmedia pos_onmedia;
      89     10372457 :         struct pcache_cache_pos_onmedia *pos_onmedia_addr = pos_onmedia_base + *index;
      90              : 
      91     10372457 :         pos_onmedia.cache_seg_id = pos->cache_seg->cache_seg_id;
      92     10372457 :         pos_onmedia.seg_off = pos->seg_off;
      93     10372457 :         pos_onmedia.header.seq = seq;
      94     10372457 :         pos_onmedia.header.crc = cache_pos_onmedia_crc(&pos_onmedia);
      95              : 
      96     10373259 :         memcpy_flushcache(pos_onmedia_addr, &pos_onmedia, sizeof(struct pcache_cache_pos_onmedia));
      97     10373259 :         pmem_wmb();
      98              : 
      99     10369513 :         *index = (*index + 1) % PCACHE_META_INDEX_MAX;
     100     10369513 : }
     101              : 
     102          100 : int cache_pos_decode(struct pcache_cache *cache,
     103              :                             struct pcache_cache_pos_onmedia *pos_onmedia,
     104              :                             struct pcache_cache_pos *pos, u64 *seq, u32 *index)
     105              : {
     106          100 :         struct pcache_cache_pos_onmedia latest, *latest_addr;
     107              : 
     108          100 :         latest_addr = pcache_meta_find_latest(&pos_onmedia->header,
     109              :                                         sizeof(struct pcache_cache_pos_onmedia),
     110              :                                         sizeof(struct pcache_cache_pos_onmedia),
     111              :                                         &latest);
     112          100 :         if (IS_ERR(latest_addr))
     113            0 :                 return PTR_ERR(latest_addr);
     114              : 
     115          100 :         if (!latest_addr)
     116              :                 return -EIO;
     117              : 
     118          100 :         pos->cache_seg = &cache->segments[latest.cache_seg_id];
     119          100 :         pos->seg_off = latest.seg_off;
     120          100 :         *seq = latest.header.seq;
     121          100 :         *index = (latest_addr - pos_onmedia);
     122              : 
     123          100 :         return 0;
     124              : }
     125              : 
     126          253 : static inline void cache_info_set_seg_id(struct pcache_cache *cache, u32 seg_id)
     127              : {
     128          253 :         cache->cache_info.seg_id = seg_id;
     129          253 : }
     130              : 
     131          308 : static int cache_init(struct dm_pcache *pcache)
     132              : {
     133          308 :         struct pcache_cache *cache = &pcache->cache;
     134          308 :         struct pcache_backing_dev *backing_dev = &pcache->backing_dev;
     135          308 :         struct pcache_cache_dev *cache_dev = &pcache->cache_dev;
     136          308 :         int ret;
     137              : 
     138          308 :         cache->segments = kvcalloc(cache_dev->seg_num, sizeof(struct pcache_cache_segment), GFP_KERNEL);
     139          308 :         if (!cache->segments) {
     140            0 :                 ret = -ENOMEM;
     141            0 :                 goto err;
     142              :         }
     143              : 
     144          308 :         cache->seg_map = kvcalloc(BITS_TO_LONGS(cache_dev->seg_num), sizeof(unsigned long), GFP_KERNEL);
     145          308 :         if (!cache->seg_map) {
     146            0 :                 ret = -ENOMEM;
     147            0 :                 goto free_segments;
     148              :         }
     149              : 
     150          308 :         cache->backing_dev = backing_dev;
     151          308 :         cache->cache_dev = &pcache->cache_dev;
     152          308 :         cache->n_segs = cache_dev->seg_num;
     153          308 :         atomic_set(&cache->gc_errors, 0);
     154          308 :         spin_lock_init(&cache->seg_map_lock);
     155          308 :         spin_lock_init(&cache->key_head_lock);
     156              : 
     157          308 :         mutex_init(&cache->cache_info_lock);
     158          308 :         mutex_init(&cache->key_tail_lock);
     159          308 :         mutex_init(&cache->dirty_tail_lock);
     160          308 :         mutex_init(&cache->writeback_lock);
     161              : 
     162          308 :         INIT_DELAYED_WORK(&cache->writeback_work, cache_writeback_fn);
     163          308 :         INIT_DELAYED_WORK(&cache->gc_work, pcache_cache_gc_fn);
     164          308 :         INIT_WORK(&cache->clean_work, clean_fn);
     165              : 
     166          308 :         return 0;
     167              : 
     168            0 : free_segments:
     169            0 :         kvfree(cache->segments);
     170              : err:
     171              :         return ret;
     172              : }
     173              : 
     174          310 : static void cache_exit(struct pcache_cache *cache)
     175              : {
     176          310 :         kvfree(cache->seg_map);
     177          310 :         kvfree(cache->segments);
     178          310 : }
     179              : 
     180          253 : static void cache_info_init_default(struct pcache_cache *cache)
     181              : {
     182          253 :         struct pcache_cache_info *cache_info = &cache->cache_info;
     183              : 
     184          253 :         cache_info->header.seq = 0;
     185          253 :         cache_info->n_segs = cache->cache_dev->seg_num;
     186          253 :         cache_info_set_gc_percent(cache_info, PCACHE_CACHE_GC_PERCENT_DEFAULT);
     187              : }
     188              : 
     189          303 : static int cache_tail_init(struct pcache_cache *cache)
     190              : {
     191          303 :         struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
     192          303 :         bool new_cache = !(cache->cache_info.flags & PCACHE_CACHE_FLAGS_INIT_DONE);
     193              : 
     194          303 :         if (new_cache) {
     195          253 :                 __set_bit(0, cache->seg_map);
     196              : 
     197          253 :                 cache->key_head.cache_seg = &cache->segments[0];
     198          253 :                 cache->key_head.seg_off = 0;
     199          253 :                 cache_pos_copy(&cache->key_tail, &cache->key_head);
     200          253 :                 cache_pos_copy(&cache->dirty_tail, &cache->key_head);
     201              : 
     202          253 :                 cache_encode_dirty_tail(cache);
     203          253 :                 cache_encode_key_tail(cache);
     204              :         } else {
     205           50 :                 if (cache_decode_key_tail(cache) || cache_decode_dirty_tail(cache)) {
     206            0 :                         pcache_dev_err(pcache, "Corrupted key tail or dirty tail.\n");
     207            0 :                         return -EIO;
     208              :                 }
     209              :         }
     210              : 
     211              :         return 0;
     212              : }
     213              : 
     214        85969 : static int get_seg_id(struct pcache_cache *cache,
     215              :                       struct pcache_cache_segment *prev_cache_seg,
     216              :                       bool new_cache, u32 *seg_id)
     217              : {
     218        85969 :         struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
     219        85969 :         struct pcache_cache_dev *cache_dev = cache->cache_dev;
     220        85969 :         int ret;
     221              : 
     222        85969 :         if (new_cache) {
     223        71555 :                 ret = cache_dev_get_empty_segment_id(cache_dev, seg_id);
     224        71555 :                 if (ret) {
     225            0 :                         pcache_dev_err(pcache, "no available segment\n");
     226            0 :                         goto err;
     227              :                 }
     228              : 
     229        71555 :                 if (prev_cache_seg)
     230        71302 :                         cache_seg_set_next_seg(prev_cache_seg, *seg_id);
     231              :                 else
     232          253 :                         cache_info_set_seg_id(cache, *seg_id);
     233              :         } else {
     234        14414 :                 if (prev_cache_seg) {
     235        14364 :                         struct pcache_segment_info *prev_seg_info;
     236              : 
     237        14364 :                         prev_seg_info = &prev_cache_seg->cache_seg_info;
     238        14364 :                         if (!segment_info_has_next(prev_seg_info)) {
     239            0 :                                 ret = -EFAULT;
     240            0 :                                 goto err;
     241              :                         }
     242        14364 :                         *seg_id = prev_cache_seg->cache_seg_info.next_seg;
     243              :                 } else {
     244           50 :                         *seg_id = cache->cache_info.seg_id;
     245              :                 }
     246              :         }
     247              :         return 0;
     248              : err:
     249              :         return ret;
     250              : }
     251              : 
     252          303 : static int cache_segs_init(struct pcache_cache *cache)
     253              : {
     254          303 :         struct pcache_cache_segment *prev_cache_seg = NULL;
     255          303 :         struct pcache_cache_info *cache_info = &cache->cache_info;
     256          303 :         bool new_cache = !(cache->cache_info.flags & PCACHE_CACHE_FLAGS_INIT_DONE);
     257          303 :         u32 seg_id;
     258          303 :         int ret;
     259          303 :         u32 i;
     260              : 
     261        86272 :         for (i = 0; i < cache_info->n_segs; i++) {
     262        85969 :                 ret = get_seg_id(cache, prev_cache_seg, new_cache, &seg_id);
     263        85969 :                 if (ret)
     264            0 :                         goto err;
     265              : 
     266        85969 :                 ret = cache_seg_init(cache, seg_id, i, new_cache);
     267        85969 :                 if (ret)
     268            0 :                         goto err;
     269              : 
     270        85969 :                 prev_cache_seg = &cache->segments[i];
     271              :         }
     272              :         return 0;
     273              : err:
     274              :         return ret;
     275              : }
     276              : 
     277          303 : static int cache_init_req_keys(struct pcache_cache *cache, u32 n_paral)
     278              : {
     279          303 :         struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
     280          303 :         u32 n_subtrees;
     281          303 :         int ret;
     282          303 :         u32 i, cpu;
     283              : 
     284              :         /* Calculate number of cache trees based on the device size */
     285          303 :         n_subtrees = DIV_ROUND_UP(cache->dev_size << SECTOR_SHIFT, PCACHE_CACHE_SUBTREE_SIZE);
     286          303 :         ret = cache_tree_init(cache, &cache->req_key_tree, n_subtrees);
     287          303 :         if (ret)
     288            0 :                 goto err;
     289              : 
     290          303 :         cache->n_ksets = n_paral;
     291          303 :         cache->ksets = kvcalloc(cache->n_ksets, PCACHE_KSET_SIZE, GFP_KERNEL);
     292          303 :         if (!cache->ksets) {
     293            0 :                 ret = -ENOMEM;
     294            0 :                 goto req_tree_exit;
     295              :         }
     296              : 
     297              :         /*
     298              :          * Initialize each kset with a spinlock and delayed work for flushing.
     299              :          * Each kset is associated with one queue to ensure independent handling
     300              :          * of cache keys across multiple queues, maximizing multiqueue concurrency.
     301              :          */
     302        14383 :         for (i = 0; i < cache->n_ksets; i++) {
     303        14080 :                 struct pcache_cache_kset *kset = get_kset(cache, i);
     304              : 
     305        14080 :                 kset->cache = cache;
     306        14080 :                 spin_lock_init(&kset->kset_lock);
     307        14080 :                 INIT_DELAYED_WORK(&kset->flush_work, kset_flush_fn);
     308              :         }
     309              : 
     310          303 :         cache->data_heads = alloc_percpu(struct pcache_cache_data_head);
     311          303 :         if (!cache->data_heads) {
     312            0 :                 ret = -ENOMEM;
     313            0 :                 goto free_kset;
     314              :         }
     315              : 
     316        28766 :         for_each_possible_cpu(cpu) {
     317        28160 :                 struct pcache_cache_data_head *h =
     318        14080 :                         per_cpu_ptr(cache->data_heads, cpu);
     319        14080 :                 h->head_pos.cache_seg = NULL;
     320              :         }
     321              : 
     322              :         /*
     323              :          * Replay persisted cache keys using cache_replay.
     324              :          * This function loads and replays cache keys from previously stored
     325              :          * ksets, allowing the cache to restore its state after a restart.
     326              :          */
     327          303 :         ret = cache_replay(cache);
     328          303 :         if (ret) {
     329            0 :                 pcache_dev_err(pcache, "failed to replay keys\n");
     330            0 :                 goto free_heads;
     331              :         }
     332              : 
     333              :         return 0;
     334              : 
     335            0 : free_heads:
     336            0 :         free_percpu(cache->data_heads);
     337            0 : free_kset:
     338            0 :         kvfree(cache->ksets);
     339            0 : req_tree_exit:
     340            0 :         cache_tree_exit(&cache->req_key_tree);
     341              : err:
     342              :         return ret;
     343              : }
     344              : 
     345          305 : static void cache_destroy_req_keys(struct pcache_cache *cache)
     346              : {
     347          305 :         u32 i;
     348              : 
     349        14513 :         for (i = 0; i < cache->n_ksets; i++) {
     350        14208 :                 struct pcache_cache_kset *kset = get_kset(cache, i);
     351              : 
     352        14208 :                 cancel_delayed_work_sync(&kset->flush_work);
     353              :         }
     354              : 
     355          305 :         free_percpu(cache->data_heads);
     356          305 :         kvfree(cache->ksets);
     357          305 :         cache_tree_exit(&cache->req_key_tree);
     358          305 : }
     359              : 
     360          308 : int pcache_cache_start(struct dm_pcache *pcache)
     361              : {
     362          308 :         struct pcache_backing_dev *backing_dev = &pcache->backing_dev;
     363          308 :         struct pcache_cache *cache = &pcache->cache;
     364          308 :         struct pcache_cache_options *opts = &pcache->opts;
     365          308 :         int ret;
     366              : 
     367          308 :         ret = cache_init(pcache);
     368          308 :         if (ret)
     369              :                 return ret;
     370              : 
     371          308 :         cache->cache_info_addr = CACHE_DEV_CACHE_INFO(cache->cache_dev);
     372          308 :         cache->cache_ctrl = CACHE_DEV_CACHE_CTRL(cache->cache_dev);
     373          308 :         backing_dev->cache = cache;
     374          308 :         cache->dev_size = backing_dev->dev_size;
     375              : 
     376          308 :         ret = cache_info_init(cache, opts);
     377          308 :         if (ret)
     378            5 :                 goto cache_exit;
     379              : 
     380          303 :         ret = cache_segs_init(cache);
     381          303 :         if (ret)
     382            0 :                 goto cache_exit;
     383              : 
     384          303 :         ret = cache_tail_init(cache);
     385          303 :         if (ret)
     386            0 :                 goto cache_exit;
     387              : 
     388          303 :         ret = cache_init_req_keys(cache, num_online_cpus());
     389          303 :         if (ret)
     390            0 :                 goto cache_exit;
     391              : 
     392          303 :         ret = cache_writeback_init(cache);
     393          303 :         if (ret)
     394            0 :                 goto destroy_keys;
     395              : 
     396          303 :         cache->cache_info.flags |= PCACHE_CACHE_FLAGS_INIT_DONE;
     397          303 :         cache_info_write(cache);
     398          303 :         queue_delayed_work(cache_get_wq(cache), &cache->gc_work, 0);
     399              : 
     400          303 :         return 0;
     401              : 
     402            0 : destroy_keys:
     403            0 :         cache_destroy_req_keys(cache);
     404            5 : cache_exit:
     405            5 :         cache_exit(cache);
     406              : 
     407            5 :         return ret;
     408              : }
     409              : 
     410          305 : void pcache_cache_stop(struct dm_pcache *pcache)
     411              : {
     412          305 :         struct pcache_cache *cache = &pcache->cache;
     413              : 
     414          305 :         cache_flush(cache);
     415              : 
     416          305 :         cancel_delayed_work_sync(&cache->gc_work);
     417          305 :         flush_work(&cache->clean_work);
     418          305 :         cache_writeback_exit(cache);
     419              : 
     420          305 :         if (cache->req_key_tree.n_subtrees)
     421          305 :                 cache_destroy_req_keys(cache);
     422              : 
     423          305 :         cache_exit(cache);
     424          305 : }
     425              : 
     426     54393183 : struct workqueue_struct *cache_get_wq(struct pcache_cache *cache)
     427              : {
     428     54393183 :         struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
     429              : 
     430          303 :         return pcache->task_wq;
     431              : }
     432              : 
     433          289 : int pcache_cache_init(void)
     434              : {
     435          289 :         key_cache = KMEM_CACHE(pcache_cache_key, 0);
     436          289 :         if (!key_cache)
     437            0 :                 return -ENOMEM;
     438              : 
     439              :         return 0;
     440              : }
     441              : 
     442          165 : void pcache_cache_exit(void)
     443              : {
     444          165 :         kmem_cache_destroy(key_cache);
     445          165 : }
        

Generated by: LCOV version 2.0-1