Skip to content

Commit f55484f

Browse files
davidhildenbrandmstsirkin
authored andcommitted
virtio-mem: check if the config changed before fake offlining memory
If we repeatedly fail to fake offline memory to unplug it, we won't be sending any unplug requests to the device. However, we only check if the config changed when sending such (un)plug requests. We could end up trying for a long time to unplug memory, even though the config changed already and we're not supposed to unplug memory anymore. For example, the hypervisor might detect a low-memory situation while unplugging memory and decide to replug some memory. Continuing trying to unplug memory in that case can be problematic. So let's check on a more regular basis. Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20230713145551.2824980-5-david@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
1 parent a31648f commit f55484f

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

drivers/virtio/virtio_mem.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,7 +1189,8 @@ static void virtio_mem_fake_online(unsigned long pfn, unsigned long nr_pages)
11891189
* Try to allocate a range, marking pages fake-offline, effectively
11901190
* fake-offlining them.
11911191
*/
1192-
static int virtio_mem_fake_offline(unsigned long pfn, unsigned long nr_pages)
1192+
static int virtio_mem_fake_offline(struct virtio_mem *vm, unsigned long pfn,
1193+
unsigned long nr_pages)
11931194
{
11941195
const bool is_movable = is_zone_movable_page(pfn_to_page(pfn));
11951196
int rc, retry_count;
@@ -1202,6 +1203,14 @@ static int virtio_mem_fake_offline(unsigned long pfn, unsigned long nr_pages)
12021203
* some guarantees.
12031204
*/
12041205
for (retry_count = 0; retry_count < 5; retry_count++) {
1206+
/*
1207+
* If the config changed, stop immediately and go back to the
1208+
* main loop: avoid trying to keep unplugging if the device
1209+
* might have decided to not remove any more memory.
1210+
*/
1211+
if (atomic_read(&vm->config_changed))
1212+
return -EAGAIN;
1213+
12051214
rc = alloc_contig_range(pfn, pfn + nr_pages, MIGRATE_MOVABLE,
12061215
GFP_KERNEL);
12071216
if (rc == -ENOMEM)
@@ -1951,7 +1960,7 @@ static int virtio_mem_sbm_unplug_sb_online(struct virtio_mem *vm,
19511960
start_pfn = PFN_DOWN(virtio_mem_mb_id_to_phys(mb_id) +
19521961
sb_id * vm->sbm.sb_size);
19531962

1954-
rc = virtio_mem_fake_offline(start_pfn, nr_pages);
1963+
rc = virtio_mem_fake_offline(vm, start_pfn, nr_pages);
19551964
if (rc)
19561965
return rc;
19571966

@@ -2149,7 +2158,7 @@ static int virtio_mem_bbm_offline_remove_and_unplug_bb(struct virtio_mem *vm,
21492158
if (!page)
21502159
continue;
21512160

2152-
rc = virtio_mem_fake_offline(pfn, PAGES_PER_SECTION);
2161+
rc = virtio_mem_fake_offline(vm, pfn, PAGES_PER_SECTION);
21532162
if (rc) {
21542163
end_pfn = pfn;
21552164
goto rollback;

0 commit comments

Comments
 (0)