radix: Use call_rcu() to free r_nodes
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 8 Jun 2018 16:42:11 +0000 (12:42 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 8 Jun 2018 16:42:11 +0000 (12:42 -0400)
commit22f750ab2c06d7c672871a2bc5c47c164bebbf0d
treed48531e5889ef7725d503c47fa14baf371b464d6
parent567d6f11934b0105bc3348825a8cf2fa50cb957d
radix: Use call_rcu() to free r_nodes

The radix code can be called from call_rcu().  That means it can't use
blocking RCU primitives, such as synchronize_rcu().  Alternatively, we
could have a racy destruction primitive, but that didn't seem worth the
effort.

For those curious, you could trigger this bug by deleting a moderately
sized file that was in the page cache.  e.g.

$ get_html; rm bin/get_html

You'll get a panic / BT similar to this:

 #02 [<0xffffffffc2058932>] in synchronize_rcu
 #03 [<0xffffffffc205741f>] in __radix_remove_slot
 #04 [<0xffffffffc2057566>] in rnode_for_each
 #05 [<0xffffffffc20574e8>] in rnode_for_each
 #06 [<0xffffffffc20578db>] in radix_for_each_slot
 #07 [<0xffffffffc204f9af>] in pm_destroy
 #08 [<0xffffffffc203fdcb>] in cleanup_fs_file
 #09 [<0xffffffffc204a418>] in __tf_free
 #10 [<0xffffffffc204a4a0>] in __tf_free_rcu
 #11 [<0xffffffffc2057f92>] in rcu_exec_cb
 #12 [<0xffffffffc2058232>] in rcu_mgmt_ktask

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/include/radix.h
kern/src/radix.c