^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/math64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "ctree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "block-group.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "discard.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "free-space-cache.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * This contains the logic to handle async discard.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Async discard manages trimming of free space outside of transaction commit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * Discarding is done by managing the block_groups on a LRU list based on free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * space recency. Two passes are used to first prioritize discarding extents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * and then allow for trimming in the bitmap the best opportunity to coalesce.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * The block_groups are maintained on multiple lists to allow for multiple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * passes with different discard filter requirements. A delayed work item is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * used to manage discarding with timeout determined by a max of the delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * incurred by the iops rate limit, the byte rate limit, and the max delay of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * BTRFS_DISCARD_MAX_DELAY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Note, this only keeps track of block_groups that are explicitly for data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Mixed block_groups are not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * The first list is special to manage discarding of fully free block groups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * This is necessary because we issue a final trim for a full free block group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * after forgetting it. When a block group becomes unused, instead of directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * being added to the unused_bgs list, we add it to this first list. Then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * from there, if it becomes fully discarded, we place it onto the unused_bgs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * The in-memory free space cache serves as the backing state for discard.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * Consequently this means there is no persistence. We opt to load all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * block groups in as not discarded, so the mount case degenerates to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * crashing case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * As the free space cache uses bitmaps, there exists a tradeoff between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * ease/efficiency for find_free_extent() and the accuracy of discard state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * Here we opt to let untrimmed regions merge with everything while only letting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * trimmed regions merge with other trimmed regions. This can cause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * overtrimming, but the coalescing benefit seems to be worth it. Additionally,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * bitmap state is tracked as a whole. If we're able to fully trim a bitmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * the trimmed flag is set on the bitmap. Otherwise, if an allocation comes in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * this resets the state and we will retry trimming the whole bitmap. This is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * tradeoff between discard state accuracy and the cost of accounting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* This is an initial delay to give some chance for block reuse */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define BTRFS_DISCARD_DELAY (120ULL * NSEC_PER_SEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define BTRFS_DISCARD_UNUSED_DELAY (10ULL * NSEC_PER_SEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /* Target completion latency of discarding all discardable extents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define BTRFS_DISCARD_TARGET_MSEC (6 * 60 * 60UL * MSEC_PER_SEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define BTRFS_DISCARD_MIN_DELAY_MSEC (1UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define BTRFS_DISCARD_MAX_DELAY_MSEC (1000UL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define BTRFS_DISCARD_MAX_IOPS (10U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Montonically decreasing minimum length filters after index 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int discard_minlen[BTRFS_NR_DISCARD_LISTS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) BTRFS_ASYNC_DISCARD_MAX_FILTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) BTRFS_ASYNC_DISCARD_MIN_FILTER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static struct list_head *get_discard_list(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct btrfs_block_group *block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return &discard_ctl->discard_list[block_group->discard_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static void __add_to_discard_list(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct btrfs_block_group *block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (!btrfs_run_discard_work(discard_ctl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) if (list_empty(&block_group->discard_list) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) block_group->discard_index == BTRFS_DISCARD_INDEX_UNUSED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (block_group->discard_index == BTRFS_DISCARD_INDEX_UNUSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) block_group->discard_index = BTRFS_DISCARD_INDEX_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) block_group->discard_eligible_time = (ktime_get_ns() +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) BTRFS_DISCARD_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) block_group->discard_state = BTRFS_DISCARD_RESET_CURSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) list_move_tail(&block_group->discard_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) get_discard_list(discard_ctl, block_group));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static void add_to_discard_list(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct btrfs_block_group *block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (!btrfs_is_block_group_data_only(block_group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) __add_to_discard_list(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void add_to_discard_unused_list(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct btrfs_block_group *block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (!btrfs_run_discard_work(discard_ctl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) list_del_init(&block_group->discard_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) block_group->discard_index = BTRFS_DISCARD_INDEX_UNUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) block_group->discard_eligible_time = (ktime_get_ns() +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) BTRFS_DISCARD_UNUSED_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) block_group->discard_state = BTRFS_DISCARD_RESET_CURSOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) list_add_tail(&block_group->discard_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) &discard_ctl->discard_list[BTRFS_DISCARD_INDEX_UNUSED]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static bool remove_from_discard_list(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct btrfs_block_group *block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) bool running = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (block_group == discard_ctl->block_group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) running = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) discard_ctl->block_group = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) block_group->discard_eligible_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) list_del_init(&block_group->discard_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * find_next_block_group - find block_group that's up next for discarding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * @now: current time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * Iterate over the discard lists to find the next block_group up for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * discarding checking the discard_eligible_time of block_group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static struct btrfs_block_group *find_next_block_group(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u64 now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct btrfs_block_group *ret_block_group = NULL, *block_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) for (i = 0; i < BTRFS_NR_DISCARD_LISTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) struct list_head *discard_list = &discard_ctl->discard_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (!list_empty(discard_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) block_group = list_first_entry(discard_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct btrfs_block_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) discard_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (!ret_block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) ret_block_group = block_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (ret_block_group->discard_eligible_time < now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (ret_block_group->discard_eligible_time >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) block_group->discard_eligible_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ret_block_group = block_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return ret_block_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * peek_discard_list - wrap find_next_block_group()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * @discard_state: the discard_state of the block_group after state management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * @discard_index: the discard_index of the block_group after state management
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * This wraps find_next_block_group() and sets the block_group to be in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * discard_state's control flow is managed here. Variables related to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * discard_state are reset here as needed (eg discard_cursor). @discard_state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * and @discard_index are remembered as it may change while we're discarding,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * but we want the discard to execute in the context determined here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static struct btrfs_block_group *peek_discard_list(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) enum btrfs_discard_state *discard_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int *discard_index, u64 now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct btrfs_block_group *block_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) block_group = find_next_block_group(discard_ctl, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (block_group && now >= block_group->discard_eligible_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (block_group->discard_index == BTRFS_DISCARD_INDEX_UNUSED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) block_group->used != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (btrfs_is_block_group_data_only(block_group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) __add_to_discard_list(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) list_del_init(&block_group->discard_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (block_group->discard_state == BTRFS_DISCARD_RESET_CURSOR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) block_group->discard_cursor = block_group->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) block_group->discard_state = BTRFS_DISCARD_EXTENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) discard_ctl->block_group = block_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (block_group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) *discard_state = block_group->discard_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) *discard_index = block_group->discard_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return block_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * btrfs_discard_check_filter - updates a block groups filters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * @block_group: block group of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * @bytes: recently freed region size after coalescing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * Async discard maintains multiple lists with progressively smaller filters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * to prioritize discarding based on size. Should a free space that matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * a larger filter be returned to the free_space_cache, prioritize that discard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * by moving @block_group to the proper filter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) void btrfs_discard_check_filter(struct btrfs_block_group *block_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u64 bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct btrfs_discard_ctl *discard_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (!block_group ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) !btrfs_test_opt(block_group->fs_info, DISCARD_ASYNC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) discard_ctl = &block_group->fs_info->discard_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (block_group->discard_index > BTRFS_DISCARD_INDEX_START &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) bytes >= discard_minlen[block_group->discard_index - 1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) remove_from_discard_list(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) for (i = BTRFS_DISCARD_INDEX_START; i < BTRFS_NR_DISCARD_LISTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (bytes >= discard_minlen[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) block_group->discard_index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) add_to_discard_list(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * btrfs_update_discard_index - moves a block group along the discard lists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * @block_group: block_group of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Increment @block_group's discard_index. If it falls of the list, let it be.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * Otherwise add it back to the appropriate list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static void btrfs_update_discard_index(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct btrfs_block_group *block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) block_group->discard_index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (block_group->discard_index == BTRFS_NR_DISCARD_LISTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) block_group->discard_index = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) add_to_discard_list(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * btrfs_discard_cancel_work - remove a block_group from the discard lists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * @block_group: block_group of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * This removes @block_group from the discard lists. If necessary, it waits on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * the current work and then reschedules the delayed work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) void btrfs_discard_cancel_work(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct btrfs_block_group *block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (remove_from_discard_list(discard_ctl, block_group)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) cancel_delayed_work_sync(&discard_ctl->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) btrfs_discard_schedule_work(discard_ctl, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * btrfs_discard_queue_work - handles queuing the block_groups
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * @block_group: block_group of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * This maintains the LRU order of the discard lists.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) void btrfs_discard_queue_work(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct btrfs_block_group *block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (!block_group || !btrfs_test_opt(block_group->fs_info, DISCARD_ASYNC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (block_group->used == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) add_to_discard_unused_list(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) add_to_discard_list(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (!delayed_work_pending(&discard_ctl->work))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) btrfs_discard_schedule_work(discard_ctl, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static void __btrfs_discard_schedule_work(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) u64 now, bool override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct btrfs_block_group *block_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (!btrfs_run_discard_work(discard_ctl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!override && delayed_work_pending(&discard_ctl->work))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) block_group = find_next_block_group(discard_ctl, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (block_group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) unsigned long delay = discard_ctl->delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) u32 kbps_limit = READ_ONCE(discard_ctl->kbps_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * A single delayed workqueue item is responsible for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * discarding, so we can manage the bytes rate limit by keeping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * track of the previous discard.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (kbps_limit && discard_ctl->prev_discard) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) u64 bps_limit = ((u64)kbps_limit) * SZ_1K;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) u64 bps_delay = div64_u64(discard_ctl->prev_discard *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) MSEC_PER_SEC, bps_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) delay = max(delay, msecs_to_jiffies(bps_delay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * This timeout is to hopefully prevent immediate discarding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * in a recently allocated block group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (now < block_group->discard_eligible_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u64 bg_timeout = block_group->discard_eligible_time - now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) delay = max(delay, nsecs_to_jiffies(bg_timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) mod_delayed_work(discard_ctl->discard_workers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) &discard_ctl->work, delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * btrfs_discard_schedule_work - responsible for scheduling the discard work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * @override: override the current timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * Discards are issued by a delayed workqueue item. @override is used to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * update the current delay as the baseline delay interval is reevaluated on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) * transaction commit. This is also maxed with any other rate limit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) void btrfs_discard_schedule_work(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) bool override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) const u64 now = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) __btrfs_discard_schedule_work(discard_ctl, now, override);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * btrfs_finish_discard_pass - determine next step of a block_group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * @block_group: block_group of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * This determines the next step for a block group after it's finished going
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * through a pass on a discard list. If it is unused and fully trimmed, we can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * mark it unused and send it to the unused_bgs path. Otherwise, pass it onto
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * the appropriate filter list or let it fall off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static void btrfs_finish_discard_pass(struct btrfs_discard_ctl *discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct btrfs_block_group *block_group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) remove_from_discard_list(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (block_group->used == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (btrfs_is_free_space_trimmed(block_group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) btrfs_mark_bg_unused(block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) add_to_discard_unused_list(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) btrfs_update_discard_index(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * btrfs_discard_workfn - discard work function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * @work: work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * This finds the next block_group to start discarding and then discards a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * single region. It does this in a two-pass fashion: first extents and second
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * bitmaps. Completely discarded block groups are sent to the unused_bgs path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static void btrfs_discard_workfn(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) struct btrfs_discard_ctl *discard_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct btrfs_block_group *block_group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) enum btrfs_discard_state discard_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int discard_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) u64 trimmed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) u64 minlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) u64 now = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) discard_ctl = container_of(work, struct btrfs_discard_ctl, work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) block_group = peek_discard_list(discard_ctl, &discard_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) &discard_index, now);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (!block_group || !btrfs_run_discard_work(discard_ctl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (now < block_group->discard_eligible_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) btrfs_discard_schedule_work(discard_ctl, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) /* Perform discarding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) minlen = discard_minlen[discard_index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (discard_state == BTRFS_DISCARD_BITMAPS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) u64 maxlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * Use the previous levels minimum discard length as the max
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * length filter. In the case something is added to make a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * region go beyond the max filter, the entire bitmap is set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * back to BTRFS_TRIM_STATE_UNTRIMMED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (discard_index != BTRFS_DISCARD_INDEX_UNUSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) maxlen = discard_minlen[discard_index - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) btrfs_trim_block_group_bitmaps(block_group, &trimmed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) block_group->discard_cursor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) btrfs_block_group_end(block_group),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) minlen, maxlen, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) discard_ctl->discard_bitmap_bytes += trimmed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) btrfs_trim_block_group_extents(block_group, &trimmed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) block_group->discard_cursor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) btrfs_block_group_end(block_group),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) minlen, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) discard_ctl->discard_extent_bytes += trimmed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) discard_ctl->prev_discard = trimmed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* Determine next steps for a block_group */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (block_group->discard_cursor >= btrfs_block_group_end(block_group)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (discard_state == BTRFS_DISCARD_BITMAPS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) btrfs_finish_discard_pass(discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) block_group->discard_cursor = block_group->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) if (block_group->discard_state !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) BTRFS_DISCARD_RESET_CURSOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) block_group->discard_state =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) BTRFS_DISCARD_BITMAPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) discard_ctl->block_group = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) __btrfs_discard_schedule_work(discard_ctl, now, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) * btrfs_run_discard_work - determines if async discard should be running
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) * Checks if the file system is writeable and BTRFS_FS_DISCARD_RUNNING is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) bool btrfs_run_discard_work(struct btrfs_discard_ctl *discard_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct btrfs_fs_info *fs_info = container_of(discard_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct btrfs_fs_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) discard_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return (!(fs_info->sb->s_flags & SB_RDONLY) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) test_bit(BTRFS_FS_DISCARD_RUNNING, &fs_info->flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * btrfs_discard_calc_delay - recalculate the base delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * Recalculate the base delay which is based off the total number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * discardable_extents. Clamp this between the lower_limit (iops_limit or 1ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * and the upper_limit (BTRFS_DISCARD_MAX_DELAY_MSEC).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) void btrfs_discard_calc_delay(struct btrfs_discard_ctl *discard_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) s32 discardable_extents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) s64 discardable_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) u32 iops_limit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) unsigned long delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) unsigned long lower_limit = BTRFS_DISCARD_MIN_DELAY_MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) discardable_extents = atomic_read(&discard_ctl->discardable_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (!discardable_extents)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * The following is to fix a potential -1 discrepenancy that we're not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * sure how to reproduce. But given that this is the only place that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * utilizes these numbers and this is only called by from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * btrfs_finish_extent_commit() which is synchronized, we can correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (discardable_extents < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) atomic_add(-discardable_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) &discard_ctl->discardable_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) discardable_bytes = atomic64_read(&discard_ctl->discardable_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (discardable_bytes < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) atomic64_add(-discardable_bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) &discard_ctl->discardable_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (discardable_extents <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) iops_limit = READ_ONCE(discard_ctl->iops_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (iops_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) lower_limit = max_t(unsigned long, lower_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) MSEC_PER_SEC / iops_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) delay = BTRFS_DISCARD_TARGET_MSEC / discardable_extents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) delay = clamp(delay, lower_limit, BTRFS_DISCARD_MAX_DELAY_MSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) discard_ctl->delay = msecs_to_jiffies(delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * btrfs_discard_update_discardable - propagate discard counters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * @block_group: block_group of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * @ctl: free_space_ctl of @block_group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * This propagates deltas of counters up to the discard_ctl. It maintains a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * current counter and a previous counter passing the delta up to the global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * stat. Then the current counter value becomes the previous counter value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) void btrfs_discard_update_discardable(struct btrfs_block_group *block_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct btrfs_free_space_ctl *ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct btrfs_discard_ctl *discard_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) s32 extents_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) s64 bytes_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (!block_group ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) !btrfs_test_opt(block_group->fs_info, DISCARD_ASYNC) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) !btrfs_is_block_group_data_only(block_group))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) discard_ctl = &block_group->fs_info->discard_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) extents_delta = ctl->discardable_extents[BTRFS_STAT_CURR] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ctl->discardable_extents[BTRFS_STAT_PREV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (extents_delta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) atomic_add(extents_delta, &discard_ctl->discardable_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ctl->discardable_extents[BTRFS_STAT_PREV] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ctl->discardable_extents[BTRFS_STAT_CURR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) bytes_delta = ctl->discardable_bytes[BTRFS_STAT_CURR] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ctl->discardable_bytes[BTRFS_STAT_PREV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (bytes_delta) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) atomic64_add(bytes_delta, &discard_ctl->discardable_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ctl->discardable_bytes[BTRFS_STAT_PREV] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) ctl->discardable_bytes[BTRFS_STAT_CURR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * btrfs_discard_punt_unused_bgs_list - punt unused_bgs list to discard lists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * @fs_info: fs_info of interest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * The unused_bgs list needs to be punted to the discard lists because the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * order of operations is changed. In the normal sychronous discard path, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * block groups are trimmed via a single large trim in transaction commit. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * is ultimately what we are trying to avoid with asynchronous discard. Thus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * it must be done before going down the unused_bgs path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) void btrfs_discard_punt_unused_bgs_list(struct btrfs_fs_info *fs_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) struct btrfs_block_group *block_group, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) spin_lock(&fs_info->unused_bgs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) /* We enabled async discard, so punt all to the queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) list_for_each_entry_safe(block_group, next, &fs_info->unused_bgs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) bg_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) list_del_init(&block_group->bg_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) btrfs_put_block_group(block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) btrfs_discard_queue_work(&fs_info->discard_ctl, block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) spin_unlock(&fs_info->unused_bgs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * btrfs_discard_purge_list - purge discard lists
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * @discard_ctl: discard control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * If we are disabling async discard, we may have intercepted block groups that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * are completely free and ready for the unused_bgs path. As discarding will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * now happen in transaction commit or not at all, we can safely mark the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) * corresponding block groups as unused and they will be sent on their merry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) * way to the unused_bgs list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static void btrfs_discard_purge_list(struct btrfs_discard_ctl *discard_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct btrfs_block_group *block_group, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) for (i = 0; i < BTRFS_NR_DISCARD_LISTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) list_for_each_entry_safe(block_group, next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) &discard_ctl->discard_list[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) discard_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) list_del_init(&block_group->discard_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (block_group->used == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) btrfs_mark_bg_unused(block_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) spin_lock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) spin_unlock(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) void btrfs_discard_resume(struct btrfs_fs_info *fs_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (!btrfs_test_opt(fs_info, DISCARD_ASYNC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) btrfs_discard_cleanup(fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) btrfs_discard_punt_unused_bgs_list(fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) set_bit(BTRFS_FS_DISCARD_RUNNING, &fs_info->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) void btrfs_discard_stop(struct btrfs_fs_info *fs_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) clear_bit(BTRFS_FS_DISCARD_RUNNING, &fs_info->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) void btrfs_discard_init(struct btrfs_fs_info *fs_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct btrfs_discard_ctl *discard_ctl = &fs_info->discard_ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) spin_lock_init(&discard_ctl->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) INIT_DELAYED_WORK(&discard_ctl->work, btrfs_discard_workfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) for (i = 0; i < BTRFS_NR_DISCARD_LISTS; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) INIT_LIST_HEAD(&discard_ctl->discard_list[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) discard_ctl->prev_discard = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) atomic_set(&discard_ctl->discardable_extents, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) atomic64_set(&discard_ctl->discardable_bytes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) discard_ctl->max_discard_size = BTRFS_ASYNC_DISCARD_DEFAULT_MAX_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) discard_ctl->delay = BTRFS_DISCARD_MAX_DELAY_MSEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) discard_ctl->iops_limit = BTRFS_DISCARD_MAX_IOPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) discard_ctl->kbps_limit = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) discard_ctl->discard_extent_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) discard_ctl->discard_bitmap_bytes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) atomic64_set(&discard_ctl->discard_bytes_saved, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) void btrfs_discard_cleanup(struct btrfs_fs_info *fs_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) btrfs_discard_stop(fs_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) cancel_delayed_work_sync(&fs_info->discard_ctl.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) btrfs_discard_purge_list(&fs_info->discard_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) }