virtio: serialize the unplugging of virtio memblocks
The below scenario can cause plugging of memory block enter into oom path thus can cause the dead lock scenario: 1) Plug 'm' memory blocks. Happens sequentially under qvm_lock + flush(work). 2) Unplug 'n' memory blocks, that can happen once for a bunch as this get triggered in close(fd) and asynchronously. 3) some blocks from step2 are failed thus the final updated plugged size is much larger than 'qvm_hint_total'(which effects the requested size for the next block to be plugged) 4) Now memory pressure triggered the below: acquire(oom_lock)->qvm_oom_notify->plug memory block. The expectation here is to plug the memory block but because of step 3, the requested size will be still below the plugged size thus it takes the unplug path which again enters into reclaim and stuck on oom_lock. This can be avoided by serializing the step2 which happens under qvm_lock and flush(vm->wq). For the blocks that are failed to unplug will not lead into changing the 'qvm_hint_total' thus not effect the requested size calculation for the next block. Change-Id: I14bd05ef21ada9d183f00f30806b1556eb967099 Signed-off-by: Charan Teja Kalla <quic_charante@quicinc.com>
This commit is contained in:
parent
07ae530480
commit
52b5629ec5
@ -71,10 +71,13 @@ static int qti_virtio_mem_hint_update(struct qti_virtio_mem_hint *hint,
|
||||
static void qti_virtio_mem_hint_kref_release(struct kref *kref)
|
||||
{
|
||||
struct qti_virtio_mem_hint *hint;
|
||||
int rc;
|
||||
|
||||
mutex_lock(&qvm_lock);
|
||||
hint = container_of(kref, struct qti_virtio_mem_hint, kref);
|
||||
WARN_ON(qti_virtio_mem_hint_update(hint, 0, false));
|
||||
rc = qti_virtio_mem_hint_update(hint, 0, true);
|
||||
if (rc)
|
||||
pr_err("Possible permanent plug of memory to vm\n");
|
||||
|
||||
list_del(&hint->list);
|
||||
mutex_unlock(&qvm_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user