Skip to content

Commit

Permalink
btrfs: keep track of discard reuse stats
Browse files Browse the repository at this point in the history
Keep track of how much we are discarding and how often we are reusing
with async discard. The discard_*_bytes values don't need any special
protection because the work item provides the single threaded access.

Reviewed-by: Josef Bacik <[email protected]>
Signed-off-by: Dennis Zhou <[email protected]>
Reviewed-by: David Sterba <[email protected]>
Signed-off-by: David Sterba <[email protected]>
  • Loading branch information
dennisszhou authored and kdave committed Jan 20, 2020
1 parent 5cb0724 commit 9ddf648
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 0 deletions.
3 changes: 3 additions & 0 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,9 @@ struct btrfs_discard_ctl {
unsigned long delay;
u32 iops_limit;
u32 kbps_limit;
u64 discard_extent_bytes;
u64 discard_bitmap_bytes;
atomic64_t discard_bytes_saved;
};

/* delayed seq elem */
Expand Down
5 changes: 5 additions & 0 deletions fs/btrfs/discard.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,11 +417,13 @@ static void btrfs_discard_workfn(struct work_struct *work)
block_group->discard_cursor,
btrfs_block_group_end(block_group),
minlen, maxlen, true);
discard_ctl->discard_bitmap_bytes += trimmed;
} else {
btrfs_trim_block_group_extents(block_group, &trimmed,
block_group->discard_cursor,
btrfs_block_group_end(block_group),
minlen, true);
discard_ctl->discard_extent_bytes += trimmed;
}

discard_ctl->prev_discard = trimmed;
Expand Down Expand Up @@ -626,6 +628,9 @@ void btrfs_discard_init(struct btrfs_fs_info *fs_info)
discard_ctl->delay = BTRFS_DISCARD_MAX_DELAY_MSEC;
discard_ctl->iops_limit = BTRFS_DISCARD_MAX_IOPS;
discard_ctl->kbps_limit = 0;
discard_ctl->discard_extent_bytes = 0;
discard_ctl->discard_bitmap_bytes = 0;
atomic64_set(&discard_ctl->discard_bytes_saved, 0);
}

void btrfs_discard_cleanup(struct btrfs_fs_info *fs_info)
Expand Down
14 changes: 14 additions & 0 deletions fs/btrfs/free-space-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -2842,6 +2842,8 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group *block_group,
u64 *max_extent_size)
{
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
struct btrfs_discard_ctl *discard_ctl =
&block_group->fs_info->discard_ctl;
struct btrfs_free_space *entry = NULL;
u64 bytes_search = bytes + empty_size;
u64 ret = 0;
Expand All @@ -2858,6 +2860,10 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group *block_group,
ret = offset;
if (entry->bitmap) {
bitmap_clear_bits(ctl, entry, offset, bytes);

if (!btrfs_free_space_trimmed(entry))
atomic64_add(bytes, &discard_ctl->discard_bytes_saved);

if (!entry->bytes)
free_bitmap(ctl, entry);
} else {
Expand All @@ -2866,6 +2872,9 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group *block_group,
align_gap = entry->offset;
align_gap_trim_state = entry->trim_state;

if (!btrfs_free_space_trimmed(entry))
atomic64_add(bytes, &discard_ctl->discard_bytes_saved);

entry->offset = offset + bytes;
WARN_ON(entry->bytes < bytes + align_gap_len);

Expand Down Expand Up @@ -2969,6 +2978,8 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group *block_group,
u64 min_start, u64 *max_extent_size)
{
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
struct btrfs_discard_ctl *discard_ctl =
&block_group->fs_info->discard_ctl;
struct btrfs_free_space *entry = NULL;
struct rb_node *node;
u64 ret = 0;
Expand Down Expand Up @@ -3033,6 +3044,9 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group *block_group,

spin_lock(&ctl->tree_lock);

if (!btrfs_free_space_trimmed(entry))
atomic64_add(bytes, &discard_ctl->discard_bytes_saved);

ctl->free_space -= bytes;
if (!entry->bitmap && !btrfs_free_space_trimmed(entry))
ctl->discardable_bytes[BTRFS_STAT_CURR] -= bytes;
Expand Down
36 changes: 36 additions & 0 deletions fs/btrfs/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,39 @@ static ssize_t btrfs_discardable_extents_show(struct kobject *kobj,
}
BTRFS_ATTR(discard, discardable_extents, btrfs_discardable_extents_show);

static ssize_t btrfs_discard_bitmap_bytes_show(struct kobject *kobj,
struct kobj_attribute *a,
char *buf)
{
struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);

return snprintf(buf, PAGE_SIZE, "%lld\n",
fs_info->discard_ctl.discard_bitmap_bytes);
}
BTRFS_ATTR(discard, discard_bitmap_bytes, btrfs_discard_bitmap_bytes_show);

static ssize_t btrfs_discard_bytes_saved_show(struct kobject *kobj,
struct kobj_attribute *a,
char *buf)
{
struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);

return snprintf(buf, PAGE_SIZE, "%lld\n",
atomic64_read(&fs_info->discard_ctl.discard_bytes_saved));
}
BTRFS_ATTR(discard, discard_bytes_saved, btrfs_discard_bytes_saved_show);

static ssize_t btrfs_discard_extent_bytes_show(struct kobject *kobj,
struct kobj_attribute *a,
char *buf)
{
struct btrfs_fs_info *fs_info = discard_to_fs_info(kobj);

return snprintf(buf, PAGE_SIZE, "%lld\n",
fs_info->discard_ctl.discard_extent_bytes);
}
BTRFS_ATTR(discard, discard_extent_bytes, btrfs_discard_extent_bytes_show);

static ssize_t btrfs_discard_iops_limit_show(struct kobject *kobj,
struct kobj_attribute *a,
char *buf)
Expand Down Expand Up @@ -459,6 +492,9 @@ BTRFS_ATTR_RW(discard, max_discard_size, btrfs_discard_max_discard_size_show,
static const struct attribute *discard_debug_attrs[] = {
BTRFS_ATTR_PTR(discard, discardable_bytes),
BTRFS_ATTR_PTR(discard, discardable_extents),
BTRFS_ATTR_PTR(discard, discard_bitmap_bytes),
BTRFS_ATTR_PTR(discard, discard_bytes_saved),
BTRFS_ATTR_PTR(discard, discard_extent_bytes),
BTRFS_ATTR_PTR(discard, iops_limit),
BTRFS_ATTR_PTR(discard, kbps_limit),
BTRFS_ATTR_PTR(discard, max_discard_size),
Expand Down

0 comments on commit 9ddf648

Please sign in to comment.