mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'stefanha/block' into staging
# By Alex Bligh (32) and others # Via Stefan Hajnoczi * stefanha/block: (42 commits) win32-aio: drop win32_aio_flush_cb() aio-win32: replace incorrect AioHandler->opaque usage with ->e aio / timers: remove dummy_io_handler_flush from tests/test-aio.c aio / timers: Remove legacy interface aio / timers: Switch entire codebase to the new timer API aio / timers: Add scripts/switch-timer-api aio / timers: Add test harness for AioContext timers aio / timers: convert block_job_sleep_ns and co_sleep_ns to new API aio / timers: Convert rtc_clock to be a QEMUClockType aio / timers: Remove main_loop_timerlist aio / timers: Rearrange timer.h & make legacy functions call non-legacy aio / timers: Add qemu_clock_get_ms and qemu_clock_get_ms aio / timers: Remove legacy qemu_clock_deadline & qemu_timerlist_deadline aio / timers: Remove alarm timers aio / timers: Add documentation and new format calls aio / timers: Use all timerlists in icount warp calculations aio / timers: Introduce new API timer_new and friends aio / timers: On timer modification, qemu_notify or aio_notify aio / timers: Convert mainloop to use timeout aio / timers: Convert aio_poll to use AioContext timers' deadline ... Message-id: 1377202298-22896-1-git-send-email-stefanha@redhat.com Signed-off-by: Anthony Liguori <anthony@codemonkey.ws>
This commit is contained in:
+12
-6
@@ -165,6 +165,10 @@ static bool aio_dispatch(AioContext *ctx)
|
||||
g_free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Run our timers */
|
||||
progress |= timerlistgroup_run_timers(&ctx->tlg);
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
@@ -219,9 +223,9 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
}
|
||||
|
||||
/* wait until next event */
|
||||
ret = g_poll((GPollFD *)ctx->pollfds->data,
|
||||
ctx->pollfds->len,
|
||||
blocking ? -1 : 0);
|
||||
ret = qemu_poll_ns((GPollFD *)ctx->pollfds->data,
|
||||
ctx->pollfds->len,
|
||||
blocking ? timerlistgroup_deadline_ns(&ctx->tlg) : 0);
|
||||
|
||||
/* if we have any readable fds, dispatch event */
|
||||
if (ret > 0) {
|
||||
@@ -232,9 +236,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
node->pfd.revents = pfd->revents;
|
||||
}
|
||||
}
|
||||
if (aio_dispatch(ctx)) {
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run dispatch even if there were no readable fds to run timers */
|
||||
if (aio_dispatch(ctx)) {
|
||||
progress = true;
|
||||
}
|
||||
|
||||
return progress;
|
||||
|
||||
+20
-4
@@ -95,6 +95,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
HANDLE events[MAXIMUM_WAIT_OBJECTS + 1];
|
||||
bool progress;
|
||||
int count;
|
||||
int timeout;
|
||||
|
||||
progress = false;
|
||||
|
||||
@@ -108,6 +109,9 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
progress = true;
|
||||
}
|
||||
|
||||
/* Run timers */
|
||||
progress |= timerlistgroup_run_timers(&ctx->tlg);
|
||||
|
||||
/*
|
||||
* Then dispatch any pending callbacks from the GSource.
|
||||
*
|
||||
@@ -125,7 +129,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
node->io_notify(node->e);
|
||||
|
||||
/* aio_notify() does not count as progress */
|
||||
if (node->opaque != &ctx->notifier) {
|
||||
if (node->e != &ctx->notifier) {
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
@@ -164,8 +168,11 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
|
||||
/* wait until next event */
|
||||
while (count > 0) {
|
||||
int timeout = blocking ? INFINITE : 0;
|
||||
int ret = WaitForMultipleObjects(count, events, FALSE, timeout);
|
||||
int ret;
|
||||
|
||||
timeout = blocking ?
|
||||
qemu_timeout_ns_to_ms(timerlistgroup_deadline_ns(&ctx->tlg)) : 0;
|
||||
ret = WaitForMultipleObjects(count, events, FALSE, timeout);
|
||||
|
||||
/* if we have any signaled events, dispatch event */
|
||||
if ((DWORD) (ret - WAIT_OBJECT_0) >= count) {
|
||||
@@ -188,7 +195,7 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
node->io_notify(node->e);
|
||||
|
||||
/* aio_notify() does not count as progress */
|
||||
if (node->opaque != &ctx->notifier) {
|
||||
if (node->e != &ctx->notifier) {
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
@@ -208,5 +215,14 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
events[ret - WAIT_OBJECT_0] = events[--count];
|
||||
}
|
||||
|
||||
if (blocking) {
|
||||
/* Run the timers a second time. We do this because otherwise aio_wait
|
||||
* will not note progress - and will stop a drain early - if we have
|
||||
* a timer that was not ready to run entering g_poll but is ready
|
||||
* after g_poll. This will only do anything if a timer has expired.
|
||||
*/
|
||||
progress |= timerlistgroup_run_timers(&ctx->tlg);
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
+6
-6
@@ -392,7 +392,7 @@ static void migration_bitmap_sync(void)
|
||||
}
|
||||
|
||||
if (!start_time) {
|
||||
start_time = qemu_get_clock_ms(rt_clock);
|
||||
start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
}
|
||||
|
||||
trace_migration_bitmap_sync_start();
|
||||
@@ -410,7 +410,7 @@ static void migration_bitmap_sync(void)
|
||||
trace_migration_bitmap_sync_end(migration_dirty_pages
|
||||
- num_dirty_pages_init);
|
||||
num_dirty_pages_period += migration_dirty_pages - num_dirty_pages_init;
|
||||
end_time = qemu_get_clock_ms(rt_clock);
|
||||
end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
|
||||
/* more than 1 second = 1000 millisecons */
|
||||
if (end_time > start_time + 1000) {
|
||||
@@ -672,7 +672,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
|
||||
|
||||
ram_control_before_iterate(f, RAM_CONTROL_ROUND);
|
||||
|
||||
t0 = qemu_get_clock_ns(rt_clock);
|
||||
t0 = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
||||
i = 0;
|
||||
while ((ret = qemu_file_rate_limit(f)) == 0) {
|
||||
int bytes_sent;
|
||||
@@ -691,7 +691,7 @@ static int ram_save_iterate(QEMUFile *f, void *opaque)
|
||||
iterations
|
||||
*/
|
||||
if ((i & 63) == 0) {
|
||||
uint64_t t1 = (qemu_get_clock_ns(rt_clock) - t0) / 1000000;
|
||||
uint64_t t1 = (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - t0) / 1000000;
|
||||
if (t1 > MAX_WAIT) {
|
||||
DPRINTF("big wait: %" PRIu64 " milliseconds, %d iterations\n",
|
||||
t1, i);
|
||||
@@ -1217,11 +1217,11 @@ static void check_guest_throttling(void)
|
||||
}
|
||||
|
||||
if (!t0) {
|
||||
t0 = qemu_get_clock_ns(rt_clock);
|
||||
t0 = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
||||
return;
|
||||
}
|
||||
|
||||
t1 = qemu_get_clock_ns(rt_clock);
|
||||
t1 = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
||||
|
||||
/* If it has been more than 40 ms since the last time the guest
|
||||
* was throttled then do it again.
|
||||
|
||||
@@ -150,7 +150,10 @@ aio_ctx_prepare(GSource *source, gint *timeout)
|
||||
{
|
||||
AioContext *ctx = (AioContext *) source;
|
||||
QEMUBH *bh;
|
||||
int deadline;
|
||||
|
||||
/* We assume there is no timeout already supplied */
|
||||
*timeout = -1;
|
||||
for (bh = ctx->first_bh; bh; bh = bh->next) {
|
||||
if (!bh->deleted && bh->scheduled) {
|
||||
if (bh->idle) {
|
||||
@@ -166,6 +169,14 @@ aio_ctx_prepare(GSource *source, gint *timeout)
|
||||
}
|
||||
}
|
||||
|
||||
deadline = qemu_timeout_ns_to_ms(timerlistgroup_deadline_ns(&ctx->tlg));
|
||||
if (deadline == 0) {
|
||||
*timeout = 0;
|
||||
return true;
|
||||
} else {
|
||||
*timeout = qemu_soonest_timeout(*timeout, deadline);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -180,7 +191,7 @@ aio_ctx_check(GSource *source)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return aio_pending(ctx);
|
||||
return aio_pending(ctx) || (timerlistgroup_deadline_ns(&ctx->tlg) == 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -205,6 +216,7 @@ aio_ctx_finalize(GSource *source)
|
||||
event_notifier_cleanup(&ctx->notifier);
|
||||
qemu_mutex_destroy(&ctx->bh_lock);
|
||||
g_array_free(ctx->pollfds, TRUE);
|
||||
timerlistgroup_deinit(&ctx->tlg);
|
||||
}
|
||||
|
||||
static GSourceFuncs aio_source_funcs = {
|
||||
@@ -233,6 +245,11 @@ void aio_notify(AioContext *ctx)
|
||||
event_notifier_set(&ctx->notifier);
|
||||
}
|
||||
|
||||
static void aio_timerlist_notify(void *opaque)
|
||||
{
|
||||
aio_notify(opaque);
|
||||
}
|
||||
|
||||
AioContext *aio_context_new(void)
|
||||
{
|
||||
AioContext *ctx;
|
||||
@@ -244,6 +261,7 @@ AioContext *aio_context_new(void)
|
||||
aio_set_event_notifier(ctx, &ctx->notifier,
|
||||
(EventNotifierHandler *)
|
||||
event_notifier_test_and_clear);
|
||||
timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
+3
-3
@@ -1124,10 +1124,10 @@ static int audio_is_timer_needed (void)
|
||||
static void audio_reset_timer (AudioState *s)
|
||||
{
|
||||
if (audio_is_timer_needed ()) {
|
||||
qemu_mod_timer (s->ts, qemu_get_clock_ns (vm_clock) + 1);
|
||||
timer_mod (s->ts, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1);
|
||||
}
|
||||
else {
|
||||
qemu_del_timer (s->ts);
|
||||
timer_del (s->ts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1834,7 +1834,7 @@ static void audio_init (void)
|
||||
QLIST_INIT (&s->cap_head);
|
||||
atexit (audio_atexit);
|
||||
|
||||
s->ts = qemu_new_timer_ns (vm_clock, audio_timer, s);
|
||||
s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
|
||||
if (!s->ts) {
|
||||
hw_error("Could not create audio timer\n");
|
||||
}
|
||||
|
||||
+2
-2
@@ -46,7 +46,7 @@ static int no_run_out (HWVoiceOut *hw, int live)
|
||||
int64_t ticks;
|
||||
int64_t bytes;
|
||||
|
||||
now = qemu_get_clock_ns (vm_clock);
|
||||
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ticks = now - no->old_ticks;
|
||||
bytes = muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
|
||||
bytes = audio_MIN (bytes, INT_MAX);
|
||||
@@ -102,7 +102,7 @@ static int no_run_in (HWVoiceIn *hw)
|
||||
int samples = 0;
|
||||
|
||||
if (dead) {
|
||||
int64_t now = qemu_get_clock_ns (vm_clock);
|
||||
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
int64_t ticks = now - no->old_ticks;
|
||||
int64_t bytes =
|
||||
muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
|
||||
|
||||
+2
-2
@@ -81,7 +81,7 @@ static void spice_audio_fini (void *opaque)
|
||||
static void rate_start (SpiceRateCtl *rate)
|
||||
{
|
||||
memset (rate, 0, sizeof (*rate));
|
||||
rate->start_ticks = qemu_get_clock_ns (vm_clock);
|
||||
rate->start_ticks = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
}
|
||||
|
||||
static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
|
||||
@@ -91,7 +91,7 @@ static int rate_get_samples (struct audio_pcm_info *info, SpiceRateCtl *rate)
|
||||
int64_t bytes;
|
||||
int64_t samples;
|
||||
|
||||
now = qemu_get_clock_ns (vm_clock);
|
||||
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
ticks = now - rate->start_ticks;
|
||||
bytes = muldiv64 (ticks, info->bytes_per_second, get_ticks_per_sec ());
|
||||
samples = (bytes - rate->bytes_sent) >> info->shift;
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ static int wav_run_out (HWVoiceOut *hw, int live)
|
||||
int rpos, decr, samples;
|
||||
uint8_t *dst;
|
||||
struct st_sample *src;
|
||||
int64_t now = qemu_get_clock_ns (vm_clock);
|
||||
int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
int64_t ticks = now - wav->old_ticks;
|
||||
int64_t bytes =
|
||||
muldiv64 (ticks, hw->info.bytes_per_second, get_ticks_per_sec ());
|
||||
|
||||
+8
-8
@@ -314,9 +314,9 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
|
||||
return 0; \
|
||||
if (*cur++ != ESC) { \
|
||||
DPRINTF("Broken packet %#2x, tossing\n", req); \
|
||||
if (qemu_timer_pending(baum->cellCount_timer)) { \
|
||||
qemu_del_timer(baum->cellCount_timer); \
|
||||
baum_cellCount_timer_cb(baum); \
|
||||
if (timer_pending(baum->cellCount_timer)) { \
|
||||
timer_del(baum->cellCount_timer); \
|
||||
baum_cellCount_timer_cb(baum); \
|
||||
} \
|
||||
return (cur - 2 - buf); \
|
||||
} \
|
||||
@@ -334,7 +334,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
|
||||
int i;
|
||||
|
||||
/* Allow 100ms to complete the DisplayData packet */
|
||||
qemu_mod_timer(baum->cellCount_timer, qemu_get_clock_ns(vm_clock) +
|
||||
timer_mod(baum->cellCount_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
||||
get_ticks_per_sec() / 10);
|
||||
for (i = 0; i < baum->x * baum->y ; i++) {
|
||||
EAT(c);
|
||||
@@ -348,7 +348,7 @@ static int baum_eat_packet(BaumDriverState *baum, const uint8_t *buf, int len)
|
||||
c = '?';
|
||||
text[i] = c;
|
||||
}
|
||||
qemu_del_timer(baum->cellCount_timer);
|
||||
timer_del(baum->cellCount_timer);
|
||||
|
||||
memset(zero, 0, sizeof(zero));
|
||||
|
||||
@@ -553,7 +553,7 @@ static void baum_close(struct CharDriverState *chr)
|
||||
{
|
||||
BaumDriverState *baum = chr->opaque;
|
||||
|
||||
qemu_free_timer(baum->cellCount_timer);
|
||||
timer_free(baum->cellCount_timer);
|
||||
if (baum->brlapi) {
|
||||
brlapi__closeConnection(baum->brlapi);
|
||||
g_free(baum->brlapi);
|
||||
@@ -588,7 +588,7 @@ CharDriverState *chr_baum_init(void)
|
||||
goto fail_handle;
|
||||
}
|
||||
|
||||
baum->cellCount_timer = qemu_new_timer_ns(vm_clock, baum_cellCount_timer_cb, baum);
|
||||
baum->cellCount_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, baum_cellCount_timer_cb, baum);
|
||||
|
||||
if (brlapi__getDisplaySize(handle, &baum->x, &baum->y) == -1) {
|
||||
brlapi_perror("baum_init: brlapi_getDisplaySize");
|
||||
@@ -614,7 +614,7 @@ CharDriverState *chr_baum_init(void)
|
||||
return chr;
|
||||
|
||||
fail:
|
||||
qemu_free_timer(baum->cellCount_timer);
|
||||
timer_free(baum->cellCount_timer);
|
||||
brlapi__closeConnection(handle);
|
||||
fail_handle:
|
||||
g_free(handle);
|
||||
|
||||
@@ -130,8 +130,8 @@ void bdrv_io_limits_disable(BlockDriverState *bs)
|
||||
do {} while (qemu_co_enter_next(&bs->throttled_reqs));
|
||||
|
||||
if (bs->block_timer) {
|
||||
qemu_del_timer(bs->block_timer);
|
||||
qemu_free_timer(bs->block_timer);
|
||||
timer_del(bs->block_timer);
|
||||
timer_free(bs->block_timer);
|
||||
bs->block_timer = NULL;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ static void bdrv_block_timer(void *opaque)
|
||||
|
||||
void bdrv_io_limits_enable(BlockDriverState *bs)
|
||||
{
|
||||
bs->block_timer = qemu_new_timer_ns(vm_clock, bdrv_block_timer, bs);
|
||||
bs->block_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, bdrv_block_timer, bs);
|
||||
bs->io_limits_enabled = true;
|
||||
}
|
||||
|
||||
@@ -180,8 +180,8 @@ static void bdrv_io_limits_intercept(BlockDriverState *bs,
|
||||
*/
|
||||
|
||||
while (bdrv_exceed_io_limits(bs, nb_sectors, is_write, &wait_time)) {
|
||||
qemu_mod_timer(bs->block_timer,
|
||||
wait_time + qemu_get_clock_ns(vm_clock));
|
||||
timer_mod(bs->block_timer,
|
||||
wait_time + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
qemu_co_queue_wait_insert_head(&bs->throttled_reqs);
|
||||
}
|
||||
|
||||
@@ -706,6 +706,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,
|
||||
|
||||
bs->open_flags = flags;
|
||||
bs->buffer_alignment = 512;
|
||||
bs->zero_beyond_eof = true;
|
||||
open_flags = bdrv_open_flags(bs, flags);
|
||||
bs->read_only = !(open_flags & BDRV_O_RDWR);
|
||||
|
||||
@@ -1402,6 +1403,7 @@ void bdrv_close(BlockDriverState *bs)
|
||||
bs->valid_key = 0;
|
||||
bs->sg = 0;
|
||||
bs->growable = 0;
|
||||
bs->zero_beyond_eof = false;
|
||||
QDECREF(bs->options);
|
||||
bs->options = NULL;
|
||||
|
||||
@@ -2569,7 +2571,35 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
|
||||
}
|
||||
}
|
||||
|
||||
ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
|
||||
if (!(bs->zero_beyond_eof && bs->growable)) {
|
||||
ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
|
||||
} else {
|
||||
/* Read zeros after EOF of growable BDSes */
|
||||
int64_t len, total_sectors, max_nb_sectors;
|
||||
|
||||
len = bdrv_getlength(bs);
|
||||
if (len < 0) {
|
||||
ret = len;
|
||||
goto out;
|
||||
}
|
||||
|
||||
total_sectors = len >> BDRV_SECTOR_BITS;
|
||||
max_nb_sectors = MAX(0, total_sectors - sector_num);
|
||||
if (max_nb_sectors > 0) {
|
||||
ret = drv->bdrv_co_readv(bs, sector_num,
|
||||
MIN(nb_sectors, max_nb_sectors), qiov);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
/* Reading beyond end of file is supposed to produce zeroes */
|
||||
if (ret == 0 && total_sectors < sector_num + nb_sectors) {
|
||||
uint64_t offset = MAX(0, total_sectors - sector_num);
|
||||
uint64_t bytes = (sector_num + nb_sectors - offset) *
|
||||
BDRV_SECTOR_SIZE;
|
||||
qemu_iovec_memset(qiov, offset * BDRV_SECTOR_SIZE, 0, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
tracked_request_end(&req);
|
||||
@@ -3717,7 +3747,7 @@ static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors,
|
||||
double elapsed_time;
|
||||
int bps_ret, iops_ret;
|
||||
|
||||
now = qemu_get_clock_ns(vm_clock);
|
||||
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
if (now > bs->slice_end) {
|
||||
bs->slice_start = now;
|
||||
bs->slice_end = now + BLOCK_IO_SLICE_TIME;
|
||||
@@ -3737,7 +3767,7 @@ static bool bdrv_exceed_io_limits(BlockDriverState *bs, int nb_sectors,
|
||||
*wait = max_wait;
|
||||
}
|
||||
|
||||
now = qemu_get_clock_ns(vm_clock);
|
||||
now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
|
||||
if (bs->slice_end < now + max_wait) {
|
||||
bs->slice_end = now + max_wait;
|
||||
}
|
||||
|
||||
+2
-2
@@ -272,9 +272,9 @@ static void coroutine_fn backup_run(void *opaque)
|
||||
uint64_t delay_ns = ratelimit_calculate_delay(
|
||||
&job->limit, job->sectors_read);
|
||||
job->sectors_read = 0;
|
||||
block_job_sleep_ns(&job->common, rt_clock, delay_ns);
|
||||
block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, delay_ns);
|
||||
} else {
|
||||
block_job_sleep_ns(&job->common, rt_clock, 0);
|
||||
block_job_sleep_ns(&job->common, QEMU_CLOCK_REALTIME, 0);
|
||||
}
|
||||
|
||||
if (block_job_is_cancelled(&job->common)) {
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ wait:
|
||||
/* Note that even when no rate limit is applied we need to yield
|
||||
* with no pending I/O here so that bdrv_drain_all() returns.
|
||||
*/
|
||||
block_job_sleep_ns(&s->common, rt_clock, delay_ns);
|
||||
block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
|
||||
if (block_job_is_cancelled(&s->common)) {
|
||||
break;
|
||||
}
|
||||
|
||||
+7
-7
@@ -960,7 +960,7 @@ static void iscsi_nop_timed_event(void *opaque)
|
||||
return;
|
||||
}
|
||||
|
||||
qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) + NOP_INTERVAL);
|
||||
timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
|
||||
iscsi_set_events(iscsilun);
|
||||
}
|
||||
#endif
|
||||
@@ -1173,8 +1173,8 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags)
|
||||
|
||||
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
|
||||
/* Set up a timer for sending out iSCSI NOPs */
|
||||
iscsilun->nop_timer = qemu_new_timer_ms(rt_clock, iscsi_nop_timed_event, iscsilun);
|
||||
qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) + NOP_INTERVAL);
|
||||
iscsilun->nop_timer = timer_new_ms(QEMU_CLOCK_REALTIME, iscsi_nop_timed_event, iscsilun);
|
||||
timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
|
||||
#endif
|
||||
|
||||
out:
|
||||
@@ -1204,8 +1204,8 @@ static void iscsi_close(BlockDriverState *bs)
|
||||
struct iscsi_context *iscsi = iscsilun->iscsi;
|
||||
|
||||
if (iscsilun->nop_timer) {
|
||||
qemu_del_timer(iscsilun->nop_timer);
|
||||
qemu_free_timer(iscsilun->nop_timer);
|
||||
timer_del(iscsilun->nop_timer);
|
||||
timer_free(iscsilun->nop_timer);
|
||||
}
|
||||
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
|
||||
iscsi_destroy_context(iscsi);
|
||||
@@ -1267,8 +1267,8 @@ static int iscsi_create(const char *filename, QEMUOptionParameter *options)
|
||||
goto out;
|
||||
}
|
||||
if (iscsilun->nop_timer) {
|
||||
qemu_del_timer(iscsilun->nop_timer);
|
||||
qemu_free_timer(iscsilun->nop_timer);
|
||||
timer_del(iscsilun->nop_timer);
|
||||
timer_free(iscsilun->nop_timer);
|
||||
}
|
||||
if (iscsilun->type != TYPE_DISK) {
|
||||
ret = -ENODEV;
|
||||
|
||||
+5
-5
@@ -356,7 +356,7 @@ static void coroutine_fn mirror_run(void *opaque)
|
||||
}
|
||||
|
||||
bdrv_dirty_iter_init(bs, &s->hbi);
|
||||
last_pause_ns = qemu_get_clock_ns(rt_clock);
|
||||
last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
||||
for (;;) {
|
||||
uint64_t delay_ns;
|
||||
int64_t cnt;
|
||||
@@ -374,7 +374,7 @@ static void coroutine_fn mirror_run(void *opaque)
|
||||
* We do so every SLICE_TIME nanoseconds, or when there is an error,
|
||||
* or when the source is clean, whichever comes first.
|
||||
*/
|
||||
if (qemu_get_clock_ns(rt_clock) - last_pause_ns < SLICE_TIME &&
|
||||
if (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - last_pause_ns < SLICE_TIME &&
|
||||
s->common.iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
|
||||
if (s->in_flight == MAX_IN_FLIGHT || s->buf_free_count == 0 ||
|
||||
(cnt == 0 && s->in_flight > 0)) {
|
||||
@@ -439,13 +439,13 @@ static void coroutine_fn mirror_run(void *opaque)
|
||||
delay_ns = 0;
|
||||
}
|
||||
|
||||
block_job_sleep_ns(&s->common, rt_clock, delay_ns);
|
||||
block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
|
||||
if (block_job_is_cancelled(&s->common)) {
|
||||
break;
|
||||
}
|
||||
} else if (!should_complete) {
|
||||
delay_ns = (s->in_flight == 0 && cnt == 0 ? SLICE_TIME : 0);
|
||||
block_job_sleep_ns(&s->common, rt_clock, delay_ns);
|
||||
block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
|
||||
} else if (cnt == 0) {
|
||||
/* The two disks are in sync. Exit and report successful
|
||||
* completion.
|
||||
@@ -454,7 +454,7 @@ static void coroutine_fn mirror_run(void *opaque)
|
||||
s->common.cancelled = false;
|
||||
break;
|
||||
}
|
||||
last_pause_ns = qemu_get_clock_ns(rt_clock);
|
||||
last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
||||
}
|
||||
|
||||
immediate_exit:
|
||||
|
||||
+4
-1
@@ -1402,7 +1402,7 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options)
|
||||
int flags = 0;
|
||||
size_t cluster_size = DEFAULT_CLUSTER_SIZE;
|
||||
int prealloc = 0;
|
||||
int version = 2;
|
||||
int version = 3;
|
||||
|
||||
/* Read out options */
|
||||
while (options && options->name) {
|
||||
@@ -1722,12 +1722,15 @@ static int qcow2_load_vmstate(BlockDriverState *bs, uint8_t *buf,
|
||||
{
|
||||
BDRVQcowState *s = bs->opaque;
|
||||
int growable = bs->growable;
|
||||
bool zero_beyond_eof = bs->zero_beyond_eof;
|
||||
int ret;
|
||||
|
||||
BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_LOAD);
|
||||
bs->growable = 1;
|
||||
bs->zero_beyond_eof = false;
|
||||
ret = bdrv_pread(bs, qcow2_vm_state_offset(s) + pos, buf, size);
|
||||
bs->growable = growable;
|
||||
bs->zero_beyond_eof = zero_beyond_eof;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
+5
-5
@@ -353,10 +353,10 @@ static void qed_start_need_check_timer(BDRVQEDState *s)
|
||||
{
|
||||
trace_qed_start_need_check_timer(s);
|
||||
|
||||
/* Use vm_clock so we don't alter the image file while suspended for
|
||||
/* Use QEMU_CLOCK_VIRTUAL so we don't alter the image file while suspended for
|
||||
* migration.
|
||||
*/
|
||||
qemu_mod_timer(s->need_check_timer, qemu_get_clock_ns(vm_clock) +
|
||||
timer_mod(s->need_check_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
|
||||
get_ticks_per_sec() * QED_NEED_CHECK_TIMEOUT);
|
||||
}
|
||||
|
||||
@@ -364,7 +364,7 @@ static void qed_start_need_check_timer(BDRVQEDState *s)
|
||||
static void qed_cancel_need_check_timer(BDRVQEDState *s)
|
||||
{
|
||||
trace_qed_cancel_need_check_timer(s);
|
||||
qemu_del_timer(s->need_check_timer);
|
||||
timer_del(s->need_check_timer);
|
||||
}
|
||||
|
||||
static void bdrv_qed_rebind(BlockDriverState *bs)
|
||||
@@ -494,7 +494,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
s->need_check_timer = qemu_new_timer_ns(vm_clock,
|
||||
s->need_check_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
|
||||
qed_need_check_timer_cb, s);
|
||||
|
||||
out:
|
||||
@@ -518,7 +518,7 @@ static void bdrv_qed_close(BlockDriverState *bs)
|
||||
BDRVQEDState *s = bs->opaque;
|
||||
|
||||
qed_cancel_need_check_timer(s);
|
||||
qemu_free_timer(s->need_check_timer);
|
||||
timer_free(s->need_check_timer);
|
||||
|
||||
/* Ensure writes reach stable storage */
|
||||
bdrv_flush(bs->file);
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ wait:
|
||||
/* Note that even when no rate limit is applied we need to yield
|
||||
* with no pending I/O here so that bdrv_drain_all() returns.
|
||||
*/
|
||||
block_job_sleep_ns(&s->common, rt_clock, delay_ns);
|
||||
block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, delay_ns);
|
||||
if (block_job_is_cancelled(&s->common)) {
|
||||
break;
|
||||
}
|
||||
|
||||
+27
-25
@@ -401,6 +401,14 @@ static int vmdk_add_extent(BlockDriverState *bs,
|
||||
error_report("invalid granularity, image may be corrupt");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (l1_size > 512 * 1024 * 1024) {
|
||||
/* Although with big capacity and small l1_entry_sectors, we can get a
|
||||
* big l1_size, we don't want unbounded value to allocate the table.
|
||||
* Limit it to 512M, which is 16PB for default cluster and L2 table
|
||||
* size */
|
||||
error_report("L1 size too big");
|
||||
return -EFBIG;
|
||||
}
|
||||
|
||||
s->extents = g_realloc(s->extents,
|
||||
(s->num_extents + 1) * sizeof(VmdkExtent));
|
||||
@@ -473,9 +481,9 @@ static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vmdk_open_vmdk3(BlockDriverState *bs,
|
||||
BlockDriverState *file,
|
||||
int flags)
|
||||
static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
|
||||
BlockDriverState *file,
|
||||
int flags)
|
||||
{
|
||||
int ret;
|
||||
uint32_t magic;
|
||||
@@ -486,14 +494,14 @@ static int vmdk_open_vmdk3(BlockDriverState *bs,
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = vmdk_add_extent(bs,
|
||||
bs->file, false,
|
||||
le32_to_cpu(header.disk_sectors),
|
||||
le32_to_cpu(header.l1dir_offset) << 9,
|
||||
0, 1 << 6, 1 << 9,
|
||||
le32_to_cpu(header.granularity),
|
||||
&extent);
|
||||
ret = vmdk_add_extent(bs, file, false,
|
||||
le32_to_cpu(header.disk_sectors),
|
||||
le32_to_cpu(header.l1dir_offset) << 9,
|
||||
0,
|
||||
le32_to_cpu(header.l1dir_size),
|
||||
4096,
|
||||
le32_to_cpu(header.granularity),
|
||||
&extent);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@@ -598,14 +606,6 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
||||
}
|
||||
l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
|
||||
/ l1_entry_sectors;
|
||||
if (l1_size > 512 * 1024 * 1024) {
|
||||
/* although with big capacity and small l1_entry_sectors, we can get a
|
||||
* big l1_size, we don't want unbounded value to allocate the table.
|
||||
* Limit it to 512M, which is 16PB for default cluster and L2 table
|
||||
* size */
|
||||
error_report("L1 size too big");
|
||||
return -EFBIG;
|
||||
}
|
||||
if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
|
||||
l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
|
||||
}
|
||||
@@ -674,7 +674,7 @@ static int vmdk_open_sparse(BlockDriverState *bs,
|
||||
magic = be32_to_cpu(magic);
|
||||
switch (magic) {
|
||||
case VMDK3_MAGIC:
|
||||
return vmdk_open_vmdk3(bs, file, flags);
|
||||
return vmdk_open_vmfs_sparse(bs, file, flags);
|
||||
break;
|
||||
case VMDK4_MAGIC:
|
||||
return vmdk_open_vmdk4(bs, file, flags);
|
||||
@@ -718,7 +718,8 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
||||
}
|
||||
|
||||
if (sectors <= 0 ||
|
||||
(strcmp(type, "FLAT") && strcmp(type, "SPARSE")) ||
|
||||
(strcmp(type, "FLAT") && strcmp(type, "SPARSE") &&
|
||||
strcmp(type, "VMFS") && strcmp(type, "VMFSSPARSE")) ||
|
||||
(strcmp(access, "RW"))) {
|
||||
goto next_line;
|
||||
}
|
||||
@@ -731,7 +732,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
||||
}
|
||||
|
||||
/* save to extents array */
|
||||
if (!strcmp(type, "FLAT")) {
|
||||
if (!strcmp(type, "FLAT") || !strcmp(type, "VMFS")) {
|
||||
/* FLAT extent */
|
||||
VmdkExtent *extent;
|
||||
|
||||
@@ -741,8 +742,8 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
||||
return ret;
|
||||
}
|
||||
extent->flat_start_offset = flat_offset << 9;
|
||||
} else if (!strcmp(type, "SPARSE")) {
|
||||
/* SPARSE extent */
|
||||
} else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
|
||||
/* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
|
||||
ret = vmdk_open_sparse(bs, extent_file, bs->open_flags);
|
||||
if (ret) {
|
||||
bdrv_delete(extent_file);
|
||||
@@ -789,6 +790,8 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
|
||||
goto exit;
|
||||
}
|
||||
if (strcmp(ct, "monolithicFlat") &&
|
||||
strcmp(ct, "vmfs") &&
|
||||
strcmp(ct, "vmfsSparse") &&
|
||||
strcmp(ct, "twoGbMaxExtentSparse") &&
|
||||
strcmp(ct, "twoGbMaxExtentFlat")) {
|
||||
fprintf(stderr,
|
||||
@@ -1381,7 +1384,6 @@ static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int vmdk_create_extent(const char *filename, int64_t filesize,
|
||||
bool flat, bool compress, bool zeroed_grain)
|
||||
{
|
||||
|
||||
+1
-9
@@ -105,13 +105,6 @@ static void win32_aio_completion_cb(EventNotifier *e)
|
||||
}
|
||||
}
|
||||
|
||||
static int win32_aio_flush_cb(EventNotifier *e)
|
||||
{
|
||||
QEMUWin32AIOState *s = container_of(e, QEMUWin32AIOState, e);
|
||||
|
||||
return (s->count > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void win32_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||
{
|
||||
QEMUWin32AIOCB *waiocb = (QEMUWin32AIOCB *)blockacb;
|
||||
@@ -201,8 +194,7 @@ QEMUWin32AIOState *win32_aio_init(void)
|
||||
goto out_close_efd;
|
||||
}
|
||||
|
||||
qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb,
|
||||
win32_aio_flush_cb);
|
||||
qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb);
|
||||
|
||||
return s;
|
||||
|
||||
|
||||
+6
-2
@@ -487,7 +487,11 @@ static DriveInfo *blockdev_init(QemuOpts *all_opts,
|
||||
|
||||
drv = bdrv_find_whitelisted_format(buf, ro);
|
||||
if (!drv) {
|
||||
error_report("'%s' invalid format", buf);
|
||||
if (!ro && bdrv_find_whitelisted_format(buf, !ro)) {
|
||||
error_report("'%s' can be only used as read-only device.", buf);
|
||||
} else {
|
||||
error_report("'%s' invalid format", buf);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@@ -1295,7 +1299,7 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
|
||||
bdrv_io_limits_disable(bs);
|
||||
} else {
|
||||
if (bs->block_timer) {
|
||||
qemu_mod_timer(bs->block_timer, qemu_get_clock_ns(vm_clock));
|
||||
timer_mod(bs->block_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user