Skip to content

Commit

Permalink
lib/radix-tree.c: swapoff tmpfs radix_tree: remember to rcu_read_unlock
Browse files Browse the repository at this point in the history
Running fsx on tmpfs with concurrent memhog-swapoff-swapon, lots of

  BUG: sleeping function called from invalid context at kernel/fork.c:606
  in_atomic(): 0, irqs_disabled(): 0, pid: 1394, name: swapoff
  1 lock held by swapoff/1394:
   #0:  (rcu_read_lock){.+.+.+}, at: [<ffffffff812520a1>] radix_tree_locate_item+0x1f/0x2b6

followed by

  ================================================
  [ BUG: lock held when returning to user space! ]
  3.14.0-rc1 #3 Not tainted
  ------------------------------------------------
  swapoff/1394 is leaving the kernel with locks still held!
  1 lock held by swapoff/1394:
   #0:  (rcu_read_lock){.+.+.+}, at: [<ffffffff812520a1>] radix_tree_locate_item+0x1f/0x2b6

after which the system recovered nicely.

Whoops, I long ago forgot the rcu_read_unlock() on one unlikely branch.

Fixes e504f3f ("tmpfs radix_tree: locate_item to speed up swapoff")

Signed-off-by: Hugh Dickins <[email protected]>
Cc: Johannes Weiner <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Hugh Dickins authored and torvalds committed Mar 4, 2014
1 parent 3b7a641 commit 5f30fc9
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lib/radix-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1253,8 +1253,10 @@ unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item)

node = indirect_to_ptr(node);
max_index = radix_tree_maxindex(node->height);
if (cur_index > max_index)
if (cur_index > max_index) {
rcu_read_unlock();
break;
}

cur_index = __locate(node, item, cur_index, &found_index);
rcu_read_unlock();
Expand Down

0 comments on commit 5f30fc9

Please sign in to comment.