Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 49958fd7 authored by Josef Bacik's avatar Josef Bacik Committed by Chris Mason
Browse files

Btrfs: change the ordered tree to use a spinlock instead of a mutex



The ordered tree used to need a mutex, but currently all we use it for is to
protect the rb_tree, and a spin_lock is just fine for that.  Using a spin_lock
instead makes dbench run a little faster, 58 mb/s instead of 51 mb/s, and have
less latency, 3445.138 ms instead of 3820.633 ms.

Signed-off-by: default avatarJosef Bacik <josef@redhat.com>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 4125bf76
Loading
Loading
Loading
Loading
+17 −17
Original line number Original line Diff line number Diff line
@@ -174,7 +174,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
	if (!entry)
	if (!entry)
		return -ENOMEM;
		return -ENOMEM;


	mutex_lock(&tree->mutex);
	entry->file_offset = file_offset;
	entry->file_offset = file_offset;
	entry->start = start;
	entry->start = start;
	entry->len = len;
	entry->len = len;
@@ -190,16 +189,17 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
	INIT_LIST_HEAD(&entry->list);
	INIT_LIST_HEAD(&entry->list);
	INIT_LIST_HEAD(&entry->root_extent_list);
	INIT_LIST_HEAD(&entry->root_extent_list);


	spin_lock(&tree->lock);
	node = tree_insert(&tree->tree, file_offset,
	node = tree_insert(&tree->tree, file_offset,
			   &entry->rb_node);
			   &entry->rb_node);
	BUG_ON(node);
	BUG_ON(node);
	spin_unlock(&tree->lock);


	spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
	spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
	list_add_tail(&entry->root_extent_list,
	list_add_tail(&entry->root_extent_list,
		      &BTRFS_I(inode)->root->fs_info->ordered_extents);
		      &BTRFS_I(inode)->root->fs_info->ordered_extents);
	spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
	spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);


	mutex_unlock(&tree->mutex);
	BUG_ON(node);
	BUG_ON(node);
	return 0;
	return 0;
}
}
@@ -216,9 +216,9 @@ int btrfs_add_ordered_sum(struct inode *inode,
	struct btrfs_ordered_inode_tree *tree;
	struct btrfs_ordered_inode_tree *tree;


	tree = &BTRFS_I(inode)->ordered_tree;
	tree = &BTRFS_I(inode)->ordered_tree;
	mutex_lock(&tree->mutex);
	spin_lock(&tree->lock);
	list_add_tail(&sum->list, &entry->list);
	list_add_tail(&sum->list, &entry->list);
	mutex_unlock(&tree->mutex);
	spin_unlock(&tree->lock);
	return 0;
	return 0;
}
}


