Message ID | b0dada84ff74a4c7246acad7fe78250550b89f7f.1577999991.git.dennis@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: async discard follow up | expand |
On Thu, Jan 02, 2020 at 04:26:37PM -0500, Dennis Zhou wrote: > Throttle the maximum size of a discard so that we can provide an upper > bound for the rate of async discard. While the block layer is able to > split discards into the appropriate sized discards, we want to be able > to account more accurately the rate at which we are consuming ncq slots > as well as limit the upper bound of work for a discard. > > Signed-off-by: Dennis Zhou <dennis@kernel.org> > Reviewed-by: Josef Bacik <josef@toxicpanda.com> > --- > fs/btrfs/discard.h | 5 +++++ > fs/btrfs/free-space-cache.c | 41 +++++++++++++++++++++++++++++-------- > 2 files changed, 37 insertions(+), 9 deletions(-) > > diff --git a/fs/btrfs/discard.h b/fs/btrfs/discard.h > index 5250fe178e49..562c60fab77a 100644 > --- a/fs/btrfs/discard.h > +++ b/fs/btrfs/discard.h > @@ -3,10 +3,15 @@ > #ifndef BTRFS_DISCARD_H > #define BTRFS_DISCARD_H > > +#include <linux/sizes.h> > + > struct btrfs_fs_info; > struct btrfs_discard_ctl; > struct btrfs_block_group; > > +/* Discard size limits */ > +#define BTRFS_ASYNC_DISCARD_MAX_SIZE (SZ_64M) > + > /* Work operations */ > void btrfs_discard_cancel_work(struct btrfs_discard_ctl *discard_ctl, > struct btrfs_block_group *block_group); > diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c > index 40fb918a82f4..34291c777998 100644 > --- a/fs/btrfs/free-space-cache.c > +++ b/fs/btrfs/free-space-cache.c > @@ -3466,16 +3466,36 @@ static int trim_no_bitmap(struct btrfs_block_group *block_group, > extent_start = entry->offset; > extent_bytes = entry->bytes; > extent_trim_state = entry->trim_state; > - start = max(start, extent_start); > - bytes = min(extent_start + extent_bytes, end) - start; > - if (bytes < minlen) { > - spin_unlock(&ctl->tree_lock); > - mutex_unlock(&ctl->cache_writeout_mutex); > - goto next; > - } > + if (async) { > + start = entry->offset; > + bytes = entry->bytes; > + if (bytes < minlen) { > + spin_unlock(&ctl->tree_lock); > + mutex_unlock(&ctl->cache_writeout_mutex); > + goto next; > + } > + unlink_free_space(ctl, entry); > + if (bytes > BTRFS_ASYNC_DISCARD_MAX_SIZE) { > + bytes = extent_bytes = > + BTRFS_ASYNC_DISCARD_MAX_SIZE; You still left one chain assignment here, fixed and also in the followup patch that switches to the variable limit.
diff --git a/fs/btrfs/discard.h b/fs/btrfs/discard.h index 5250fe178e49..562c60fab77a 100644 --- a/fs/btrfs/discard.h +++ b/fs/btrfs/discard.h @@ -3,10 +3,15 @@ #ifndef BTRFS_DISCARD_H #define BTRFS_DISCARD_H +#include <linux/sizes.h> + struct btrfs_fs_info; struct btrfs_discard_ctl; struct btrfs_block_group; +/* Discard size limits */ +#define BTRFS_ASYNC_DISCARD_MAX_SIZE (SZ_64M) + /* Work operations */ void btrfs_discard_cancel_work(struct btrfs_discard_ctl *discard_ctl, struct btrfs_block_group *block_group); diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 40fb918a82f4..34291c777998 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -3466,16 +3466,36 @@ static int trim_no_bitmap(struct btrfs_block_group *block_group, extent_start = entry->offset; extent_bytes = entry->bytes; extent_trim_state = entry->trim_state; - start = max(start, extent_start); - bytes = min(extent_start + extent_bytes, end) - start; - if (bytes < minlen) { - spin_unlock(&ctl->tree_lock); - mutex_unlock(&ctl->cache_writeout_mutex); - goto next; - } + if (async) { + start = entry->offset; + bytes = entry->bytes; + if (bytes < minlen) { + spin_unlock(&ctl->tree_lock); + mutex_unlock(&ctl->cache_writeout_mutex); + goto next; + } + unlink_free_space(ctl, entry); + if (bytes > BTRFS_ASYNC_DISCARD_MAX_SIZE) { + bytes = extent_bytes = + BTRFS_ASYNC_DISCARD_MAX_SIZE; + entry->offset += BTRFS_ASYNC_DISCARD_MAX_SIZE; + entry->bytes -= BTRFS_ASYNC_DISCARD_MAX_SIZE; + link_free_space(ctl, entry); + } else { + kmem_cache_free(btrfs_free_space_cachep, entry); + } + } else { + start = max(start, extent_start); + bytes = min(extent_start + extent_bytes, end) - start; + if (bytes < minlen) { + spin_unlock(&ctl->tree_lock); + mutex_unlock(&ctl->cache_writeout_mutex); + goto next; + } - unlink_free_space(ctl, entry); - kmem_cache_free(btrfs_free_space_cachep, entry); + unlink_free_space(ctl, entry); + kmem_cache_free(btrfs_free_space_cachep, entry); + } spin_unlock(&ctl->tree_lock); trim_entry.start = extent_start; @@ -3639,6 +3659,9 @@ static int trim_bitmaps(struct btrfs_block_group *block_group, goto next; } + if (async && bytes > BTRFS_ASYNC_DISCARD_MAX_SIZE) + bytes = BTRFS_ASYNC_DISCARD_MAX_SIZE; + bitmap_clear_bits(ctl, entry, start, bytes); if (entry->bytes == 0) free_bitmap(ctl, entry);