linux/drivers/virtio
Michael S. Tsirkin c7cdff0e86 virtio_balloon: fix deadlock on OOM
fill_balloon doing memory allocations under balloon_lock
can cause a deadlock when leak_balloon is called from
virtballoon_oom_notify and tries to take same lock.

To fix, split page allocation and enqueue and do allocations outside the lock.

Here's a detailed analysis of the deadlock by Tetsuo Handa:

In leak_balloon(), mutex_lock(&vb->balloon_lock) is called in order to
serialize against fill_balloon(). But in fill_balloon(),
alloc_page(GFP_HIGHUSER[_MOVABLE] | __GFP_NOMEMALLOC | __GFP_NORETRY) is
called with vb->balloon_lock mutex held. Since GFP_HIGHUSER[_MOVABLE]
implies __GFP_DIRECT_RECLAIM | __GFP_IO | __GFP_FS, despite __GFP_NORETRY
is specified, this allocation attempt might indirectly depend on somebody
else's __GFP_DIRECT_RECLAIM memory allocation. And such indirect
__GFP_DIRECT_RECLAIM memory allocation might call leak_balloon() via
virtballoon_oom_notify() via blocking_notifier_call_chain() callback via
out_of_memory() when it reached __alloc_pages_may_oom() and held oom_lock
mutex. Since vb->balloon_lock mutex is already held by fill_balloon(), it
will cause OOM lockup.

  Thread1                                       Thread2
    fill_balloon()
      takes a balloon_lock
      balloon_page_enqueue()
        alloc_page(GFP_HIGHUSER_MOVABLE)
          direct reclaim (__GFP_FS context)       takes a fs lock
            waits for that fs lock                  alloc_page(GFP_NOFS)
                                                      __alloc_pages_may_oom()
                                                        takes the oom_lock
                                                        out_of_memory()
                                                          blocking_notifier_call_chain()
                                                            leak_balloon()
                                                              tries to take that balloon_lock and deadlocks

Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Wei Wang <wei.w.wang@intel.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2017-11-14 23:57:38 +02:00
..
Kconfig x86/lguest: Remove lguest support 2017-08-24 09:57:28 +02:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
virtio.c virtio: allow drivers to validate features 2017-04-07 16:38:59 +03:00
virtio_balloon.c virtio_balloon: fix deadlock on OOM 2017-11-14 23:57:38 +02:00
virtio_input.c virtio: wrap find_vqs 2017-05-02 23:41:42 +03:00
virtio_mmio.c virtio: add context flag to find vqs 2017-05-02 23:41:43 +03:00
virtio_pci_common.c virtio_pci: fix cpu affinity support 2017-08-25 21:38:26 +03:00
virtio_pci_common.h virtio: add context flag to find vqs 2017-05-02 23:41:43 +03:00
virtio_pci_legacy.c virtio: add context flag to find vqs 2017-05-02 23:41:43 +03:00
virtio_pci_modern.c virtio: add context flag to find vqs 2017-05-02 23:41:43 +03:00
virtio_ring.c SCSI misc on 20170907 2017-09-07 21:11:05 -07:00