Merge remote-tracking branch 'qemu/master'
[qemu/ar7.git] / block / fvd-prefetch.c
blob4a0d495f463d25f87a0c4e4202dcaf4f93702303
1 /*
2 * Copyright (c) 2010-2011 IBM
4 * Authors:
5 * Chunqiang Tang <ctang@us.ibm.com>
7 * This work is licensed under the terms of the GNU GPL, version 2.
8 * See the COPYING file in the top-level directory.
9 */
11 /*=============================================================================
12 * A short description: this FVD module implements the function of
13 * prefetching data from the base image and storing it in the FVD image.
14 *============================================================================*/
16 static void resume_prefetch (BlockDriverState * bs, int64_t current_time);
17 static void do_next_prefetch_read (BlockDriverState * bs, int64_t current_time);
19 void fvd_init_prefetch (void *opaque)
21 BlockDriverState * bs = opaque;
22 BDRVFvdState *s = bs->opaque;
23 FvdAIOCB *acb;
24 int i;
26 QDEBUG ("Start prefetching\n");
28 if (bdrv_find_format ("blksim") == NULL) {
29 /* In simulation mode, the random seed should not be initialized here.*/
30 srandom (time (NULL) + getpid () + getpid () * 987654 + random ());
33 s->prefetch_acb =
34 my_qemu_malloc (sizeof (FvdAIOCB *) * s->num_prefetch_slots);
36 for (i = 0; i < s->num_prefetch_slots; i++) {
37 acb = s->prefetch_acb[i] =
38 my_qemu_aio_get (&fvd_aio_pool, bs, null_prefetch_cb, NULL);
40 if (!acb) {
41 s->prefetch_error = TRUE;
42 int j;
43 for (j = 0; j < i; j++) {
44 my_qemu_aio_release (s->prefetch_acb[j]);
45 s->prefetch_acb[j] = NULL;
48 my_qemu_free (s->prefetch_acb);
49 s->prefetch_acb = NULL;
50 fprintf (stderr,
51 "qemu_aio_get() failed and cannot start prefetching.\n");
52 return;
55 acb->type = OP_COPY;
58 s->prefetch_state = PREFETCH_STATE_RUNNING;
60 for (i = 0; i < s->num_prefetch_slots; i++) {
61 acb = s->prefetch_acb[i];
62 acb->copy.buffered_sector_begin = acb->copy.buffered_sector_end = 0;
63 QLIST_INIT (&acb->copy_lock.dependent_writes);
64 acb->copy_lock.next.le_prev = NULL;
65 acb->copy.hd_acb = NULL;
66 acb->sector_num = 0;
67 acb->nb_sectors = 0;
68 acb->copy.iov.iov_len = s->sectors_per_prefetch * 512;
69 acb->copy.buf = acb->copy.iov.iov_base =
70 my_qemu_blockalign (bs->backing_hd, acb->copy.iov.iov_len);
71 qemu_iovec_init_external (&acb->copy.qiov, &acb->copy.iov, 1);
74 if (s->prefetch_timer) {
75 timer_free(s->prefetch_timer);
76 s->prefetch_timer =
77 timer_new_ns(QEMU_CLOCK_REALTIME, (QEMUTimerCB *) resume_prefetch, bs);
80 s->pause_prefetch_requested = FALSE;
81 s->unclaimed_prefetch_region_start = 0;
82 s->prefetch_read_throughput = -1; /* Indicate not initialized. */
83 s->prefetch_write_throughput = -1; /* Indicate not initialized. */
84 s->prefetch_read_time = 0;
85 s->prefetch_write_time = 0;
86 s->prefetch_data_read = 0;
87 s->prefetch_data_written = 0;
88 s->next_prefetch_read_slot = 0;
89 s->num_filled_prefetch_slots = 0;
90 s->prefetch_read_active = FALSE;
92 do_next_prefetch_read (bs, qemu_clock_get_ns(QEMU_CLOCK_REALTIME));
95 static void pause_prefetch (BDRVFvdState * s)
97 int64_t ms = 1 + (int64_t) ((random () / ((double) RAND_MAX))
98 * s->prefetch_throttle_time);
99 QDEBUG ("Pause prefetch for %" PRId64 " milliseconds\n", ms);
100 /* When the timer expires, it goes to resume_prefetch(). */
101 timer_mod(s->prefetch_timer, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + ms);
104 static void terminate_prefetch (BlockDriverState * bs, int final_state)
106 BDRVFvdState *s = bs->opaque;
107 int i;
109 ASSERT (!s->prefetch_read_active && s->num_filled_prefetch_slots == 0);
111 for (i = 0; i < s->num_prefetch_slots; i++) {
112 if (s->prefetch_acb) {
113 my_qemu_vfree (s->prefetch_acb[i]->copy.buf);
114 my_qemu_aio_release (s->prefetch_acb[i]);
115 s->prefetch_acb[i] = NULL;
118 my_qemu_free (s->prefetch_acb);
119 s->prefetch_acb = NULL;
121 if (s->prefetch_timer) {
122 timer_del(s->prefetch_timer);
123 timer_free(s->prefetch_timer);
124 s->prefetch_timer = NULL;
127 if (final_state == PREFETCH_STATE_FINISHED) {
128 if (s->prefetch_error) {
129 s->prefetch_state = PREFETCH_STATE_DISABLED;
130 } else {
131 s->prefetch_state = PREFETCH_STATE_FINISHED;
133 } else {
134 s->prefetch_state = final_state;
137 if (s->prefetch_state == PREFETCH_STATE_FINISHED) {
138 QDEBUG ("FVD prefetching finished successfully.\n");
140 if (s->stale_bitmap) {
141 memset (s->stale_bitmap, 0xFF, s->bitmap_size);
142 if (s->fresh_bitmap && s->fresh_bitmap != s->stale_bitmap) {
143 memset (s->fresh_bitmap, 0xFF, s->bitmap_size);
147 /* Flush the table since its entries may be dirty due to 'soft-write'
148 * by prefetching or copy-on-read. */
149 flush_metadata_to_disk (bs);
151 /* Update the on-disk header. */
152 FvdHeader header;
153 read_fvd_header (s, &header);
154 header.all_data_in_fvd_img = TRUE;
155 update_fvd_header (s, &header);
156 s->copy_on_read = FALSE;
157 } else if (s->prefetch_state == PREFETCH_STATE_DISABLED) {
158 QDEBUG ("FVD disk prefetching disabled.\n");
162 static void do_next_prefetch_read (BlockDriverState * bs, int64_t current_time)
164 FvdAIOCB *acb;
165 BDRVFvdState *s = bs->opaque;
166 int64_t begin, end;
168 ASSERT (!s->prefetch_read_active
169 && s->num_filled_prefetch_slots < s->num_prefetch_slots
170 && !s->pause_prefetch_requested);
172 /* Find the next region to prefetch. */
173 begin = s->unclaimed_prefetch_region_start;
174 while (1) {
175 if (begin >= s->nb_sectors_in_base_img) {
176 s->unclaimed_prefetch_region_start = s->nb_sectors_in_base_img;
177 if (s->num_filled_prefetch_slots == 0) {
178 terminate_prefetch (bs, PREFETCH_STATE_FINISHED);
180 return;
182 end = begin + s->sectors_per_prefetch;
183 if (end > s->nb_sectors_in_base_img) {
184 end = s->nb_sectors_in_base_img;
186 if (find_region_in_base_img (s, &begin, &end)) {
187 break;
189 begin = end;
192 ASSERT (begin % s->block_size == 0
193 && (end % s->block_size == 0 || end == s->nb_sectors_in_base_img));
195 acb = s->prefetch_acb[s->next_prefetch_read_slot];
196 acb->copy.buffered_sector_begin = acb->sector_num = begin;
197 acb->copy.buffered_sector_end = s->unclaimed_prefetch_region_start = end;
198 acb->nb_sectors = end - begin;
199 acb->copy.qiov.size = acb->copy.iov.iov_len = acb->nb_sectors * 512;
200 acb->copy.iov.iov_base = acb->copy.buf;
201 acb->copy.last_prefetch_op_start_time = current_time;
202 acb->copy.hd_acb = bdrv_aio_readv (bs->backing_hd, acb->sector_num,
203 &acb->copy.qiov, acb->nb_sectors,
204 finish_prefetch_read, acb);
207 if (acb->copy.hd_acb == NULL) {
208 QDEBUG ("PREFETCH: error when starting read for sector_num=%" PRId64
209 " nb_sectors=%d\n", acb->sector_num, acb->nb_sectors);
210 s->prefetch_error = TRUE;
211 s->prefetch_state = PREFETCH_STATE_DISABLED;
212 if (s->num_filled_prefetch_slots == 0) {
213 terminate_prefetch (bs, PREFETCH_STATE_DISABLED);
215 } else {
216 s->prefetch_read_active = TRUE;
217 QDEBUG ("PREFETCH: start read for sector_num=%" PRId64
218 " nb_sectors=%d total_prefetched_bytes=%" PRId64 "\n",
219 acb->sector_num, acb->nb_sectors, s->total_prefetch_data);
220 #ifdef FVD_DEBUG
221 s->total_prefetch_data += acb->copy.iov.iov_len;
222 #endif
226 static void finish_prefetch_write (void *opaque, int ret)
228 FvdAIOCB *acb = (FvdAIOCB *) opaque;
229 BlockDriverState *bs = acb->common.bs;
230 BDRVFvdState *s = bs->opaque;
231 int64_t begin, end;
232 const int64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
234 ASSERT (acb->nb_sectors > 0 && s->num_filled_prefetch_slots > 0);
236 QLIST_REMOVE (acb, copy_lock.next);
237 restart_dependent_writes (acb);
238 acb->copy.hd_acb = NULL;
239 QLIST_INIT (&acb->copy_lock.dependent_writes);
241 if (ret != 0) {
242 QDEBUG ("PREFETCH: finished write with error for sector_num=%" PRId64
243 " nb_sectors=%d\n", acb->sector_num, acb->nb_sectors);
244 s->num_filled_prefetch_slots = 0;
245 s->prefetch_error = TRUE;
246 s->prefetch_state = PREFETCH_STATE_DISABLED;
247 if (!s->prefetch_read_active) {
248 terminate_prefetch (bs, PREFETCH_STATE_DISABLED);
250 return;
253 /* No need to update the on-disk bitmap or the stale bitmap. See Section
254 * 3.3.4 of the FVD-cow paper. */
255 update_fresh_bitmap (acb->sector_num, acb->nb_sectors, s);
257 const int64_t write_time =
258 current_time - acb->copy.last_prefetch_op_start_time;
259 s->prefetch_write_time += write_time;
260 s->prefetch_data_written += acb->nb_sectors * 512;
262 QDEBUG ("PREFETCH: write_finished sector_num=%" PRId64
263 " nb_sectors=%d write_time=%d (ms)\n", acb->sector_num,
264 acb->nb_sectors, (int) write_time);
266 /* Calculate throughput and determine if it needs to pause prefetching due
267 * to low throughput. */
268 if (s->prefetch_timer && s->prefetch_throttle_time > 0
269 && !s->pause_prefetch_requested
270 && s->prefetch_write_time > s->prefetch_write_throughput_measure_time) {
271 const double this_round_throughput =
272 s->prefetch_data_written / (double) s->prefetch_write_time;
273 if (s->prefetch_write_throughput < 0) {
274 /* Previously not initialized. */
275 s->prefetch_write_throughput = this_round_throughput;
276 } else {
277 s->prefetch_write_throughput =
278 s->prefetch_perf_calc_alpha * s->prefetch_write_throughput +
279 (1 - s->prefetch_perf_calc_alpha) * this_round_throughput;
281 if (s->prefetch_write_throughput < s->prefetch_min_write_throughput) {
282 QDEBUG ("PREFETCH: slow_write this_write=%d (ms) "
283 "this_write_throughput=%.3lf (MB/s) "
284 "avg_write_throughput=%.3lf (MB/s)\n",
285 (int) write_time,
286 this_round_throughput / 1048576 * 1000,
287 s->prefetch_write_throughput / 1048576 * 1000);
289 /* Make a randomized decision to pause prefetching. This avoids
290 * pausing all contending FVD drivers. See Section 3.4.2 of the
291 * FVD-cow paper. */
292 if (random () > (RAND_MAX / 2)) {
293 QDEBUG ("PREFETCH: pause requested.\n");
294 s->pause_prefetch_requested = TRUE;
295 } else {
296 QDEBUG ("PREFETCH: continue due to 50%% probability, despite "
297 "slow write.\n");
298 s->prefetch_write_throughput = -1; /*Indicate not initialized.*/
300 } else {
301 QDEBUG ("PREFETCH: this_write_throughput=%.3lf (MB/s) "
302 "avg_write_throughput=%.3lf (MB/s)\n",
303 this_round_throughput / 1048576 * 1000,
304 s->prefetch_write_throughput / 1048576 * 1000);
307 /* Preparing for measuring the next round of throughput. */
308 s->prefetch_data_written = 0;
309 s->prefetch_write_time = 0;
312 /* Find in this prefetch slot the next section of prefetched but
313 * not-yet-written data. */
314 begin = acb->sector_num + acb->nb_sectors;
315 if (begin < acb->copy.buffered_sector_end) {
316 end = acb->copy.buffered_sector_end;
317 if (find_region_in_base_img (s, &begin, &end)) {
318 acb->sector_num = begin;
319 acb->nb_sectors = end - begin;
320 acb->copy.iov.iov_base = acb->copy.buf +
321 (begin - acb->copy.buffered_sector_begin) * 512;
322 acb->copy.qiov.size = acb->copy.iov.iov_len = acb->nb_sectors * 512;
323 QDEBUG ("PREFETCH: write_data sector_num=%" PRId64
324 " nb_sectors=%d\n", acb->sector_num, acb->nb_sectors);
325 acb->copy.hd_acb = store_data (TRUE, acb, bs, acb->sector_num,
326 &acb->copy.qiov, acb->nb_sectors,
327 finish_prefetch_write, acb);
328 if (acb->copy.hd_acb == NULL) {
329 QDEBUG ("PREFETCH: error in starting bdrv_aio_writev().\n");
330 s->num_filled_prefetch_slots = 0;
331 s->prefetch_error = TRUE;
332 s->prefetch_state = PREFETCH_STATE_DISABLED;
333 if (!s->prefetch_read_active) {
334 terminate_prefetch (bs, PREFETCH_STATE_DISABLED);
336 } else {
337 acb->copy_lock.begin = begin;
338 acb->copy_lock.end = end;
339 QLIST_INSERT_HEAD (&s->copy_locks, acb, copy_lock.next);
342 return;
346 s->num_filled_prefetch_slots--;
348 if (s->prefetch_state == PREFETCH_STATE_DISABLED) {
349 if (s->num_filled_prefetch_slots == 0 && !s->prefetch_read_active) {
350 terminate_prefetch (bs, PREFETCH_STATE_DISABLED);
352 return;
355 if (begin >= s->nb_sectors_in_base_img) {
356 /* Prefetching finished. */
357 ASSERT (s->num_filled_prefetch_slots == 0 && !s->prefetch_read_active);
358 terminate_prefetch (bs, PREFETCH_STATE_FINISHED);
359 return;
362 if (s->pause_prefetch_requested) {
363 if (s->num_filled_prefetch_slots == 0) {
364 if (!s->prefetch_read_active) {
365 pause_prefetch (s);
366 } else {
367 QDEBUG ("PREFETCH: wait for the read operation to finish in "
368 "order to pause prefetch.\n");
370 return;
374 /* Write out data in the next prefetched slot. */
375 while (s->num_filled_prefetch_slots > 0) {
376 int k = s->next_prefetch_read_slot - s->num_filled_prefetch_slots;
377 if (k < 0) {
378 k += s->num_prefetch_slots;
380 acb = s->prefetch_acb[k];
382 int64_t begin = acb->copy.buffered_sector_begin;
383 int64_t end = acb->copy.buffered_sector_end;
384 if (find_region_in_base_img (s, &begin, &end)) {
385 acb->copy.last_prefetch_op_start_time = current_time;
386 acb->sector_num = begin;
387 acb->nb_sectors = end - begin;
388 acb->copy.iov.iov_base =
389 acb->copy.buf + (begin - acb->copy.buffered_sector_begin) * 512;
390 acb->copy.qiov.size = acb->copy.iov.iov_len = acb->nb_sectors * 512;
391 QDEBUG ("PREFETCH: writes data: sector_num=%" PRId64
392 " nb_sectors=%d\n", acb->sector_num, acb->nb_sectors);
393 acb->copy.hd_acb = store_data (TRUE, acb, bs, acb->sector_num,
394 &acb->copy.qiov, acb->nb_sectors,
395 finish_prefetch_write, acb);
397 if (acb->copy.hd_acb == NULL) {
398 QDEBUG ("PREFETCH: error cannot get a control block to write "
399 "a prefetched block.\n");
400 s->prefetch_error = TRUE;
401 s->prefetch_state = PREFETCH_STATE_DISABLED;
402 s->num_filled_prefetch_slots = 0;
403 if (!s->prefetch_read_active) {
404 terminate_prefetch (bs, PREFETCH_STATE_DISABLED);
406 return;
409 acb->copy_lock.begin = begin;
410 acb->copy_lock.end = end;
411 QLIST_INSERT_HEAD (&s->copy_locks, acb, copy_lock.next);
412 break;
413 } else {
414 QDEBUG ("PREFETCH: discard prefetched data as they have been "
415 "covered: sector_num=%" PRId64 " nb_sectors=%d\n",
416 acb->sector_num, acb->nb_sectors);
417 s->num_filled_prefetch_slots--;
421 /* If the reader was stopped due to lack of slots, start the reader. */
422 if (!s->prefetch_read_active && !s->pause_prefetch_requested) {
423 do_next_prefetch_read (bs, current_time);
427 static void finish_prefetch_read (void *opaque, int ret)
429 FvdAIOCB *acb = (FvdAIOCB *) opaque;
430 BlockDriverState *bs = acb->common.bs;
431 BDRVFvdState *s = bs->opaque;
433 ASSERT (s->prefetch_read_active && s->num_filled_prefetch_slots >= 0
434 && s->num_filled_prefetch_slots < s->num_prefetch_slots);
436 s->prefetch_read_active = FALSE;
437 acb->copy.hd_acb = NULL;
439 if (s->prefetch_state == PREFETCH_STATE_DISABLED) {
440 if (s->num_filled_prefetch_slots == 0) {
441 terminate_prefetch (bs, PREFETCH_STATE_DISABLED);
443 return;
446 if (ret != 0) {
447 QDEBUG ("PREFETCH: read_error sector_num=%" PRId64 " nb_sectors=%d.\n",
448 acb->sector_num, acb->nb_sectors);
449 s->prefetch_error = TRUE;
450 s->prefetch_state = PREFETCH_STATE_DISABLED;
451 if (s->num_filled_prefetch_slots == 0) {
452 terminate_prefetch (bs, PREFETCH_STATE_DISABLED);
454 return;
457 const int64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
458 const int64_t read_time = current_time -
459 acb->copy.last_prefetch_op_start_time;
460 s->prefetch_read_time += read_time;
461 s->prefetch_data_read += acb->nb_sectors * 512;
463 QDEBUG ("PREFETCH: read_finished sector_num=%" PRId64
464 " nb_sectors=%d read_time=%d (ms)\n", acb->sector_num,
465 acb->nb_sectors, (int) read_time);
467 /* Calculate throughput and determine if it needs to pause prefetching due
468 * to low throughput. */
469 if (s->prefetch_timer && s->prefetch_throttle_time > 0
470 && !s->pause_prefetch_requested
471 && s->prefetch_read_time > s->prefetch_read_throughput_measure_time) {
472 const double this_round_throughput =
473 s->prefetch_data_read / (double) s->prefetch_read_time;
474 if (s->prefetch_read_throughput < 0) {
475 /* Previously not initialized. */
476 s->prefetch_read_throughput = this_round_throughput;
477 } else {
478 s->prefetch_read_throughput = s->prefetch_perf_calc_alpha *
479 s->prefetch_read_throughput +
480 (1 - s->prefetch_perf_calc_alpha) * this_round_throughput;
482 if (s->prefetch_read_throughput < s->prefetch_min_read_throughput) {
483 QDEBUG ("PREFETCH: slow_read read_time=%d (ms) "
484 "this_read_throughput=%.3lf (MB/s) "
485 "avg_read_throughput=%.3lf (MB/s)\n",
486 (int) read_time, this_round_throughput / 1048576 * 1000,
487 s->prefetch_read_throughput / 1048576 * 1000);
489 /* Make a randomized decision to pause prefetching. This avoids
490 * pausing all contending FVD drivers. See Section 3.4.2 of the
491 * FVD-cow paper. */
492 if (random () > (RAND_MAX / 2)) {
493 QDEBUG ("PREFETCH: pause requested.\n");
494 s->pause_prefetch_requested = TRUE;
495 } else {
496 QDEBUG ("PREFETCH: continue due to 50%% probability, "
497 "despite slow read.\n");
498 s->prefetch_read_throughput = -1; /*Indicate not initialized.*/
500 } else {
501 QDEBUG ("PREFETCH: this_read_throughput=%.3lf (MB/s) "
502 "avg_read_throughput=%.3lf (MB/s)\n",
503 this_round_throughput / 1048576 * 1000,
504 s->prefetch_read_throughput / 1048576 * 1000);
507 /* Preparing for measuring the next round of throughput. */
508 s->prefetch_data_read = 0;
509 s->prefetch_read_time = 0;
512 if (s->num_filled_prefetch_slots > 0) {
513 /* There is one ongoing write for prefetched data. This slot will be
514 * written out later. */
515 s->num_filled_prefetch_slots++;
516 s->next_prefetch_read_slot++;
517 if (s->next_prefetch_read_slot >= s->num_prefetch_slots) {
518 s->next_prefetch_read_slot = 0;
520 } else {
521 /* The writer is not active. Start the writer. */
522 int64_t begin = acb->copy.buffered_sector_begin;
523 int64_t end = acb->copy.buffered_sector_end;
524 if (find_region_in_base_img (s, &begin, &end)) {
525 acb->copy.last_prefetch_op_start_time = current_time;
526 acb->sector_num = begin;
527 acb->nb_sectors = end - begin;
528 acb->copy.iov.iov_base =
529 acb->copy.buf + (begin - acb->copy.buffered_sector_begin) * 512;
530 acb->copy.qiov.size = acb->copy.iov.iov_len = acb->nb_sectors * 512;
531 QDEBUG ("PREFETCH: writes_data sector_num=%" PRId64
532 " nb_sectors=%d\n", acb->sector_num, acb->nb_sectors);
533 acb->copy.hd_acb = store_data (TRUE, acb, bs, acb->sector_num,
534 &acb->copy.qiov, acb->nb_sectors,
535 finish_prefetch_write, acb);
537 if (acb->copy.hd_acb == NULL) {
538 QDEBUG ("PREFETCH: error cannot get control block to write a "
539 "prefetched block.\n");
540 s->prefetch_error = TRUE;
541 s->prefetch_state = PREFETCH_STATE_DISABLED;
542 if (s->num_filled_prefetch_slots == 0) {
543 terminate_prefetch (bs, PREFETCH_STATE_DISABLED);
545 return;
548 acb->copy_lock.begin = begin;
549 acb->copy_lock.end = end;
550 QLIST_INSERT_HEAD (&s->copy_locks, acb, copy_lock.next);
551 s->num_filled_prefetch_slots++;
552 s->next_prefetch_read_slot++;
553 if (s->next_prefetch_read_slot >= s->num_prefetch_slots) {
554 s->next_prefetch_read_slot = 0;
556 } else {
557 /* The current prefetch slot will be reused to prefetch the next
558 * bunch of data. */
559 QDEBUG ("PREFETCH: discard prefetched data as they have been "
560 "covered: sector_num=%" PRId64 " nb_sectors=%d\n",
561 acb->sector_num, acb->nb_sectors);
565 if (s->num_filled_prefetch_slots >= s->num_prefetch_slots) {
566 QDEBUG ("PREFETCH: halt read because no slot is available.\n");
567 } else {
568 if (s->pause_prefetch_requested) {
569 if (s->num_filled_prefetch_slots == 0) {
570 pause_prefetch (s);
572 } else {
573 do_next_prefetch_read (bs, current_time);
578 static void resume_prefetch (BlockDriverState * bs, int64_t current_time)
580 BDRVFvdState *s = bs->opaque;
582 if (s->prefetch_state != PREFETCH_STATE_RUNNING) {
583 return;
586 ASSERT (s->num_filled_prefetch_slots == 0 && !s->prefetch_read_active);
587 QDEBUG ("PREFETCH: resume.\n");
589 s->pause_prefetch_requested = FALSE;
590 s->prefetch_read_throughput = -1; /* Indicate not initialized. */
591 s->prefetch_write_throughput = -1; /* Indicate not initialized. */
592 s->prefetch_read_time = 0;
593 s->prefetch_write_time = 0;
594 s->prefetch_data_read = 0;
595 s->prefetch_data_written = 0;
597 do_next_prefetch_read (bs, qemu_clock_get_ns(QEMU_CLOCK_REALTIME));