@@ -240,7 +240,7 @@ int btrfs_dec_test_ordered_pending(struct inode *inode,
	int ret;
	int ret;


	tree = &BTRFS_I(inode)->ordered_tree;
	tree = &BTRFS_I(inode)->ordered_tree;
	mutex_lock(&tree->mutex);
	spin_lock(&tree->lock);
	node = tree_search(tree, file_offset);
	node = tree_search(tree, file_offset);
	if (!node) {
	if (!node) {
		ret = 1;
		ret = 1;
@@ -264,7 +264,7 @@ int btrfs_dec_test_ordered_pending(struct inode *inode,
	else
	else
		ret = 1;
		ret = 1;
out:
out:
	mutex_unlock(&tree->mutex);
	spin_unlock(&tree->lock);
	return ret == 0;
	return ret == 0;
}
}


@@ -291,7 +291,7 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)


/*
/*
 * remove an ordered extent from the tree.  No references are dropped
 * remove an ordered extent from the tree.  No references are dropped
 * and you must wake_up entry->wait.  You must hold the tree mutex
 * and you must wake_up entry->wait.  You must hold the tree lock
 * while you call this function.
 * while you call this function.
 */
 */
static int __btrfs_remove_ordered_extent(struct inode *inode,
static int __btrfs_remove_ordered_extent(struct inode *inode,
@@ -340,9 +340,9 @@ int btrfs_remove_ordered_extent(struct inode *inode,
	int ret;
	int ret;


	tree = &BTRFS_I(inode)->ordered_tree;
	tree = &BTRFS_I(inode)->ordered_tree;
	mutex_lock(&tree->mutex);
	spin_lock(&tree->lock);
	ret = __btrfs_remove_ordered_extent(inode, entry);
	ret = __btrfs_remove_ordered_extent(inode, entry);
	mutex_unlock(&tree->mutex);
	spin_unlock(&tree->lock);
	wake_up(&entry->wait);
	wake_up(&entry->wait);


	return ret;
	return ret;
@@ -567,7 +567,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
	struct btrfs_ordered_extent *entry = NULL;
	struct btrfs_ordered_extent *entry = NULL;


	tree = &BTRFS_I(inode)->ordered_tree;
	tree = &BTRFS_I(inode)->ordered_tree;
	mutex_lock(&tree->mutex);
	spin_lock(&tree->lock);
	node = tree_search(tree, file_offset);
	node = tree_search(tree, file_offset);
	if (!node)
	if (!node)
		goto out;
		goto out;
@@ -578,7 +578,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
	if (entry)
	if (entry)
		atomic_inc(&entry->refs);
		atomic_inc(&entry->refs);
out:
out:
	mutex_unlock(&tree->mutex);
	spin_unlock(&tree->lock);
	return entry;
	return entry;
}
}


@@ -594,7 +594,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
	struct btrfs_ordered_extent *entry = NULL;
	struct btrfs_ordered_extent *entry = NULL;


	tree = &BTRFS_I(inode)->ordered_tree;
	tree = &BTRFS_I(inode)->ordered_tree;
	mutex_lock(&tree->mutex);
	spin_lock(&tree->lock);
	node = tree_search(tree, file_offset);
	node = tree_search(tree, file_offset);
	if (!node)
	if (!node)
		goto out;
		goto out;
@@ -602,7 +602,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
	entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
	entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
	atomic_inc(&entry->refs);
	atomic_inc(&entry->refs);
out:
out:
	mutex_unlock(&tree->mutex);
	spin_unlock(&tree->lock);
	return entry;
	return entry;
}
}


@@ -629,7 +629,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
	else
	else
		offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);
		offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);


	mutex_lock(&tree->mutex);
	spin_lock(&tree->lock);
	disk_i_size = BTRFS_I(inode)->disk_i_size;
	disk_i_size = BTRFS_I(inode)->disk_i_size;


	/* truncate file */
	/* truncate file */
@@ -735,7 +735,7 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
	 */
	 */
	if (ordered)
	if (ordered)
		__btrfs_remove_ordered_extent(inode, ordered);
		__btrfs_remove_ordered_extent(inode, ordered);
	mutex_unlock(&tree->mutex);
	spin_unlock(&tree->lock);
	if (ordered)
	if (ordered)
		wake_up(&ordered->wait);
		wake_up(&ordered->wait);
	return ret;
	return ret;
@@ -762,7 +762,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
	if (!ordered)
	if (!ordered)
		return 1;
		return 1;


	mutex_lock(&tree->mutex);
	spin_lock(&tree->lock);
	list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
	list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
		if (disk_bytenr >= ordered_sum->bytenr) {
		if (disk_bytenr >= ordered_sum->bytenr) {
			num_sectors = ordered_sum->len / sectorsize;
			num_sectors = ordered_sum->len / sectorsize;
@@ -777,7 +777,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
		}
		}
	}
	}
out:
out:
	mutex_unlock(&tree->mutex);
	spin_unlock(&tree->lock);
	btrfs_put_ordered_extent(ordered);
	btrfs_put_ordered_extent(ordered);
	return ret;
	return ret;
}
}
+2 −2
Original line number Original line Diff line number Diff line
@@ -21,7 +21,7 @@


/* one of these per inode */
/* one of these per inode */
struct btrfs_ordered_inode_tree {
struct btrfs_ordered_inode_tree {
	struct mutex mutex;
	spinlock_t lock;
	struct rb_root tree;
	struct rb_root tree;
	struct rb_node *last;
	struct rb_node *last;
};
};
@@ -128,7 +128,7 @@ static inline int btrfs_ordered_sum_size(struct btrfs_root *root,
static inline void
static inline void
btrfs_ordered_inode_tree_init(struct btrfs_ordered_inode_tree *t)
btrfs_ordered_inode_tree_init(struct btrfs_ordered_inode_tree *t)
{
{
	mutex_init(&t->mutex);
	spin_lock_init(&t->lock);
	t->tree = RB_ROOT;
	t->tree = RB_ROOT;
	t->last = NULL;
	t->last = NULL;
}
}