1 // SPDX-License-Identifier: GPL-2.0
3 * Moving/copying garbage collector
5 * Copyright 2012 Google, Inc.
13 #include <trace/events/bcache.h>
18 struct data_insert_op op
;
22 static bool moving_pred(struct keybuf
*buf
, struct bkey
*k
)
24 struct cache_set
*c
= container_of(buf
, struct cache_set
,
28 for (i
= 0; i
< KEY_PTRS(k
); i
++)
29 if (ptr_available(c
, k
, i
) &&
30 GC_MOVE(PTR_BUCKET(c
, k
, i
)))
36 /* Moving GC - IO loop */
38 static void moving_io_destructor(struct closure
*cl
)
40 struct moving_io
*io
= container_of(cl
, struct moving_io
, cl
);
45 static void write_moving_finish(struct closure
*cl
)
47 struct moving_io
*io
= container_of(cl
, struct moving_io
, cl
);
48 struct bio
*bio
= &io
->bio
.bio
;
52 if (io
->op
.replace_collision
)
53 trace_bcache_gc_copy_collision(&io
->w
->key
);
55 bch_keybuf_del(&io
->op
.c
->moving_gc_keys
, io
->w
);
57 up(&io
->op
.c
->moving_in_flight
);
59 closure_return_with_destructor(cl
, moving_io_destructor
);
62 static void read_moving_endio(struct bio
*bio
)
64 struct bbio
*b
= container_of(bio
, struct bbio
, bio
);
65 struct moving_io
*io
= container_of(bio
->bi_private
,
66 struct moving_io
, cl
);
69 io
->op
.status
= bio
->bi_status
;
70 else if (!KEY_DIRTY(&b
->key
) &&
71 ptr_stale(io
->op
.c
, &b
->key
, 0)) {
72 io
->op
.status
= BLK_STS_IOERR
;
75 bch_bbio_endio(io
->op
.c
, bio
, bio
->bi_status
, "reading data to move");
78 static void moving_init(struct moving_io
*io
)
80 struct bio
*bio
= &io
->bio
.bio
;
82 bio_init(bio
, bio
->bi_inline_vecs
,
83 DIV_ROUND_UP(KEY_SIZE(&io
->w
->key
), PAGE_SECTORS
));
85 bio_set_prio(bio
, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE
, 0));
87 bio
->bi_iter
.bi_size
= KEY_SIZE(&io
->w
->key
) << 9;
88 bio
->bi_private
= &io
->cl
;
89 bch_bio_map(bio
, NULL
);
92 static void write_moving(struct closure
*cl
)
94 struct moving_io
*io
= container_of(cl
, struct moving_io
, cl
);
95 struct data_insert_op
*op
= &io
->op
;
100 io
->bio
.bio
.bi_iter
.bi_sector
= KEY_START(&io
->w
->key
);
102 op
->bio
= &io
->bio
.bio
;
104 op
->writeback
= KEY_DIRTY(&io
->w
->key
);
105 op
->csum
= KEY_CSUM(&io
->w
->key
);
107 bkey_copy(&op
->replace_key
, &io
->w
->key
);
110 closure_call(&op
->cl
, bch_data_insert
, NULL
, cl
);
113 continue_at(cl
, write_moving_finish
, op
->wq
);
116 static void read_moving_submit(struct closure
*cl
)
118 struct moving_io
*io
= container_of(cl
, struct moving_io
, cl
);
119 struct bio
*bio
= &io
->bio
.bio
;
121 bch_submit_bbio(bio
, io
->op
.c
, &io
->w
->key
, 0);
123 continue_at(cl
, write_moving
, io
->op
.wq
);
126 static void read_moving(struct cache_set
*c
)
128 struct keybuf_key
*w
;
129 struct moving_io
*io
;
133 closure_init_stack(&cl
);
135 /* XXX: if we error, background writeback could stall indefinitely */
137 while (!test_bit(CACHE_SET_STOPPING
, &c
->flags
)) {
138 w
= bch_keybuf_next_rescan(c
, &c
->moving_gc_keys
,
139 &MAX_KEY
, moving_pred
);
143 if (ptr_stale(c
, &w
->key
, 0)) {
144 bch_keybuf_del(&c
->moving_gc_keys
, w
);
148 io
= kzalloc(struct_size(io
, bio
.bio
.bi_inline_vecs
,
149 DIV_ROUND_UP(KEY_SIZE(&w
->key
), PAGE_SECTORS
)),
156 io
->op
.inode
= KEY_INODE(&w
->key
);
158 io
->op
.wq
= c
->moving_gc_wq
;
163 bio_set_op_attrs(bio
, REQ_OP_READ
, 0);
164 bio
->bi_end_io
= read_moving_endio
;
166 if (bch_bio_alloc_pages(bio
, GFP_KERNEL
))
169 trace_bcache_gc_copy(&w
->key
);
171 down(&c
->moving_in_flight
);
172 closure_call(&io
->cl
, read_moving_submit
, NULL
, &cl
);
176 err
: if (!IS_ERR_OR_NULL(w
->private))
179 bch_keybuf_del(&c
->moving_gc_keys
, w
);
185 static bool bucket_cmp(struct bucket
*l
, struct bucket
*r
)
187 return GC_SECTORS_USED(l
) < GC_SECTORS_USED(r
);
190 static unsigned int bucket_heap_top(struct cache
*ca
)
194 return (b
= heap_peek(&ca
->heap
)) ? GC_SECTORS_USED(b
) : 0;
197 void bch_moving_gc(struct cache_set
*c
)
199 struct cache
*ca
= c
->cache
;
201 unsigned long sectors_to_move
, reserve_sectors
;
203 if (!c
->copy_gc_enabled
)
206 mutex_lock(&c
->bucket_lock
);
209 reserve_sectors
= ca
->sb
.bucket_size
*
210 fifo_used(&ca
->free
[RESERVE_MOVINGGC
]);
214 for_each_bucket(b
, ca
) {
215 if (GC_MARK(b
) == GC_MARK_METADATA
||
216 !GC_SECTORS_USED(b
) ||
217 GC_SECTORS_USED(b
) == ca
->sb
.bucket_size
||
218 atomic_read(&b
->pin
))
221 if (!heap_full(&ca
->heap
)) {
222 sectors_to_move
+= GC_SECTORS_USED(b
);
223 heap_add(&ca
->heap
, b
, bucket_cmp
);
224 } else if (bucket_cmp(b
, heap_peek(&ca
->heap
))) {
225 sectors_to_move
-= bucket_heap_top(ca
);
226 sectors_to_move
+= GC_SECTORS_USED(b
);
228 ca
->heap
.data
[0] = b
;
229 heap_sift(&ca
->heap
, 0, bucket_cmp
);
233 while (sectors_to_move
> reserve_sectors
) {
234 heap_pop(&ca
->heap
, b
, bucket_cmp
);
235 sectors_to_move
-= GC_SECTORS_USED(b
);
238 while (heap_pop(&ca
->heap
, b
, bucket_cmp
))
241 mutex_unlock(&c
->bucket_lock
);
243 c
->moving_gc_keys
.last_scanned
= ZERO_KEY
;
248 void bch_moving_init_cache_set(struct cache_set
*c
)
250 bch_keybuf_init(&c
->moving_gc_keys
);
251 sema_init(&c
->moving_in_flight
, 64);