* [PATCH] btrfs: backref: Fix soft lockup in __merge_refs function
@ 2016-07-20 7:04 Qu Wenruo
2016-07-26 15:41 ` David Sterba
0 siblings, 1 reply; 2+ messages in thread
From: Qu Wenruo @ 2016-07-20 7:04 UTC (permalink / raw)
To: linux-btrfs
When over 1000 file extents refers to one extent, find_parent_nodes()
will be obviously slow, due to the O(n^2)~O(n^3) loops inside
__merge_refs().
The following ftrace shows the cubic growth of execution time:
256 refs
5) + 91.768 us | __add_keyed_refs.isra.12 [btrfs]();
5) 1.447 us | __add_missing_keys.isra.13 [btrfs]();
5) ! 114.544 us | __merge_refs [btrfs]();
5) ! 136.399 us | __merge_refs [btrfs]();
512 refs
6) ! 279.859 us | __add_keyed_refs.isra.12 [btrfs]();
6) 3.164 us | __add_missing_keys.isra.13 [btrfs]();
6) ! 442.498 us | __merge_refs [btrfs]();
6) # 2091.073 us | __merge_refs [btrfs]();
and 1024 refs
7) ! 368.683 us | __add_keyed_refs.isra.12 [btrfs]();
7) 4.810 us | __add_missing_keys.isra.13 [btrfs]();
7) # 2043.428 us | __merge_refs [btrfs]();
7) * 18964.23 us | __merge_refs [btrfs]();
And sort them into the following char:
(Unit: us)
------------------------------------------------------------------------
Trace function | 256 ref | 512 refs | 1024 refs |
------------------------------------------------------------------------
__add_keyed_refs | 91 | 249 | 368 |
__add_missing_keys | 1 | 3 | 4 |
__merge_refs 1st call | 114 | 442 | 2043 |
__merge_refs 2nd call | 136 | 2091 | 18964 |
------------------------------------------------------------------------
We can see the that __add_keyed_refs() grows almost in linear behavior.
And __add_missing_keys() in this case doesn't change much or takes much
time.
While for the 1st __merge_refs() it's square growth
for the 2nd __merge_refs() call it's cubic growth.
It's no doubt that merge_refs() will take a long long time to execute if
the number of refs continues its grows.
So add a cond_resced() into the loop of __merge_refs().
Although this will solve the problem of soft lockup, we need to use the
new rb_tree based structure introduced by Lu Fengqi to really solve the
long execution time.
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
fs/btrfs/backref.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 8bb3509..4197610d 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -589,6 +589,7 @@ static void __merge_refs(struct list_head *head, int mode)
list_del(&ref2->list);
kmem_cache_free(btrfs_prelim_ref_cache, ref2);
+ cond_resched();
}
}
--
2.9.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] btrfs: backref: Fix soft lockup in __merge_refs function
2016-07-20 7:04 [PATCH] btrfs: backref: Fix soft lockup in __merge_refs function Qu Wenruo
@ 2016-07-26 15:41 ` David Sterba
0 siblings, 0 replies; 2+ messages in thread
From: David Sterba @ 2016-07-26 15:41 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs
On Wed, Jul 20, 2016 at 03:04:18PM +0800, Qu Wenruo wrote:
> Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
> ---
> fs/btrfs/backref.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
> index 8bb3509..4197610d 100644
> --- a/fs/btrfs/backref.c
> +++ b/fs/btrfs/backref.c
> @@ -589,6 +589,7 @@ static void __merge_refs(struct list_head *head, int mode)
>
> list_del(&ref2->list);
> kmem_cache_free(btrfs_prelim_ref_cache, ref2);
> + cond_resched();
For a potentially long loop it's a good idea to add the cond resched,
Reviewed-by: David Sterba <dsterba@suse.com>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-07-26 15:42 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-20 7:04 [PATCH] btrfs: backref: Fix soft lockup in __merge_refs function Qu Wenruo
2016-07-26 15:41 ` David Sterba
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.