Merge remote-tracking branch 'remotes/vsementsov/tags/pull-jobs-2021-06-25' into staging

block: Make block-copy API thread-safe

# gpg: Signature made Fri 25 Jun 2021 13:40:24 BST
# gpg:                using RSA key 8B9C26CDB2FD147C880E86A1561F24C1F19F79FB
# gpg: Good signature from "Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 8B9C 26CD B2FD 147C 880E  86A1 561F 24C1 F19F 79FB

* remotes/vsementsov/tags/pull-jobs-2021-06-25:
  block-copy: atomic .cancelled and .finished fields in BlockCopyCallState
  block-copy: add CoMutex lock
  block-copy: move progress_set_remaining in block_copy_task_end
  block-copy: streamline choice of copy_range vs. read/write
  block-copy: small refactor in block_copy_task_entry and block_copy_common
  co-shared-resource: protect with a mutex
  progressmeter: protect with a mutex
  blockjob: let ratelimit handle a speed of 0
  block-copy: let ratelimit handle a speed of 0
  ratelimit: treat zero speed as unlimited

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell
2021-06-28 17:08:34 +01:00
12 changed files with 405 additions and 210 deletions

View File

@ -26,15 +26,13 @@
#ifndef QEMU_CO_SHARED_RESOURCE_H
#define QEMU_CO_SHARED_RESOURCE_H
/* Accesses to co-shared-resource API are thread-safe */
typedef struct SharedResource SharedResource;
/*
* Create SharedResource structure
*
* @total: total amount of some resource to be shared between clients
*
* Note: this API is not thread-safe.
*/
SharedResource *shres_create(uint64_t total);

View File

@ -27,6 +27,8 @@
#ifndef QEMU_PROGRESS_METER_H
#define QEMU_PROGRESS_METER_H
#include "qemu/lockable.h"
typedef struct ProgressMeter {
/**
* Current progress. The unit is arbitrary as long as the ratio between
@ -37,22 +39,24 @@ typedef struct ProgressMeter {
/** Estimated current value at the completion of the process */
uint64_t total;
QemuMutex lock; /* protects concurrent access to above fields */
} ProgressMeter;
static inline void progress_work_done(ProgressMeter *pm, uint64_t done)
{
pm->current += done;
}
void progress_init(ProgressMeter *pm);
void progress_destroy(ProgressMeter *pm);
static inline void progress_set_remaining(ProgressMeter *pm, uint64_t remaining)
{
pm->total = pm->current + remaining;
}
/* Get a snapshot of internal current and total values */
void progress_get_snapshot(ProgressMeter *pm, uint64_t *current,
uint64_t *total);
static inline void progress_increase_remaining(ProgressMeter *pm,
uint64_t delta)
{
pm->total += delta;
}
/* Increases the amount of work done so far by @done */
void progress_work_done(ProgressMeter *pm, uint64_t done);
/* Sets how much work has to be done to complete to @remaining */
void progress_set_remaining(ProgressMeter *pm, uint64_t remaining);
/* Increases the total work to do by @delta */
void progress_increase_remaining(ProgressMeter *pm, uint64_t delta);
#endif /* QEMU_PROGRESS_METER_H */

View File

@ -43,7 +43,11 @@ static inline int64_t ratelimit_calculate_delay(RateLimit *limit, uint64_t n)
double delay_slices;
QEMU_LOCK_GUARD(&limit->lock);
assert(limit->slice_quota && limit->slice_ns);
if (!limit->slice_quota) {
/* Throttling disabled. */
return 0;
}
assert(limit->slice_ns);
if (limit->slice_end_time < now) {
/* Previous, possibly extended, time slice finished; reset the
@ -83,7 +87,11 @@ static inline void ratelimit_set_speed(RateLimit *limit, uint64_t speed,
{
QEMU_LOCK_GUARD(&limit->lock);
limit->slice_ns = slice_ns;
limit->slice_quota = MAX(((double)speed * slice_ns) / 1000000000ULL, 1);
if (speed == 0) {
limit->slice_quota = 0;
} else {
limit->slice_quota = MAX(((double)speed * slice_ns) / 1000000000ULL, 1);
}
}
#endif