aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/block/block.h1
-rw-r--r--include/block/block_int.h25
-rw-r--r--include/block/throttle-groups.h52
-rw-r--r--include/qemu/iov.h6
-rw-r--r--include/qemu/throttle-options.h60
-rw-r--r--include/qemu/throttle.h3
-rw-r--r--include/sysemu/block-backend.h20
7 files changed, 115 insertions, 52 deletions
diff --git a/include/block/block.h b/include/block/block.h
index ab80195..2ad1877 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -441,7 +441,6 @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
bool bdrv_is_sg(BlockDriverState *bs);
bool bdrv_is_inserted(BlockDriverState *bs);
-int bdrv_media_changed(BlockDriverState *bs);
void bdrv_lock_medium(BlockDriverState *bs, bool locked);
void bdrv_eject(BlockDriverState *bs, bool eject_flag);
const char *bdrv_get_format_name(BlockDriverState *bs);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 7816b43..ba4c383 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -87,7 +87,11 @@ struct BlockDriver {
const char *format_name;
int instance_size;
- /* set to true if the BlockDriver is a block filter */
+ /* set to true if the BlockDriver is a block filter. Block filters pass
+ * certain callbacks that refer to data (see block.c) to their bs->file if
+ * the driver doesn't implement them. Drivers that do not wish to forward
+ * must implement them and return -ENOTSUP.
+ */
bool is_filter;
/* for snapshots block filter like Quorum can implement the
* following recursive callback.
@@ -275,7 +279,6 @@ struct BlockDriver {
/* removable device specific */
bool (*bdrv_is_inserted)(BlockDriverState *bs);
- int (*bdrv_media_changed)(BlockDriverState *bs);
void (*bdrv_eject)(BlockDriverState *bs, bool eject_flag);
void (*bdrv_lock_medium)(BlockDriverState *bs, bool locked);
@@ -992,6 +995,24 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
uint64_t perm, uint64_t shared,
uint64_t *nperm, uint64_t *nshared);
+/*
+ * Default implementation for drivers to pass bdrv_co_get_block_status() to
+ * their file.
+ */
+int64_t coroutine_fn bdrv_co_get_block_status_from_file(BlockDriverState *bs,
+ int64_t sector_num,
+ int nb_sectors,
+ int *pnum,
+ BlockDriverState **file);
+/*
+ * Default implementation for drivers to pass bdrv_co_get_block_status() to
+ * their backing file.
+ */
+int64_t coroutine_fn bdrv_co_get_block_status_from_backing(BlockDriverState *bs,
+ int64_t sector_num,
+ int nb_sectors,
+ int *pnum,
+ BlockDriverState **file);
const char *bdrv_get_parent_name(const BlockDriverState *bs);
void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp);
bool blk_dev_has_removable_media(BlockBackend *blk);
diff --git a/include/block/throttle-groups.h b/include/block/throttle-groups.h
index d983d34..e2fd051 100644
--- a/include/block/throttle-groups.h
+++ b/include/block/throttle-groups.h
@@ -28,20 +28,58 @@
#include "qemu/throttle.h"
#include "block/block_int.h"
-const char *throttle_group_get_name(BlockBackend *blk);
+/* The ThrottleGroupMember structure indicates membership in a ThrottleGroup
+ * and holds related data.
+ */
+
+typedef struct ThrottleGroupMember {
+ AioContext *aio_context;
+ /* throttled_reqs_lock protects the CoQueues for throttled requests. */
+ CoMutex throttled_reqs_lock;
+ CoQueue throttled_reqs[2];
+
+ /* Nonzero if the I/O limits are currently being ignored; generally
+ * it is zero. Accessed with atomic operations.
+ */
+ unsigned int io_limits_disabled;
+
+ /* The following fields are protected by the ThrottleGroup lock.
+ * See the ThrottleGroup documentation for details.
+ * throttle_state tells us if I/O limits are configured. */
+ ThrottleState *throttle_state;
+ ThrottleTimers throttle_timers;
+ unsigned pending_reqs[2];
+ QLIST_ENTRY(ThrottleGroupMember) round_robin;
+
+} ThrottleGroupMember;
+
+#define TYPE_THROTTLE_GROUP "throttle-group"
+#define THROTTLE_GROUP(obj) OBJECT_CHECK(ThrottleGroup, (obj), TYPE_THROTTLE_GROUP)
+
+const char *throttle_group_get_name(ThrottleGroupMember *tgm);
ThrottleState *throttle_group_incref(const char *name);
void throttle_group_unref(ThrottleState *ts);
-void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg);
-void throttle_group_get_config(BlockBackend *blk, ThrottleConfig *cfg);
+void throttle_group_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
+void throttle_group_get_config(ThrottleGroupMember *tgm, ThrottleConfig *cfg);
-void throttle_group_register_blk(BlockBackend *blk, const char *groupname);
-void throttle_group_unregister_blk(BlockBackend *blk);
-void throttle_group_restart_blk(BlockBackend *blk);
+void throttle_group_register_tgm(ThrottleGroupMember *tgm,
+ const char *groupname,
+ AioContext *ctx);
+void throttle_group_unregister_tgm(ThrottleGroupMember *tgm);
+void throttle_group_restart_tgm(ThrottleGroupMember *tgm);
-void coroutine_fn throttle_group_co_io_limits_intercept(BlockBackend *blk,
+void coroutine_fn throttle_group_co_io_limits_intercept(ThrottleGroupMember *tgm,
unsigned int bytes,
bool is_write);
+void throttle_group_attach_aio_context(ThrottleGroupMember *tgm,
+ AioContext *new_context);
+void throttle_group_detach_aio_context(ThrottleGroupMember *tgm);
+/*
+ * throttle_group_exists() must be called under the global
+ * mutex.
+ */
+bool throttle_group_exists(const char *name);
#endif
diff --git a/include/qemu/iov.h b/include/qemu/iov.h
index bd9fd55..72d4c55 100644
--- a/include/qemu/iov.h
+++ b/include/qemu/iov.h
@@ -31,11 +31,6 @@ size_t iov_size(const struct iovec *iov, const unsigned int iov_cnt);
* Number of bytes actually copied will be returned, which is
* min(bytes, iov_size(iov)-offset)
* `Offset' must point to the inside of iovec.
- * It is okay to use very large value for `bytes' since we're
- * limited by the size of the iovec anyway, provided that the
- * buffer pointed to by buf has enough space. One possible
- * such "large" value is -1 (sinice size_t is unsigned),
- * so specifying `-1' as `bytes' means 'up to the end of iovec'.
*/
size_t iov_from_buf_full(const struct iovec *iov, unsigned int iov_cnt,
size_t offset, const void *buf, size_t bytes);
@@ -76,7 +71,6 @@ iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt,
* up to the end of it, will be filled with the specified value.
* Function return actual number of bytes processed, which is
* min(size, iov_size(iov) - offset).
- * Again, it is okay to use large value for `bytes' to mean "up to the end".
*/
size_t iov_memset(const struct iovec *iov, const unsigned int iov_cnt,
size_t offset, int fillc, size_t bytes);
diff --git a/include/qemu/throttle-options.h b/include/qemu/throttle-options.h
index 3133d1c..3528a8f 100644
--- a/include/qemu/throttle-options.h
+++ b/include/qemu/throttle-options.h
@@ -10,81 +10,103 @@
#ifndef THROTTLE_OPTIONS_H
#define THROTTLE_OPTIONS_H
+#define QEMU_OPT_IOPS_TOTAL "iops-total"
+#define QEMU_OPT_IOPS_TOTAL_MAX "iops-total-max"
+#define QEMU_OPT_IOPS_TOTAL_MAX_LENGTH "iops-total-max-length"
+#define QEMU_OPT_IOPS_READ "iops-read"
+#define QEMU_OPT_IOPS_READ_MAX "iops-read-max"
+#define QEMU_OPT_IOPS_READ_MAX_LENGTH "iops-read-max-length"
+#define QEMU_OPT_IOPS_WRITE "iops-write"
+#define QEMU_OPT_IOPS_WRITE_MAX "iops-write-max"
+#define QEMU_OPT_IOPS_WRITE_MAX_LENGTH "iops-write-max-length"
+#define QEMU_OPT_BPS_TOTAL "bps-total"
+#define QEMU_OPT_BPS_TOTAL_MAX "bps-total-max"
+#define QEMU_OPT_BPS_TOTAL_MAX_LENGTH "bps-total-max-length"
+#define QEMU_OPT_BPS_READ "bps-read"
+#define QEMU_OPT_BPS_READ_MAX "bps-read-max"
+#define QEMU_OPT_BPS_READ_MAX_LENGTH "bps-read-max-length"
+#define QEMU_OPT_BPS_WRITE "bps-write"
+#define QEMU_OPT_BPS_WRITE_MAX "bps-write-max"
+#define QEMU_OPT_BPS_WRITE_MAX_LENGTH "bps-write-max-length"
+#define QEMU_OPT_IOPS_SIZE "iops-size"
+#define QEMU_OPT_THROTTLE_GROUP_NAME "throttle-group"
+
+#define THROTTLE_OPT_PREFIX "throttling."
#define THROTTLE_OPTS \
{ \
- .name = "throttling.iops-total",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL,\
.type = QEMU_OPT_NUMBER,\
.help = "limit total I/O operations per second",\
},{ \
- .name = "throttling.iops-read",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ,\
.type = QEMU_OPT_NUMBER,\
.help = "limit read operations per second",\
},{ \
- .name = "throttling.iops-write",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE,\
.type = QEMU_OPT_NUMBER,\
.help = "limit write operations per second",\
},{ \
- .name = "throttling.bps-total",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL,\
.type = QEMU_OPT_NUMBER,\
.help = "limit total bytes per second",\
},{ \
- .name = "throttling.bps-read",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ,\
.type = QEMU_OPT_NUMBER,\
.help = "limit read bytes per second",\
},{ \
- .name = "throttling.bps-write",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE,\
.type = QEMU_OPT_NUMBER,\
.help = "limit write bytes per second",\
},{ \
- .name = "throttling.iops-total-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "I/O operations burst",\
},{ \
- .name = "throttling.iops-read-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "I/O operations read burst",\
},{ \
- .name = "throttling.iops-write-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "I/O operations write burst",\
},{ \
- .name = "throttling.bps-total-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "total bytes burst",\
},{ \
- .name = "throttling.bps-read-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "total bytes read burst",\
},{ \
- .name = "throttling.bps-write-max",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX,\
.type = QEMU_OPT_NUMBER,\
.help = "total bytes write burst",\
},{ \
- .name = "throttling.iops-total-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_TOTAL_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the iops-total-max burst period, in seconds",\
},{ \
- .name = "throttling.iops-read-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_READ_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the iops-read-max burst period, in seconds",\
},{ \
- .name = "throttling.iops-write-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_WRITE_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the iops-write-max burst period, in seconds",\
},{ \
- .name = "throttling.bps-total-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_TOTAL_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the bps-total-max burst period, in seconds",\
},{ \
- .name = "throttling.bps-read-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_READ_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the bps-read-max burst period, in seconds",\
},{ \
- .name = "throttling.bps-write-max-length",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_BPS_WRITE_MAX_LENGTH,\
.type = QEMU_OPT_NUMBER,\
.help = "length of the bps-write-max burst period, in seconds",\
},{ \
- .name = "throttling.iops-size",\
+ .name = THROTTLE_OPT_PREFIX QEMU_OPT_IOPS_SIZE,\
.type = QEMU_OPT_NUMBER,\
.help = "when limiting by iops max size of an I/O in bytes",\
}
diff --git a/include/qemu/throttle.h b/include/qemu/throttle.h
index 8e01885..8c93237 100644
--- a/include/qemu/throttle.h
+++ b/include/qemu/throttle.h
@@ -152,5 +152,8 @@ bool throttle_schedule_timer(ThrottleState *ts,
bool is_write);
void throttle_account(ThrottleState *ts, bool is_write, uint64_t size);
+void throttle_limits_to_config(ThrottleLimits *arg, ThrottleConfig *cfg,
+ Error **errp);
+void throttle_config_to_limits(ThrottleConfig *cfg, ThrottleLimits *var);
#endif
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index aadc733..c4e52a5 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -70,24 +70,10 @@ typedef struct BlockDevOps {
/* This struct is embedded in (the private) BlockBackend struct and contains
* fields that must be public. This is in particular for QLIST_ENTRY() and
- * friends so that BlockBackends can be kept in lists outside block-backend.c */
+ * friends so that BlockBackends can be kept in lists outside block-backend.c
+ * */
typedef struct BlockBackendPublic {
- /* throttled_reqs_lock protects the CoQueues for throttled requests. */
- CoMutex throttled_reqs_lock;
- CoQueue throttled_reqs[2];
-
- /* Nonzero if the I/O limits are currently being ignored; generally
- * it is zero. Accessed with atomic operations.
- */
- unsigned int io_limits_disabled;
-
- /* The following fields are protected by the ThrottleGroup lock.
- * See the ThrottleGroup documentation for details.
- * throttle_state tells us if I/O limits are configured. */
- ThrottleState *throttle_state;
- ThrottleTimers throttle_timers;
- unsigned pending_reqs[2];
- QLIST_ENTRY(BlockBackendPublic) round_robin;
+ ThrottleGroupMember throttle_group_member;
} BlockBackendPublic;
BlockBackend *blk_new(uint64_t perm, uint64_t shared_perm);