Commit db7b3377 authored by David Hildenbrand's avatar David Hildenbrand Committed by Michael S. Tsirkin

virtio-mem: prioritize unplug from ZONE_MOVABLE in Big Block Mode

Let's handle unplug in Big Block Mode similar to Sub Block Mode --
prioritize memory blocks onlined to ZONE_MOVABLE.

We won't care further about big blocks with mixed zones, as it's
rather a corner case that won't matter in practice.
Signed-off-by: default avatarDavid Hildenbrand <david@redhat.com>
Link: https://lore.kernel.org/r/20210602185720.31821-8-david@redhat.comSigned-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent c6bc1422
...@@ -2121,6 +2121,29 @@ static bool virtio_mem_bbm_bb_is_offline(struct virtio_mem *vm, ...@@ -2121,6 +2121,29 @@ static bool virtio_mem_bbm_bb_is_offline(struct virtio_mem *vm,
return true; return true;
} }
/*
* Test if a big block is completely onlined to ZONE_MOVABLE (or offline).
*/
static bool virtio_mem_bbm_bb_is_movable(struct virtio_mem *vm,
unsigned long bb_id)
{
const unsigned long start_pfn = PFN_DOWN(virtio_mem_bb_id_to_phys(vm, bb_id));
const unsigned long nr_pages = PFN_DOWN(vm->bbm.bb_size);
struct page *page;
unsigned long pfn;
for (pfn = start_pfn; pfn < start_pfn + nr_pages;
pfn += PAGES_PER_SECTION) {
page = pfn_to_online_page(pfn);
if (!page)
continue;
if (page_zonenum(page) != ZONE_MOVABLE)
return false;
}
return true;
}
static int virtio_mem_bbm_unplug_request(struct virtio_mem *vm, uint64_t diff) static int virtio_mem_bbm_unplug_request(struct virtio_mem *vm, uint64_t diff)
{ {
uint64_t nb_bb = diff / vm->bbm.bb_size; uint64_t nb_bb = diff / vm->bbm.bb_size;
...@@ -2134,7 +2157,7 @@ static int virtio_mem_bbm_unplug_request(struct virtio_mem *vm, uint64_t diff) ...@@ -2134,7 +2157,7 @@ static int virtio_mem_bbm_unplug_request(struct virtio_mem *vm, uint64_t diff)
* Try to unplug big blocks. Similar to SBM, start with offline * Try to unplug big blocks. Similar to SBM, start with offline
* big blocks. * big blocks.
*/ */
for (i = 0; i < 2; i++) { for (i = 0; i < 3; i++) {
virtio_mem_bbm_for_each_bb_rev(vm, bb_id, VIRTIO_MEM_BBM_BB_ADDED) { virtio_mem_bbm_for_each_bb_rev(vm, bb_id, VIRTIO_MEM_BBM_BB_ADDED) {
cond_resched(); cond_resched();
...@@ -2144,6 +2167,8 @@ static int virtio_mem_bbm_unplug_request(struct virtio_mem *vm, uint64_t diff) ...@@ -2144,6 +2167,8 @@ static int virtio_mem_bbm_unplug_request(struct virtio_mem *vm, uint64_t diff)
*/ */
if (i == 0 && !virtio_mem_bbm_bb_is_offline(vm, bb_id)) if (i == 0 && !virtio_mem_bbm_bb_is_offline(vm, bb_id))
continue; continue;
if (i == 1 && !virtio_mem_bbm_bb_is_movable(vm, bb_id))
continue;
rc = virtio_mem_bbm_offline_remove_and_unplug_bb(vm, bb_id); rc = virtio_mem_bbm_offline_remove_and_unplug_bb(vm, bb_id);
if (rc == -EBUSY) if (rc == -EBUSY)
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment