mirror of https://github.com/xemu-project/xemu.git
softmmu/physmem: Don't use atomic operations in ram_block_discard_(disable|require)
We have users in migration context that don't hold the BQL (when finishing migration). To prepare for further changes, use a dedicated mutex instead of atomic operations. Keep using qatomic_read ("READ_ONCE") for the functions that only extract the current state (e.g., used by virtio-balloon), locking isn't necessary. While at it, split up the counter into two variables to make it easier to understand. Suggested-by: Peter Xu <peterx@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Pankaj Gupta <pankaj.gupta@cloud.ionos.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Alex Williamson <alex.williamson@redhat.com> Cc: Dr. David Alan Gilbert <dgilbert@redhat.com> Cc: Igor Mammedov <imammedo@redhat.com> Cc: Pankaj Gupta <pankaj.gupta.linux@gmail.com> Cc: Peter Xu <peterx@redhat.com> Cc: Auger Eric <eric.auger@redhat.com> Cc: Wei Yang <richard.weiyang@linux.alibaba.com> Cc: teawater <teawaterz@linux.alibaba.com> Cc: Marek Kedzierski <mkedzier@redhat.com> Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20210413095531.25603-11-david@redhat.com> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
parent
0fd7616e0f
commit
98da491dff
|
@ -3684,56 +3684,64 @@ void mtree_print_dispatch(AddressSpaceDispatch *d, MemoryRegion *root)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static unsigned int ram_block_discard_required_cnt;
|
||||||
* If positive, discarding RAM is disabled. If negative, discarding RAM is
|
static unsigned int ram_block_discard_disabled_cnt;
|
||||||
* required to work and cannot be disabled.
|
static QemuMutex ram_block_discard_disable_mutex;
|
||||||
*/
|
|
||||||
static int ram_block_discard_disabled;
|
static void ram_block_discard_disable_mutex_lock(void)
|
||||||
|
{
|
||||||
|
static gsize initialized;
|
||||||
|
|
||||||
|
if (g_once_init_enter(&initialized)) {
|
||||||
|
qemu_mutex_init(&ram_block_discard_disable_mutex);
|
||||||
|
g_once_init_leave(&initialized, 1);
|
||||||
|
}
|
||||||
|
qemu_mutex_lock(&ram_block_discard_disable_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ram_block_discard_disable_mutex_unlock(void)
|
||||||
|
{
|
||||||
|
qemu_mutex_unlock(&ram_block_discard_disable_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
int ram_block_discard_disable(bool state)
|
int ram_block_discard_disable(bool state)
|
||||||
{
|
{
|
||||||
int old;
|
int ret = 0;
|
||||||
|
|
||||||
|
ram_block_discard_disable_mutex_lock();
|
||||||
if (!state) {
|
if (!state) {
|
||||||
qatomic_dec(&ram_block_discard_disabled);
|
ram_block_discard_disabled_cnt--;
|
||||||
return 0;
|
} else if (!ram_block_discard_required_cnt) {
|
||||||
|
ram_block_discard_disabled_cnt++;
|
||||||
|
} else {
|
||||||
|
ret = -EBUSY;
|
||||||
}
|
}
|
||||||
|
ram_block_discard_disable_mutex_unlock();
|
||||||
do {
|
return ret;
|
||||||
old = qatomic_read(&ram_block_discard_disabled);
|
|
||||||
if (old < 0) {
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
} while (qatomic_cmpxchg(&ram_block_discard_disabled,
|
|
||||||
old, old + 1) != old);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ram_block_discard_require(bool state)
|
int ram_block_discard_require(bool state)
|
||||||
{
|
{
|
||||||
int old;
|
int ret = 0;
|
||||||
|
|
||||||
|
ram_block_discard_disable_mutex_lock();
|
||||||
if (!state) {
|
if (!state) {
|
||||||
qatomic_inc(&ram_block_discard_disabled);
|
ram_block_discard_required_cnt--;
|
||||||
return 0;
|
} else if (!ram_block_discard_disabled_cnt) {
|
||||||
|
ram_block_discard_required_cnt++;
|
||||||
|
} else {
|
||||||
|
ret = -EBUSY;
|
||||||
}
|
}
|
||||||
|
ram_block_discard_disable_mutex_unlock();
|
||||||
do {
|
return ret;
|
||||||
old = qatomic_read(&ram_block_discard_disabled);
|
|
||||||
if (old > 0) {
|
|
||||||
return -EBUSY;
|
|
||||||
}
|
|
||||||
} while (qatomic_cmpxchg(&ram_block_discard_disabled,
|
|
||||||
old, old - 1) != old);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ram_block_discard_is_disabled(void)
|
bool ram_block_discard_is_disabled(void)
|
||||||
{
|
{
|
||||||
return qatomic_read(&ram_block_discard_disabled) > 0;
|
return qatomic_read(&ram_block_discard_disabled_cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ram_block_discard_is_required(void)
|
bool ram_block_discard_is_required(void)
|
||||||
{
|
{
|
||||||
return qatomic_read(&ram_block_discard_disabled) < 0;
|
return qatomic_read(&ram_block_discard_required_cnt);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue