mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-19 23:56:16 +07:00
Btrfs: Add efficient dirty accounting to the extent_map tree
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
448d640b66
commit
ca6646264b
@ -210,7 +210,7 @@ static int btree_writepages(struct address_space *mapping,
|
|||||||
{
|
{
|
||||||
struct extent_map_tree *tree;
|
struct extent_map_tree *tree;
|
||||||
tree = &BTRFS_I(mapping->host)->extent_tree;
|
tree = &BTRFS_I(mapping->host)->extent_tree;
|
||||||
if (wbc->sync_mode == WB_SYNC_NONE && current_is_pdflush()) {
|
if (wbc->sync_mode == WB_SYNC_NONE) {
|
||||||
u64 num_dirty;
|
u64 num_dirty;
|
||||||
u64 start = 0;
|
u64 start = 0;
|
||||||
unsigned long thresh = 96 * 1024 * 1024;
|
unsigned long thresh = 96 * 1024 * 1024;
|
||||||
@ -218,6 +218,11 @@ static int btree_writepages(struct address_space *mapping,
|
|||||||
if (wbc->for_kupdate)
|
if (wbc->for_kupdate)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (current_is_pdflush()) {
|
||||||
|
thresh = 96 * 1024 * 1024;
|
||||||
|
} else {
|
||||||
|
thresh = 8 * 1024 * 1024;
|
||||||
|
}
|
||||||
num_dirty = count_range_bits(tree, &start, thresh, EXTENT_DIRTY);
|
num_dirty = count_range_bits(tree, &start, thresh, EXTENT_DIRTY);
|
||||||
if (num_dirty < thresh) {
|
if (num_dirty < thresh) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -42,6 +42,7 @@ struct extent_page_data {
|
|||||||
struct extent_map_tree *tree;
|
struct extent_map_tree *tree;
|
||||||
get_extent_t *get_extent;
|
get_extent_t *get_extent;
|
||||||
};
|
};
|
||||||
|
|
||||||
int __init extent_map_init(void)
|
int __init extent_map_init(void)
|
||||||
{
|
{
|
||||||
extent_map_cache = btrfs_cache_create("extent_map",
|
extent_map_cache = btrfs_cache_create("extent_map",
|
||||||
@ -94,6 +95,7 @@ void extent_map_tree_init(struct extent_map_tree *tree,
|
|||||||
tree->map.rb_node = NULL;
|
tree->map.rb_node = NULL;
|
||||||
tree->state.rb_node = NULL;
|
tree->state.rb_node = NULL;
|
||||||
tree->ops = NULL;
|
tree->ops = NULL;
|
||||||
|
tree->dirty_bytes = 0;
|
||||||
rwlock_init(&tree->lock);
|
rwlock_init(&tree->lock);
|
||||||
spin_lock_init(&tree->lru_lock);
|
spin_lock_init(&tree->lru_lock);
|
||||||
tree->mapping = mapping;
|
tree->mapping = mapping;
|
||||||
@ -414,6 +416,8 @@ static int insert_state(struct extent_map_tree *tree,
|
|||||||
printk("end < start %Lu %Lu\n", end, start);
|
printk("end < start %Lu %Lu\n", end, start);
|
||||||
WARN_ON(1);
|
WARN_ON(1);
|
||||||
}
|
}
|
||||||
|
if (bits & EXTENT_DIRTY)
|
||||||
|
tree->dirty_bytes += end - start + 1;
|
||||||
state->state |= bits;
|
state->state |= bits;
|
||||||
state->start = start;
|
state->start = start;
|
||||||
state->end = end;
|
state->end = end;
|
||||||
@ -476,6 +480,12 @@ static int clear_state_bit(struct extent_map_tree *tree,
|
|||||||
int delete)
|
int delete)
|
||||||
{
|
{
|
||||||
int ret = state->state & bits;
|
int ret = state->state & bits;
|
||||||
|
|
||||||
|
if ((bits & EXTENT_DIRTY) && (state->state & EXTENT_DIRTY)) {
|
||||||
|
u64 range = state->end - state->start + 1;
|
||||||
|
WARN_ON(range > tree->dirty_bytes);
|
||||||
|
tree->dirty_bytes -= range;
|
||||||
|
}
|
||||||
state->state &= ~bits;
|
state->state &= ~bits;
|
||||||
if (wake)
|
if (wake)
|
||||||
wake_up(&state->wq);
|
wake_up(&state->wq);
|
||||||
@ -668,6 +678,17 @@ int wait_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits)
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(wait_extent_bit);
|
EXPORT_SYMBOL(wait_extent_bit);
|
||||||
|
|
||||||
|
static void set_state_bits(struct extent_map_tree *tree,
|
||||||
|
struct extent_state *state,
|
||||||
|
int bits)
|
||||||
|
{
|
||||||
|
if ((bits & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) {
|
||||||
|
u64 range = state->end - state->start + 1;
|
||||||
|
tree->dirty_bytes += range;
|
||||||
|
}
|
||||||
|
state->state |= bits;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set some bits on a range in the tree. This may require allocations
|
* set some bits on a range in the tree. This may require allocations
|
||||||
* or sleeping, so the gfp mask is used to indicate what is allowed.
|
* or sleeping, so the gfp mask is used to indicate what is allowed.
|
||||||
@ -727,7 +748,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits,
|
|||||||
err = -EEXIST;
|
err = -EEXIST;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
state->state |= bits;
|
set_state_bits(tree, state, bits);
|
||||||
start = state->end + 1;
|
start = state->end + 1;
|
||||||
merge_state(tree, state);
|
merge_state(tree, state);
|
||||||
goto search_again;
|
goto search_again;
|
||||||
@ -762,7 +783,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits,
|
|||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
if (state->end <= end) {
|
if (state->end <= end) {
|
||||||
state->state |= bits;
|
set_state_bits(tree, state, bits);
|
||||||
start = state->end + 1;
|
start = state->end + 1;
|
||||||
merge_state(tree, state);
|
merge_state(tree, state);
|
||||||
} else {
|
} else {
|
||||||
@ -808,7 +829,7 @@ int set_extent_bit(struct extent_map_tree *tree, u64 start, u64 end, int bits,
|
|||||||
err = split_state(tree, state, prealloc, end + 1);
|
err = split_state(tree, state, prealloc, end + 1);
|
||||||
BUG_ON(err == -EEXIST);
|
BUG_ON(err == -EEXIST);
|
||||||
|
|
||||||
prealloc->state |= bits;
|
set_state_bits(tree, prealloc, bits);
|
||||||
merge_state(tree, prealloc);
|
merge_state(tree, prealloc);
|
||||||
prealloc = NULL;
|
prealloc = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
@ -1116,6 +1137,11 @@ u64 count_range_bits(struct extent_map_tree *tree,
|
|||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
write_lock_irq(&tree->lock);
|
write_lock_irq(&tree->lock);
|
||||||
|
if (bits == EXTENT_DIRTY) {
|
||||||
|
*start = 0;
|
||||||
|
total_bytes = tree->dirty_bytes;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* this search will find all the extents that end after
|
* this search will find all the extents that end after
|
||||||
* our range starts.
|
* our range starts.
|
||||||
|
@ -40,6 +40,7 @@ struct extent_map_tree {
|
|||||||
struct rb_root map;
|
struct rb_root map;
|
||||||
struct rb_root state;
|
struct rb_root state;
|
||||||
struct address_space *mapping;
|
struct address_space *mapping;
|
||||||
|
u64 dirty_bytes;
|
||||||
rwlock_t lock;
|
rwlock_t lock;
|
||||||
struct extent_map_ops *ops;
|
struct extent_map_ops *ops;
|
||||||
spinlock_t lru_lock;
|
spinlock_t lru_lock;
|
||||||
|
Loading…
Reference in New Issue
Block a user