After processing certain asynchronous requests from VFS, VM would send
an asynchronous reply without supplying the AMF_NOREPLY flag. As a
result, this asynchronous reply could be taken as the result of an
ipc_sendrec() call, causing the entire VM/VFS communication to become
desynchronized. The end result was a deadlock-induced panic during a
later request.
This bug was exposed because of the higher-than-usual concurrency
level in the NetBSD rc scripts. The fix consists of properly setting
the AMF_NOREPLY flag for asynchronous replies.
Change-Id: Iafafe2fdd67f212ecbf27a53862cefba2e4cf7e8
static void handle_memory_final(struct hm_state *state, int result)
{
- int r;
+ int r, flag;
assert(state);
assert(state->valid == VALID);
assert(state->caller == VFS_PROC_NR);
/* If a transaction ID was set, reset it */
msg.m_type = TRNS_ADD_ID(msg.m_type, state->transid);
- }
+ flag = AMF_NOREPLY;
+ } else
+ flag = 0;
- if(asynsend3(state->caller, &msg, 0) != OK) {
+ /*
+ * Use AMF_NOREPLY only if there was a transaction ID, which
+ * signifies that VFS issued the request asynchronously.
+ */
+ if(asynsend3(state->caller, &msg, flag) != OK) {
panic("handle_memory_final: asynsend3 failed");
}