From bca1a290033d20981e11f81ae4207e4d0fa5b1e6 Mon Sep 17 00:00:00 2001 From: Wang Shilong Date: Sun, 26 Jan 2014 22:32:18 +0800 Subject: Btrfs: add a reschedule point in btrfs_find_all_roots() I can easily trigger the following warnings when enabling quota in my virtual machine(running Opensuse), Steps are firstly creating a subvolume full of fragment extents, and then create many snapshots (500 in my test case). [ 2362.808459] BUG: soft lockup - CPU#0 stuck for 22s! [btrfs-qgroup-re:1970] [ 2362.809023] task: e4af8450 ti: e371c000 task.ti: e371c000 [ 2362.809026] EIP: 0060:[] EFLAGS: 00000246 CPU: 0 [ 2362.809049] EIP is at __merge_refs+0x5e/0x100 [btrfs] [ 2362.809051] EAX: 00000000 EBX: cfadbcf0 ECX: 00000000 EDX: cfadbcb0 [ 2362.809052] ESI: dd8d3370 EDI: e371dde0 EBP: e371dd6c ESP: e371dd5c [ 2362.809054] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 [ 2362.809055] CR0: 80050033 CR2: ac454d50 CR3: 009a9000 CR4: 001407d0 [ 2362.809099] Stack: [ 2362.809100] 00000001 e371dde0 dfcc6890 f29f8000 e371de28 fa39016d 00000011 00000001 [ 2362.809105] 99bfc000 00000000 93928000 00000000 00000001 00000050 e371dda8 00000001 [ 2362.809109] f3a31000 f3413000 00000001 e371ddb8 000040a8 00000202 00000000 00000023 [ 2362.809113] Call Trace: [ 2362.809136] [] find_parent_nodes+0x34d/0x1280 [btrfs] [ 2362.809156] [] btrfs_find_all_roots+0xb2/0x110 [btrfs] [ 2362.809174] [] btrfs_qgroup_rescan_worker+0x358/0x7a0 [btrfs] [ 2362.809180] [] ? lock_timer_base.isra.39+0x1e/0x40 [ 2362.809199] [] worker_loop+0xff/0x470 [btrfs] [ 2362.809204] [] ? __wake_up_locked+0x1a/0x20 [ 2362.809221] [] ? btrfs_queue_worker+0x2b0/0x2b0 [btrfs] [ 2362.809225] [] kthread+0x9c/0xb0 [ 2362.809229] [] ret_from_kernel_thread+0x1b/0x30 [ 2362.809233] [] ? kthread_create_on_node+0x110/0x110 By adding a reschedule point at the end of btrfs_find_all_roots(), i no longer hit these warnings. Cc: Josef Bacik Signed-off-by: Wang Shilong Reviewed-by: David Sterba Signed-off-by: Josef Bacik Signed-off-by: Chris Mason --- fs/btrfs/backref.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 55ffcf44b909..7966acd5dc7f 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c @@ -1118,6 +1118,7 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans, if (!node) break; bytenr = node->val; + cond_resched(); } ulist_free(tmp); -- cgit v1.2.1