Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 :
3 : #include <linux/bio.h>
4 :
5 : #include "cache.h"
6 : #include "backing_dev.h"
7 : #include "cache_dev.h"
8 : #include "dm_pcache.h"
9 :
10 37876611 : static void writeback_ctx_end(struct pcache_cache *cache, int ret)
11 : {
12 37876611 : if (ret && !cache->writeback_ctx.ret) {
13 0 : pcache_dev_err(CACHE_TO_PCACHE(cache), "writeback error: %d", ret);
14 0 : cache->writeback_ctx.ret = ret;
15 : }
16 :
17 37876611 : if (!atomic_dec_and_test(&cache->writeback_ctx.pending))
18 : return;
19 :
20 5413564 : if (!cache->writeback_ctx.ret) {
21 5413564 : backing_dev_flush(cache->backing_dev);
22 :
23 5413563 : mutex_lock(&cache->dirty_tail_lock);
24 5413564 : cache_pos_advance(&cache->dirty_tail, cache->writeback_ctx.advance);
25 5413563 : cache_encode_dirty_tail(cache);
26 5413559 : mutex_unlock(&cache->dirty_tail_lock);
27 : }
28 5413564 : queue_delayed_work(cache_get_wq(cache), &cache->writeback_work, 0);
29 : }
30 :
31 32463047 : static void writeback_end_req(struct pcache_backing_dev_req *backing_req, int ret)
32 : {
33 32463047 : struct pcache_cache *cache = backing_req->priv_data;
34 :
35 32463047 : mutex_lock(&cache->writeback_lock);
36 32463055 : writeback_ctx_end(cache, ret);
37 32463053 : mutex_unlock(&cache->writeback_lock);
38 32463055 : }
39 :
40 5417806 : static inline bool is_cache_clean(struct pcache_cache *cache, struct pcache_cache_pos *dirty_tail)
41 : {
42 5417806 : struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
43 5417806 : struct pcache_cache_kset_onmedia *kset_onmedia;
44 5417806 : u32 to_copy;
45 5417806 : void *addr;
46 5417806 : int ret;
47 :
48 5417806 : addr = cache_pos_addr(dirty_tail);
49 5417806 : kset_onmedia = (struct pcache_cache_kset_onmedia *)cache->wb_kset_onmedia_buf;
50 :
51 5417806 : to_copy = min(PCACHE_KSET_ONMEDIA_SIZE_MAX, PCACHE_SEG_SIZE - dirty_tail->seg_off);
52 5417806 : ret = copy_mc_to_kernel(kset_onmedia, addr, to_copy);
53 5417806 : if (ret) {
54 0 : pcache_dev_err(pcache, "error to read kset: %d", ret);
55 0 : return true;
56 : }
57 :
58 : /* Check if the magic number matches the expected value */
59 5417806 : if (kset_onmedia->magic != PCACHE_KSET_MAGIC) {
60 4144 : pcache_dev_debug(pcache, "dirty_tail: %u:%u magic: %llx, not expected: %llx\n",
61 : dirty_tail->cache_seg->cache_seg_id, dirty_tail->seg_off,
62 : kset_onmedia->magic, PCACHE_KSET_MAGIC);
63 4144 : return true;
64 : }
65 :
66 : /* Verify the CRC checksum for data integrity */
67 5413662 : if (kset_onmedia->crc != cache_kset_crc(kset_onmedia)) {
68 0 : pcache_dev_debug(pcache, "dirty_tail: %u:%u crc: %x, not expected: %x\n",
69 : dirty_tail->cache_seg->cache_seg_id, dirty_tail->seg_off,
70 : cache_kset_crc(kset_onmedia), kset_onmedia->crc);
71 0 : return true;
72 : }
73 :
74 : return false;
75 : }
76 :
77 305 : void cache_writeback_exit(struct pcache_cache *cache)
78 : {
79 305 : cancel_delayed_work_sync(&cache->writeback_work);
80 305 : cache_tree_exit(&cache->writeback_key_tree);
81 305 : }
82 :
83 303 : int cache_writeback_init(struct pcache_cache *cache)
84 : {
85 303 : int ret;
86 :
87 303 : ret = cache_tree_init(cache, &cache->writeback_key_tree, 1);
88 303 : if (ret)
89 0 : goto err;
90 :
91 303 : atomic_set(&cache->writeback_ctx.pending, 0);
92 :
93 : /* Queue delayed work to start writeback handling */
94 303 : queue_delayed_work(cache_get_wq(cache), &cache->writeback_work, 0);
95 :
96 303 : return 0;
97 0 : err:
98 0 : return ret;
99 : }
100 :
101 33311842 : static void cache_key_writeback(struct pcache_cache *cache, struct pcache_cache_key *key)
102 : {
103 33311842 : struct pcache_backing_dev_req *writeback_req;
104 33311842 : struct pcache_backing_dev_req_opts writeback_req_opts = { 0 };
105 33311842 : struct pcache_cache_pos *pos;
106 33311842 : void *addr;
107 33311842 : u32 seg_remain;
108 33311842 : u64 off;
109 :
110 33311842 : if (cache_key_clean(key))
111 848803 : return;
112 :
113 32463039 : pos = &key->cache_pos;
114 :
115 32463039 : seg_remain = cache_seg_remain(pos);
116 32463039 : BUG_ON(seg_remain < key->len);
117 :
118 32463039 : addr = cache_pos_addr(pos);
119 32463039 : off = key->off;
120 :
121 32463039 : writeback_req_opts.type = BACKING_DEV_REQ_TYPE_KMEM;
122 32463039 : writeback_req_opts.gfp_mask = GFP_NOIO;
123 32463039 : writeback_req_opts.end_fn = writeback_end_req;
124 32463039 : writeback_req_opts.priv_data = cache;
125 :
126 32463039 : writeback_req_opts.kmem.data = addr;
127 32463039 : writeback_req_opts.kmem.opf = REQ_OP_WRITE;
128 32463039 : writeback_req_opts.kmem.len = key->len;
129 32463039 : writeback_req_opts.kmem.backing_off = off;
130 :
131 32463039 : writeback_req = backing_dev_req_create(cache->backing_dev, &writeback_req_opts);
132 :
133 32463035 : atomic_inc(&cache->writeback_ctx.pending);
134 32463056 : backing_dev_req_submit(writeback_req, true);
135 : }
136 :
137 5413562 : static void cache_wb_tree_writeback(struct pcache_cache *cache, u32 advance)
138 : {
139 5413562 : struct pcache_cache_tree *cache_tree = &cache->writeback_key_tree;
140 5413562 : struct pcache_cache_subtree *cache_subtree;
141 5413562 : struct rb_node *node;
142 5413562 : struct pcache_cache_key *key;
143 5413562 : u32 i;
144 :
145 5413562 : cache->writeback_ctx.ret = 0;
146 5413562 : cache->writeback_ctx.advance = advance;
147 5413562 : atomic_set(&cache->writeback_ctx.pending, 1);
148 :
149 10827124 : for (i = 0; i < cache_tree->n_subtrees; i++) {
150 5413562 : cache_subtree = &cache_tree->subtrees[i];
151 :
152 5413562 : node = rb_first(&cache_subtree->root);
153 38725405 : while (node) {
154 33311843 : key = CACHE_KEY(node);
155 33311843 : node = rb_next(node);
156 :
157 33311842 : cache_key_writeback(cache, key);
158 33311849 : cache_key_delete(key);
159 : }
160 : }
161 5413562 : writeback_ctx_end(cache, 0);
162 5413563 : }
163 :
164 5413562 : static int cache_kset_insert_tree(struct pcache_cache *cache, struct pcache_cache_kset_onmedia *kset_onmedia)
165 : {
166 5413562 : struct pcache_cache_key_onmedia *key_onmedia;
167 5413562 : struct pcache_cache_subtree *cache_subtree;
168 5413562 : struct pcache_cache_key *key;
169 5413562 : int ret;
170 5413562 : u32 i;
171 :
172 : /* Iterate through all keys in the kset and write each back to storage */
173 48258516 : for (i = 0; i < kset_onmedia->key_num; i++) {
174 42844954 : key_onmedia = &kset_onmedia->data[i];
175 :
176 42844954 : key = cache_key_alloc(&cache->writeback_key_tree, GFP_NOIO);
177 42845011 : ret = cache_key_decode(cache, key_onmedia, key);
178 42844996 : if (ret) {
179 0 : cache_key_put(key);
180 0 : goto clear_tree;
181 : }
182 :
183 42844996 : cache_subtree = get_subtree(&cache->writeback_key_tree, key->off);
184 42844996 : spin_lock(&cache_subtree->tree_lock);
185 42845006 : cache_key_insert(&cache->writeback_key_tree, key, true);
186 42844955 : spin_unlock(&cache_subtree->tree_lock);
187 : }
188 :
189 : return 0;
190 0 : clear_tree:
191 0 : cache_tree_clear(&cache->writeback_key_tree);
192 0 : return ret;
193 : }
194 :
195 99 : static void last_kset_writeback(struct pcache_cache *cache,
196 : struct pcache_cache_kset_onmedia *last_kset_onmedia)
197 : {
198 99 : struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
199 99 : struct pcache_cache_segment *next_seg;
200 :
201 99 : pcache_dev_debug(pcache, "last kset, next: %u\n", last_kset_onmedia->next_cache_seg_id);
202 :
203 99 : next_seg = &cache->segments[last_kset_onmedia->next_cache_seg_id];
204 :
205 99 : mutex_lock(&cache->dirty_tail_lock);
206 99 : cache->dirty_tail.cache_seg = next_seg;
207 99 : cache->dirty_tail.seg_off = 0;
208 99 : cache_encode_dirty_tail(cache);
209 99 : mutex_unlock(&cache->dirty_tail_lock);
210 99 : }
211 :
212 5571308 : void cache_writeback_fn(struct work_struct *work)
213 : {
214 5571308 : struct pcache_cache *cache = container_of(work, struct pcache_cache, writeback_work.work);
215 5571308 : struct dm_pcache *pcache = CACHE_TO_PCACHE(cache);
216 5571308 : struct pcache_cache_pos dirty_tail;
217 5571308 : struct pcache_cache_kset_onmedia *kset_onmedia;
218 5571308 : u32 delay;
219 5571308 : int ret;
220 :
221 5571308 : mutex_lock(&cache->writeback_lock);
222 5571310 : if (atomic_read(&cache->writeback_ctx.pending))
223 153502 : goto unlock;
224 :
225 5417808 : if (pcache_is_stopping(pcache))
226 1 : goto unlock;
227 :
228 5417807 : kset_onmedia = (struct pcache_cache_kset_onmedia *)cache->wb_kset_onmedia_buf;
229 :
230 5417807 : mutex_lock(&cache->dirty_tail_lock);
231 5417807 : cache_pos_copy(&dirty_tail, &cache->dirty_tail);
232 5417807 : mutex_unlock(&cache->dirty_tail_lock);
233 :
234 5417807 : if (is_cache_clean(cache, &dirty_tail)) {
235 4144 : delay = PCACHE_CACHE_WRITEBACK_INTERVAL;
236 4144 : goto queue_work;
237 : }
238 :
239 5413661 : if (kset_onmedia->flags & PCACHE_KSET_FLAGS_LAST) {
240 99 : last_kset_writeback(cache, kset_onmedia);
241 99 : delay = 0;
242 99 : goto queue_work;
243 : }
244 :
245 5413562 : ret = cache_kset_insert_tree(cache, kset_onmedia);
246 5413562 : if (ret) {
247 0 : delay = PCACHE_CACHE_WRITEBACK_INTERVAL;
248 0 : goto queue_work;
249 : }
250 :
251 5413562 : cache_wb_tree_writeback(cache, get_kset_onmedia_size(kset_onmedia));
252 5413562 : delay = 0;
253 5417807 : queue_work:
254 5417807 : queue_delayed_work(cache_get_wq(cache), &cache->writeback_work, delay);
255 5571309 : unlock:
256 5571309 : mutex_unlock(&cache->writeback_lock);
257 5571309 : }
|