|
|
26ba25 |
From bd3d631a2e5d982559f99bac55718813dde1b783 Mon Sep 17 00:00:00 2001
|
|
|
26ba25 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
26ba25 |
Date: Tue, 26 Jun 2018 09:47:54 +0200
|
|
|
26ba25 |
Subject: [PATCH 086/268] blockjob: Implement block_job_set_speed() centrally
|
|
|
26ba25 |
|
|
|
26ba25 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
26ba25 |
Message-id: <20180626094856.6924-12-kwolf@redhat.com>
|
|
|
26ba25 |
Patchwork-id: 81102
|
|
|
26ba25 |
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH v2 11/73] blockjob: Implement block_job_set_speed() centrally
|
|
|
26ba25 |
Bugzilla: 1513543
|
|
|
26ba25 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
26ba25 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
26ba25 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
26ba25 |
|
|
|
26ba25 |
All block job drivers support .set_speed and all of them duplicate the
|
|
|
26ba25 |
same code to implement it. Move that code to blockjob.c and remove the
|
|
|
26ba25 |
now useless callback.
|
|
|
26ba25 |
|
|
|
26ba25 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
26ba25 |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
26ba25 |
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
|
|
26ba25 |
Reviewed-by: John Snow <jsnow@redhat.com>
|
|
|
26ba25 |
(cherry picked from commit 18bb69287ea522ab696e1bea818b93e5eaa85745)
|
|
|
26ba25 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
26ba25 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
26ba25 |
---
|
|
|
26ba25 |
block/backup.c | 13 -------------
|
|
|
26ba25 |
block/commit.c | 14 --------------
|
|
|
26ba25 |
block/mirror.c | 26 ++++++--------------------
|
|
|
26ba25 |
block/stream.c | 14 --------------
|
|
|
26ba25 |
blockjob.c | 12 ++++--------
|
|
|
26ba25 |
include/block/blockjob.h | 2 ++
|
|
|
26ba25 |
include/block/blockjob_int.h | 3 ---
|
|
|
26ba25 |
7 files changed, 12 insertions(+), 72 deletions(-)
|
|
|
26ba25 |
|
|
|
26ba25 |
diff --git a/block/backup.c b/block/backup.c
|
|
|
26ba25 |
index 7585c43..8468fd9 100644
|
|
|
26ba25 |
--- a/block/backup.c
|
|
|
26ba25 |
+++ b/block/backup.c
|
|
|
26ba25 |
@@ -27,7 +27,6 @@
|
|
|
26ba25 |
#include "qemu/error-report.h"
|
|
|
26ba25 |
|
|
|
26ba25 |
#define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16)
|
|
|
26ba25 |
-#define SLICE_TIME 100000000ULL /* ns */
|
|
|
26ba25 |
|
|
|
26ba25 |
typedef struct BackupBlockJob {
|
|
|
26ba25 |
BlockJob common;
|
|
|
26ba25 |
@@ -190,17 +189,6 @@ static int coroutine_fn backup_before_write_notify(
|
|
|
26ba25 |
return backup_do_cow(job, req->offset, req->bytes, NULL, true);
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
-static void backup_set_speed(BlockJob *job, int64_t speed, Error **errp)
|
|
|
26ba25 |
-{
|
|
|
26ba25 |
- BackupBlockJob *s = container_of(job, BackupBlockJob, common);
|
|
|
26ba25 |
-
|
|
|
26ba25 |
- if (speed < 0) {
|
|
|
26ba25 |
- error_setg(errp, QERR_INVALID_PARAMETER, "speed");
|
|
|
26ba25 |
- return;
|
|
|
26ba25 |
- }
|
|
|
26ba25 |
- ratelimit_set_speed(&s->common.limit, speed, SLICE_TIME);
|
|
|
26ba25 |
-}
|
|
|
26ba25 |
-
|
|
|
26ba25 |
static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
BdrvDirtyBitmap *bm;
|
|
|
26ba25 |
@@ -540,7 +528,6 @@ static const BlockJobDriver backup_job_driver = {
|
|
|
26ba25 |
.instance_size = sizeof(BackupBlockJob),
|
|
|
26ba25 |
.job_type = BLOCK_JOB_TYPE_BACKUP,
|
|
|
26ba25 |
.start = backup_run,
|
|
|
26ba25 |
- .set_speed = backup_set_speed,
|
|
|
26ba25 |
.commit = backup_commit,
|
|
|
26ba25 |
.abort = backup_abort,
|
|
|
26ba25 |
.clean = backup_clean,
|
|
|
26ba25 |
diff --git a/block/commit.c b/block/commit.c
|
|
|
26ba25 |
index beec5d0..46cbeae 100644
|
|
|
26ba25 |
--- a/block/commit.c
|
|
|
26ba25 |
+++ b/block/commit.c
|
|
|
26ba25 |
@@ -31,8 +31,6 @@ enum {
|
|
|
26ba25 |
COMMIT_BUFFER_SIZE = 512 * 1024, /* in bytes */
|
|
|
26ba25 |
};
|
|
|
26ba25 |
|
|
|
26ba25 |
-#define SLICE_TIME 100000000ULL /* ns */
|
|
|
26ba25 |
-
|
|
|
26ba25 |
typedef struct CommitBlockJob {
|
|
|
26ba25 |
BlockJob common;
|
|
|
26ba25 |
BlockDriverState *commit_top_bs;
|
|
|
26ba25 |
@@ -216,21 +214,9 @@ out:
|
|
|
26ba25 |
block_job_defer_to_main_loop(&s->common, commit_complete, data);
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
-static void commit_set_speed(BlockJob *job, int64_t speed, Error **errp)
|
|
|
26ba25 |
-{
|
|
|
26ba25 |
- CommitBlockJob *s = container_of(job, CommitBlockJob, common);
|
|
|
26ba25 |
-
|
|
|
26ba25 |
- if (speed < 0) {
|
|
|
26ba25 |
- error_setg(errp, QERR_INVALID_PARAMETER, "speed");
|
|
|
26ba25 |
- return;
|
|
|
26ba25 |
- }
|
|
|
26ba25 |
- ratelimit_set_speed(&s->common.limit, speed, SLICE_TIME);
|
|
|
26ba25 |
-}
|
|
|
26ba25 |
-
|
|
|
26ba25 |
static const BlockJobDriver commit_job_driver = {
|
|
|
26ba25 |
.instance_size = sizeof(CommitBlockJob),
|
|
|
26ba25 |
.job_type = BLOCK_JOB_TYPE_COMMIT,
|
|
|
26ba25 |
- .set_speed = commit_set_speed,
|
|
|
26ba25 |
.start = commit_run,
|
|
|
26ba25 |
};
|
|
|
26ba25 |
|
|
|
26ba25 |
diff --git a/block/mirror.c b/block/mirror.c
|
|
|
26ba25 |
index a515ec1..d5e0ff2 100644
|
|
|
26ba25 |
--- a/block/mirror.c
|
|
|
26ba25 |
+++ b/block/mirror.c
|
|
|
26ba25 |
@@ -22,7 +22,6 @@
|
|
|
26ba25 |
#include "qemu/ratelimit.h"
|
|
|
26ba25 |
#include "qemu/bitmap.h"
|
|
|
26ba25 |
|
|
|
26ba25 |
-#define SLICE_TIME 100000000ULL /* ns */
|
|
|
26ba25 |
#define MAX_IN_FLIGHT 16
|
|
|
26ba25 |
#define MAX_IO_BYTES (1 << 20) /* 1 Mb */
|
|
|
26ba25 |
#define DEFAULT_MIRROR_BUF_SIZE (MAX_IN_FLIGHT * MAX_IO_BYTES)
|
|
|
26ba25 |
@@ -596,7 +595,7 @@ static void mirror_throttle(MirrorBlockJob *s)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
|
|
26ba25 |
|
|
|
26ba25 |
- if (now - s->last_pause_ns > SLICE_TIME) {
|
|
|
26ba25 |
+ if (now - s->last_pause_ns > BLOCK_JOB_SLICE_TIME) {
|
|
|
26ba25 |
s->last_pause_ns = now;
|
|
|
26ba25 |
block_job_sleep_ns(&s->common, 0);
|
|
|
26ba25 |
} else {
|
|
|
26ba25 |
@@ -799,11 +798,10 @@ static void coroutine_fn mirror_run(void *opaque)
|
|
|
26ba25 |
|
|
|
26ba25 |
/* Note that even when no rate limit is applied we need to yield
|
|
|
26ba25 |
* periodically with no pending I/O so that bdrv_drain_all() returns.
|
|
|
26ba25 |
- * We do so every SLICE_TIME nanoseconds, or when there is an error,
|
|
|
26ba25 |
- * or when the source is clean, whichever comes first.
|
|
|
26ba25 |
- */
|
|
|
26ba25 |
+ * We do so every BLKOCK_JOB_SLICE_TIME nanoseconds, or when there is
|
|
|
26ba25 |
+ * an error, or when the source is clean, whichever comes first. */
|
|
|
26ba25 |
delta = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - s->last_pause_ns;
|
|
|
26ba25 |
- if (delta < SLICE_TIME &&
|
|
|
26ba25 |
+ if (delta < BLOCK_JOB_SLICE_TIME &&
|
|
|
26ba25 |
s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
|
|
|
26ba25 |
if (s->in_flight >= MAX_IN_FLIGHT || s->buf_free_count == 0 ||
|
|
|
26ba25 |
(cnt == 0 && s->in_flight > 0)) {
|
|
|
26ba25 |
@@ -869,7 +867,8 @@ static void coroutine_fn mirror_run(void *opaque)
|
|
|
26ba25 |
ret = 0;
|
|
|
26ba25 |
|
|
|
26ba25 |
if (s->synced && !should_complete) {
|
|
|
26ba25 |
- delay_ns = (s->in_flight == 0 && cnt == 0 ? SLICE_TIME : 0);
|
|
|
26ba25 |
+ delay_ns = (s->in_flight == 0 &&
|
|
|
26ba25 |
+ cnt == 0 ? BLOCK_JOB_SLICE_TIME : 0);
|
|
|
26ba25 |
}
|
|
|
26ba25 |
trace_mirror_before_sleep(s, cnt, s->synced, delay_ns);
|
|
|
26ba25 |
block_job_sleep_ns(&s->common, delay_ns);
|
|
|
26ba25 |
@@ -908,17 +907,6 @@ immediate_exit:
|
|
|
26ba25 |
block_job_defer_to_main_loop(&s->common, mirror_exit, data);
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
-static void mirror_set_speed(BlockJob *job, int64_t speed, Error **errp)
|
|
|
26ba25 |
-{
|
|
|
26ba25 |
- MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
|
|
|
26ba25 |
-
|
|
|
26ba25 |
- if (speed < 0) {
|
|
|
26ba25 |
- error_setg(errp, QERR_INVALID_PARAMETER, "speed");
|
|
|
26ba25 |
- return;
|
|
|
26ba25 |
- }
|
|
|
26ba25 |
- ratelimit_set_speed(&s->common.limit, speed, SLICE_TIME);
|
|
|
26ba25 |
-}
|
|
|
26ba25 |
-
|
|
|
26ba25 |
static void mirror_complete(BlockJob *job, Error **errp)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
|
|
|
26ba25 |
@@ -1003,7 +991,6 @@ static void mirror_drain(BlockJob *job)
|
|
|
26ba25 |
static const BlockJobDriver mirror_job_driver = {
|
|
|
26ba25 |
.instance_size = sizeof(MirrorBlockJob),
|
|
|
26ba25 |
.job_type = BLOCK_JOB_TYPE_MIRROR,
|
|
|
26ba25 |
- .set_speed = mirror_set_speed,
|
|
|
26ba25 |
.start = mirror_run,
|
|
|
26ba25 |
.complete = mirror_complete,
|
|
|
26ba25 |
.pause = mirror_pause,
|
|
|
26ba25 |
@@ -1014,7 +1001,6 @@ static const BlockJobDriver mirror_job_driver = {
|
|
|
26ba25 |
static const BlockJobDriver commit_active_job_driver = {
|
|
|
26ba25 |
.instance_size = sizeof(MirrorBlockJob),
|
|
|
26ba25 |
.job_type = BLOCK_JOB_TYPE_COMMIT,
|
|
|
26ba25 |
- .set_speed = mirror_set_speed,
|
|
|
26ba25 |
.start = mirror_run,
|
|
|
26ba25 |
.complete = mirror_complete,
|
|
|
26ba25 |
.pause = mirror_pause,
|
|
|
26ba25 |
diff --git a/block/stream.c b/block/stream.c
|
|
|
26ba25 |
index a1d4768..797d7c4 100644
|
|
|
26ba25 |
--- a/block/stream.c
|
|
|
26ba25 |
+++ b/block/stream.c
|
|
|
26ba25 |
@@ -29,8 +29,6 @@ enum {
|
|
|
26ba25 |
STREAM_BUFFER_SIZE = 512 * 1024, /* in bytes */
|
|
|
26ba25 |
};
|
|
|
26ba25 |
|
|
|
26ba25 |
-#define SLICE_TIME 100000000ULL /* ns */
|
|
|
26ba25 |
-
|
|
|
26ba25 |
typedef struct StreamBlockJob {
|
|
|
26ba25 |
BlockJob common;
|
|
|
26ba25 |
BlockDriverState *base;
|
|
|
26ba25 |
@@ -210,21 +208,9 @@ out:
|
|
|
26ba25 |
block_job_defer_to_main_loop(&s->common, stream_complete, data);
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
-static void stream_set_speed(BlockJob *job, int64_t speed, Error **errp)
|
|
|
26ba25 |
-{
|
|
|
26ba25 |
- StreamBlockJob *s = container_of(job, StreamBlockJob, common);
|
|
|
26ba25 |
-
|
|
|
26ba25 |
- if (speed < 0) {
|
|
|
26ba25 |
- error_setg(errp, QERR_INVALID_PARAMETER, "speed");
|
|
|
26ba25 |
- return;
|
|
|
26ba25 |
- }
|
|
|
26ba25 |
- ratelimit_set_speed(&s->common.limit, speed, SLICE_TIME);
|
|
|
26ba25 |
-}
|
|
|
26ba25 |
-
|
|
|
26ba25 |
static const BlockJobDriver stream_job_driver = {
|
|
|
26ba25 |
.instance_size = sizeof(StreamBlockJob),
|
|
|
26ba25 |
.job_type = BLOCK_JOB_TYPE_STREAM,
|
|
|
26ba25 |
- .set_speed = stream_set_speed,
|
|
|
26ba25 |
.start = stream_run,
|
|
|
26ba25 |
};
|
|
|
26ba25 |
|
|
|
26ba25 |
diff --git a/blockjob.c b/blockjob.c
|
|
|
26ba25 |
index d0a2ac5..0f7214c 100644
|
|
|
26ba25 |
--- a/blockjob.c
|
|
|
26ba25 |
+++ b/blockjob.c
|
|
|
26ba25 |
@@ -667,22 +667,18 @@ static void block_job_completed_txn_success(BlockJob *job)
|
|
|
26ba25 |
|
|
|
26ba25 |
void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
|
|
|
26ba25 |
{
|
|
|
26ba25 |
- Error *local_err = NULL;
|
|
|
26ba25 |
int64_t old_speed = job->speed;
|
|
|
26ba25 |
|
|
|
26ba25 |
- if (!job->driver->set_speed) {
|
|
|
26ba25 |
- error_setg(errp, QERR_UNSUPPORTED);
|
|
|
26ba25 |
- return;
|
|
|
26ba25 |
- }
|
|
|
26ba25 |
if (block_job_apply_verb(job, BLOCK_JOB_VERB_SET_SPEED, errp)) {
|
|
|
26ba25 |
return;
|
|
|
26ba25 |
}
|
|
|
26ba25 |
- job->driver->set_speed(job, speed, &local_err);
|
|
|
26ba25 |
- if (local_err) {
|
|
|
26ba25 |
- error_propagate(errp, local_err);
|
|
|
26ba25 |
+ if (speed < 0) {
|
|
|
26ba25 |
+ error_setg(errp, QERR_INVALID_PARAMETER, "speed");
|
|
|
26ba25 |
return;
|
|
|
26ba25 |
}
|
|
|
26ba25 |
|
|
|
26ba25 |
+ ratelimit_set_speed(&job->limit, speed, BLOCK_JOB_SLICE_TIME);
|
|
|
26ba25 |
+
|
|
|
26ba25 |
job->speed = speed;
|
|
|
26ba25 |
if (speed && speed <= old_speed) {
|
|
|
26ba25 |
return;
|
|
|
26ba25 |
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
|
|
|
26ba25 |
index 22bf418..82f52f4 100644
|
|
|
26ba25 |
--- a/include/block/blockjob.h
|
|
|
26ba25 |
+++ b/include/block/blockjob.h
|
|
|
26ba25 |
@@ -29,6 +29,8 @@
|
|
|
26ba25 |
#include "block/block.h"
|
|
|
26ba25 |
#include "qemu/ratelimit.h"
|
|
|
26ba25 |
|
|
|
26ba25 |
+#define BLOCK_JOB_SLICE_TIME 100000000ULL /* ns */
|
|
|
26ba25 |
+
|
|
|
26ba25 |
typedef struct BlockJobDriver BlockJobDriver;
|
|
|
26ba25 |
typedef struct BlockJobTxn BlockJobTxn;
|
|
|
26ba25 |
|
|
|
26ba25 |
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
|
|
|
26ba25 |
index d5a515d..ad510d5 100644
|
|
|
26ba25 |
--- a/include/block/blockjob_int.h
|
|
|
26ba25 |
+++ b/include/block/blockjob_int.h
|
|
|
26ba25 |
@@ -41,9 +41,6 @@ struct BlockJobDriver {
|
|
|
26ba25 |
/** String describing the operation, part of query-block-jobs QMP API */
|
|
|
26ba25 |
BlockJobType job_type;
|
|
|
26ba25 |
|
|
|
26ba25 |
- /** Optional callback for job types that support setting a speed limit */
|
|
|
26ba25 |
- void (*set_speed)(BlockJob *job, int64_t speed, Error **errp);
|
|
|
26ba25 |
-
|
|
|
26ba25 |
/** Mandatory: Entrypoint for the Coroutine. */
|
|
|
26ba25 |
CoroutineEntry *start;
|
|
|
26ba25 |
|
|
|
26ba25 |
--
|
|
|
26ba25 |
1.8.3.1
|
|
|
26ba25 |
|