Message ID | 1305149755-4413-1-git-send-email-josef@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 11.05.2011 23:35, Josef Bacik wrote: > If we have particularly full nodes, we could call btrfs_node_blockptr up to 32 > times, which is 32 pairs of kmap/kunmap, which _sucks_. So go ahead and map the > extent buffer while we look for readahead targets. Thanks, > > Signed-off-by: Josef Bacik <josef@redhat.com> > --- > fs/btrfs/ctree.c | 23 +++++++++++++++++++++-- > 1 files changed, 21 insertions(+), 2 deletions(-) > > diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c > index 84d7ca1..009bcf7 100644 > --- a/fs/btrfs/ctree.c > +++ b/fs/btrfs/ctree.c > @@ -1229,6 +1229,7 @@ static void reada_for_search(struct btrfs_root *root, > u64 search; > u64 target; > u64 nread = 0; > + u64 gen; > int direction = path->reada; > struct extent_buffer *eb; > u32 nr; > @@ -1256,6 +1257,15 @@ static void reada_for_search(struct btrfs_root *root, > nritems = btrfs_header_nritems(node); > nr = slot; > while (1) { > + if (!node->map_token) { > + unsigned long offset = btrfs_node_key_ptr_offset(nr); > + map_private_extent_buffer(node, offset, > + sizeof(struct btrfs_key_ptr), > + &node->map_token, > + &node->kaddr, > + &node->map_start, > + &node->map_len, KM_USER1); You can't do that. It puts us in atomic context, and the following readahead_tree_block will try a memory allocation with GFP_NOFS, which leads to a BUG: sleeping function called from invalid context. It didn't fall on our feet earlier because you also turned off readahead, but scrub still uses it. -Arne > + } > if (direction < 0) { > if (nr == 0) > break; > @@ -1273,14 +1283,23 @@ static void reada_for_search(struct btrfs_root *root, > search = btrfs_node_blockptr(node, nr); > if ((search <= target && target - search <= 65536) || > (search > target && search - target <= 65536)) { > - readahead_tree_block(root, search, blocksize, > - btrfs_node_ptr_generation(node, nr)); > + gen = btrfs_node_ptr_generation(node, nr); > + if (node->map_token) { > + unmap_extent_buffer(node, node->map_token, > + KM_USER1); > + node->map_token = NULL; > + } > + readahead_tree_block(root, search, blocksize, gen); > nread += blocksize; > } > nscan++; > if ((nread > 65536 || nscan > 32)) > break; > } > + if (node->map_token) { > + unmap_extent_buffer(node, node->map_token, KM_USER1); > + node->map_token = NULL; > + } > } > > /* -- 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
On 06/08/2011 04:21 AM, Arne Jansen wrote: > On 11.05.2011 23:35, Josef Bacik wrote: >> If we have particularly full nodes, we could call btrfs_node_blockptr up to 32 >> times, which is 32 pairs of kmap/kunmap, which _sucks_. So go ahead and map the >> extent buffer while we look for readahead targets. Thanks, >> >> Signed-off-by: Josef Bacik <josef@redhat.com> >> --- >> fs/btrfs/ctree.c | 23 +++++++++++++++++++++-- >> 1 files changed, 21 insertions(+), 2 deletions(-) >> >> diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c >> index 84d7ca1..009bcf7 100644 >> --- a/fs/btrfs/ctree.c >> +++ b/fs/btrfs/ctree.c >> @@ -1229,6 +1229,7 @@ static void reada_for_search(struct btrfs_root *root, >> u64 search; >> u64 target; >> u64 nread = 0; >> + u64 gen; >> int direction = path->reada; >> struct extent_buffer *eb; >> u32 nr; >> @@ -1256,6 +1257,15 @@ static void reada_for_search(struct btrfs_root *root, >> nritems = btrfs_header_nritems(node); >> nr = slot; >> while (1) { >> + if (!node->map_token) { >> + unsigned long offset = btrfs_node_key_ptr_offset(nr); >> + map_private_extent_buffer(node, offset, >> + sizeof(struct btrfs_key_ptr), >> + &node->map_token, >> + &node->kaddr, >> + &node->map_start, >> + &node->map_len, KM_USER1); > > You can't do that. It puts us in atomic context, and the following > readahead_tree_block will try a memory allocation with GFP_NOFS, > which leads to a BUG: sleeping function called from invalid context. > It didn't fall on our feet earlier because you also turned off > readahead, but scrub still uses it. We don't make any memory allocations within the area that we've kmap_atomic()'ed, something else is going wrong, this patch is fine. Thanks, Josef -- 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
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 84d7ca1..009bcf7 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -1229,6 +1229,7 @@ static void reada_for_search(struct btrfs_root *root, u64 search; u64 target; u64 nread = 0; + u64 gen; int direction = path->reada; struct extent_buffer *eb; u32 nr; @@ -1256,6 +1257,15 @@ static void reada_for_search(struct btrfs_root *root, nritems = btrfs_header_nritems(node); nr = slot; while (1) { + if (!node->map_token) { + unsigned long offset = btrfs_node_key_ptr_offset(nr); + map_private_extent_buffer(node, offset, + sizeof(struct btrfs_key_ptr), + &node->map_token, + &node->kaddr, + &node->map_start, + &node->map_len, KM_USER1); + } if (direction < 0) { if (nr == 0) break; @@ -1273,14 +1283,23 @@ static void reada_for_search(struct btrfs_root *root, search = btrfs_node_blockptr(node, nr); if ((search <= target && target - search <= 65536) || (search > target && search - target <= 65536)) { - readahead_tree_block(root, search, blocksize, - btrfs_node_ptr_generation(node, nr)); + gen = btrfs_node_ptr_generation(node, nr); + if (node->map_token) { + unmap_extent_buffer(node, node->map_token, + KM_USER1); + node->map_token = NULL; + } + readahead_tree_block(root, search, blocksize, gen); nread += blocksize; } nscan++; if ((nread > 65536 || nscan > 32)) break; } + if (node->map_token) { + unmap_extent_buffer(node, node->map_token, KM_USER1); + node->map_token = NULL; + } } /*
If we have particularly full nodes, we could call btrfs_node_blockptr up to 32 times, which is 32 pairs of kmap/kunmap, which _sucks_. So go ahead and map the extent buffer while we look for readahead targets. Thanks, Signed-off-by: Josef Bacik <josef@redhat.com> --- fs/btrfs/ctree.c | 23 +++++++++++++++++++++-- 1 files changed, 21 insertions(+), 2 deletions(-)