Hi all,
I am trying to understand the memory barriers used in
btrfs_defrag_root in fs/btrfs/transaction.c.The kernel version I am
looking at is 2.6.34-rc2.
In this function
int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
{
struct btrfs_fs_info *info = root->fs_info;
int ret;
struct btrfs_trans_handle *trans;
unsigned long nr;
smp_mb();
if (root->defrag_running)
return 0;
trans = btrfs_start_transaction(root, 1);
while (1) {
root->defrag_running = 1;
ret = btrfs_defrag_leaves(trans, root, cacheonly);
nr = trans->blocks_used;
btrfs_end_transaction(trans, root);
btrfs_btree_balance_dirty(info->tree_root, nr);
cond_resched();
trans = btrfs_start_transaction(root, 1);
if (root->fs_info->closing || ret != -EAGAIN)
break;
}
root->defrag_running = 0;
smp_mb();
btrfs_end_transaction(trans, root);
return 0;
}
Is the barrier here being used to provide some kind of ordering
constraints between defrag_running and any common memory accessed in
btrfs_start_transaction function and btrfs_end_transaction
function?But these start and end transaction functions take and
release a mutex which should help in ordering as they act as barriers.
Or is it the case when the defrag_running is set to 0 and if it
remains in the write buffer, the barrier helps the check of
defrag_running on some other CPU to gets the updated value of
0.Thus,the barrier seems to provide ordering constraint for accessing
a single variable which is defrag_running.Can I say it is in some way
helping the read to get last updated value thus providing some kind of
write atomicity?
Also,why isn''t a barrier taken after setting the value of
defrag_running to 1?
My understanding of barriers is that it enforces ordering constraints
between instructions before and after the barrier and are used for
instructions involving different memory locations.
Are barriers also used to get the most updated value?I saw a comment
in an old kernel release in file fs/btrfs/disk-io.c function
''btrfs_unplug_io_fn'' as
/*
* page->mapping may change at any time. Get a consistent copy
* and use that for everything below
*/
smp_mb();
mapping = page->mapping;
if (!mapping)
return;
Here from the comment it seems that this barrier is used to get the
most updated value of page mapping.
I am sorry but my understanding of barriers is not very clear.I have
gone through the kernel documentation on memory barriers but they do
not mention anything on barriers being used to get the most updated
value before a read. I am trying understand the use of barriers in the
Linux kernel and I was puzzled by this example.Any help would be
great.
Thanks.
-Abhinav.
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs"
in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html