vold: do not acquire lock when abort fuse

reboot maybe cause a deadlock scenario:

1:init->vdc->vold for abort_fuse blocked on futex hold by another
vold binder_x

2:binder_x blocked in binder_ioctl_write_read wait a dead service's
response

3:dead service is exiting and schedule a deferred work for put files
in binder_vma_close, after put files is completed, the binder_x will
eventually wake up

4:kworker execute binder_deferred_work is blocked on fuse request:
crash> bt 1707
PID: 1707   TASK: ffffffe366175e80  CPU: 2   COMMAND: "kworker/2:4"
 #0 [ffffff801b8b3ac0] __switch_to at ffffff962ce88a60
 #1 [ffffff801b8b3b10] __schedule at ffffff962e2d3d30
 #2 [ffffff801b8b3b70] schedule at ffffff962e2d3ff4
 #3 [ffffff801b8b3bc0] __fuse_request_send at ffffff962d20e008
 #4 [ffffff801b8b3c00] fuse_request_send at ffffff962d20deac
 #5 [ffffff801b8b3c30] fuse_flush at ffffff962d217fa4
 #6 [ffffff801b8b3c80] filp_close at ffffff962d0bd7b4
 #7 [ffffff801b8b3cb0] put_files_struct at ffffff962d0e7658
 #8 [ffffff801b8b3d30] binder_deferred_func at ffffff962dc9e60c
 #9 [ffffff801b8b3d90] process_one_work at ffffff962cee761c
 #10 [ffffff801b8b3e00] worker_thread at ffffff962cee7a68
 #11 [ffffff801b8b3e60] kthread at ffffff962ceecc14
waiting for init abort_fuse

suggested by maco, do not acquire lock when abort fuse.

Test: reboot stress test

Change-Id: If6dd7f5e9c413a16ba047204c33d82d6ff41c4ae
Signed-off-by: lijiazi <lijiazi@xiaomi.com>
This commit is contained in:
lijiazi 2021-03-17 16:51:16 +08:00 committed by jiazi li
parent 759022d0f1
commit ffe7622d83

View file

@ -178,7 +178,9 @@ binder::Status VoldNativeService::shutdown() {
binder::Status VoldNativeService::abortFuse() { binder::Status VoldNativeService::abortFuse() {
ENFORCE_SYSTEM_OR_ROOT; ENFORCE_SYSTEM_OR_ROOT;
ACQUIRE_LOCK; // if acquire lock, maybe lead to a deadlock if lock is held by a
// thread that is blocked on a FUSE operation.
// abort fuse doesn't need to access any state, so do not acquire lock
return translate(VolumeManager::Instance()->abortFuse()); return translate(VolumeManager::Instance()->abortFuse());
} }