virtio-mem: retry fake-offlining via alloc_contig_range() on ZONE_MOVABLE
ZONE_MOVABLE is supposed to give some guarantees, yet, alloc_contig_range() isn't prepared to properly deal with some racy cases properly (e.g., temporary page pinning when exiting processed, PCP). Retry 5 times for now. There is certainly room for improvement in the future. Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Jason Wang <jasowang@redhat.com> Cc: Pankaj Gupta <pankaj.gupta.linux@gmail.com> Signed-off-by: David Hildenbrand <david@redhat.com> Link: https://lore.kernel.org/r/20201112133815.13332-11-david@redhat.com Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
committed by
Michael S. Tsirkin
parent
7a34c77dab
commit
f2d799d591
@@ -784,21 +784,36 @@ static void virtio_mem_fake_online(unsigned long pfn, unsigned long nr_pages)
|
|||||||
*/
|
*/
|
||||||
static int virtio_mem_fake_offline(unsigned long pfn, unsigned long nr_pages)
|
static int virtio_mem_fake_offline(unsigned long pfn, unsigned long nr_pages)
|
||||||
{
|
{
|
||||||
int rc;
|
const bool is_movable = zone_idx(page_zone(pfn_to_page(pfn))) ==
|
||||||
|
ZONE_MOVABLE;
|
||||||
|
int rc, retry_count;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: We want an alloc_contig_range() mode that tries to allocate
|
||||||
|
* harder (e.g., dealing with temporarily pinned pages, PCP), especially
|
||||||
|
* with ZONE_MOVABLE. So for now, retry a couple of times with
|
||||||
|
* ZONE_MOVABLE before giving up - because that zone is supposed to give
|
||||||
|
* some guarantees.
|
||||||
|
*/
|
||||||
|
for (retry_count = 0; retry_count < 5; retry_count++) {
|
||||||
rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
|
rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (rc == -ENOMEM)
|
if (rc == -ENOMEM)
|
||||||
/* whoops, out of memory */
|
/* whoops, out of memory */
|
||||||
return rc;
|
return rc;
|
||||||
if (rc)
|
else if (rc && !is_movable)
|
||||||
return -EBUSY;
|
break;
|
||||||
|
else if (rc)
|
||||||
|
continue;
|
||||||
|
|
||||||
virtio_mem_set_fake_offline(pfn, nr_pages, true);
|
virtio_mem_set_fake_offline(pfn, nr_pages, true);
|
||||||
adjust_managed_page_count(pfn_to_page(pfn), -nr_pages);
|
adjust_managed_page_count(pfn_to_page(pfn), -nr_pages);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle fake-offline pages when memory is going offline - such that the
|
* Handle fake-offline pages when memory is going offline - such that the
|
||||||
* pages can be skipped by mm-core when offlining.
|
* pages can be skipped by mm-core when offlining.
|
||||||
|
|||||||
Reference in New Issue
Block a user