Skip to content

Commit c6bc142

Browse files
davidhildenbrandmstsirkin
authored andcommitted
virtio-mem: simplify high-level unplug handling in Big Block Mode
Let's simplify high-level big block selection when unplugging in Big Block Mode. Combine handling of offline and online blocks. We can get rid of virtio_mem_bbm_bb_is_offline() and simply use virtio_mem_bbm_offline_remove_and_unplug_bb(), as that already tolerates offline parts. We can race with concurrent onlining/offlining either way, so we don;t have to be super correct by failing if an offline big block we'd like to unplug just got (partially) onlined. Signed-off-by: David Hildenbrand <david@redhat.com> Link: https://lore.kernel.org/r/20210602185720.31821-7-david@redhat.com Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
1 parent c740bb9 commit c6bc142

1 file changed

Lines changed: 24 additions & 72 deletions

File tree

drivers/virtio/virtio_mem.c

Lines changed: 24 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -702,18 +702,6 @@ static int virtio_mem_sbm_remove_mb(struct virtio_mem *vm, unsigned long mb_id)
702702
return virtio_mem_remove_memory(vm, addr, size);
703703
}
704704

705-
/*
706-
* See virtio_mem_remove_memory(): Try to remove all Linux memory blocks covered
707-
* by the big block.
708-
*/
709-
static int virtio_mem_bbm_remove_bb(struct virtio_mem *vm, unsigned long bb_id)
710-
{
711-
const uint64_t addr = virtio_mem_bb_id_to_phys(vm, bb_id);
712-
const uint64_t size = vm->bbm.bb_size;
713-
714-
return virtio_mem_remove_memory(vm, addr, size);
715-
}
716-
717705
/*
718706
* Try offlining and removing memory from Linux.
719707
*
@@ -2114,35 +2102,6 @@ static int virtio_mem_bbm_offline_remove_and_unplug_bb(struct virtio_mem *vm,
21142102
return rc;
21152103
}
21162104

2117-
/*
2118-
* Try to remove a big block from Linux and unplug it. Will fail with
2119-
* -EBUSY if some memory is online.
2120-
*
2121-
* Will modify the state of the memory block.
2122-
*/
2123-
static int virtio_mem_bbm_remove_and_unplug_bb(struct virtio_mem *vm,
2124-
unsigned long bb_id)
2125-
{
2126-
int rc;
2127-
2128-
if (WARN_ON_ONCE(virtio_mem_bbm_get_bb_state(vm, bb_id) !=
2129-
VIRTIO_MEM_BBM_BB_ADDED))
2130-
return -EINVAL;
2131-
2132-
rc = virtio_mem_bbm_remove_bb(vm, bb_id);
2133-
if (rc)
2134-
return -EBUSY;
2135-
2136-
rc = virtio_mem_bbm_unplug_bb(vm, bb_id);
2137-
if (rc)
2138-
virtio_mem_bbm_set_bb_state(vm, bb_id,
2139-
VIRTIO_MEM_BBM_BB_PLUGGED);
2140-
else
2141-
virtio_mem_bbm_set_bb_state(vm, bb_id,
2142-
VIRTIO_MEM_BBM_BB_UNUSED);
2143-
return rc;
2144-
}
2145-
21462105
/*
21472106
* Test if a big block is completely offline.
21482107
*/
@@ -2166,42 +2125,35 @@ static int virtio_mem_bbm_unplug_request(struct virtio_mem *vm, uint64_t diff)
21662125
{
21672126
uint64_t nb_bb = diff / vm->bbm.bb_size;
21682127
uint64_t bb_id;
2169-
int rc;
2128+
int rc, i;
21702129

21712130
if (!nb_bb)
21722131
return 0;
21732132

2174-
/* Try to unplug completely offline big blocks first. */
2175-
virtio_mem_bbm_for_each_bb_rev(vm, bb_id, VIRTIO_MEM_BBM_BB_ADDED) {
2176-
cond_resched();
2177-
/*
2178-
* As we're holding no locks, this check is racy as memory
2179-
* can get onlined in the meantime - but we'll fail gracefully.
2180-
*/
2181-
if (!virtio_mem_bbm_bb_is_offline(vm, bb_id))
2182-
continue;
2183-
rc = virtio_mem_bbm_remove_and_unplug_bb(vm, bb_id);
2184-
if (rc == -EBUSY)
2185-
continue;
2186-
if (!rc)
2187-
nb_bb--;
2188-
if (rc || !nb_bb)
2189-
return rc;
2190-
}
2191-
2192-
if (!unplug_online)
2193-
return 0;
2133+
/*
2134+
* Try to unplug big blocks. Similar to SBM, start with offline
2135+
* big blocks.
2136+
*/
2137+
for (i = 0; i < 2; i++) {
2138+
virtio_mem_bbm_for_each_bb_rev(vm, bb_id, VIRTIO_MEM_BBM_BB_ADDED) {
2139+
cond_resched();
21942140

2195-
/* Try to unplug any big blocks. */
2196-
virtio_mem_bbm_for_each_bb_rev(vm, bb_id, VIRTIO_MEM_BBM_BB_ADDED) {
2197-
cond_resched();
2198-
rc = virtio_mem_bbm_offline_remove_and_unplug_bb(vm, bb_id);
2199-
if (rc == -EBUSY)
2200-
continue;
2201-
if (!rc)
2202-
nb_bb--;
2203-
if (rc || !nb_bb)
2204-
return rc;
2141+
/*
2142+
* As we're holding no locks, these checks are racy,
2143+
* but we don't care.
2144+
*/
2145+
if (i == 0 && !virtio_mem_bbm_bb_is_offline(vm, bb_id))
2146+
continue;
2147+
rc = virtio_mem_bbm_offline_remove_and_unplug_bb(vm, bb_id);
2148+
if (rc == -EBUSY)
2149+
continue;
2150+
if (!rc)
2151+
nb_bb--;
2152+
if (rc || !nb_bb)
2153+
return rc;
2154+
}
2155+
if (i == 0 && !unplug_online)
2156+
return 0;
22052157
}
22062158

22072159
return nb_bb ? -EBUSY : 0;

0 commit comments

Comments
 (0)