2 * Copyright (c) 2010-2011 IBM
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.
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
;
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 ());
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
);
41 s
->prefetch_error
= TRUE
;
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
;
51 "qemu_aio_get() failed and cannot start prefetching.\n");
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
;
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
);
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
;
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
;
131 s
->prefetch_state
= PREFETCH_STATE_FINISHED
;
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. */
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
)
165 BDRVFvdState
*s
= bs
->opaque
;
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
;
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
);
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
)) {
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
);
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
);
221 s
->total_prefetch_data
+= acb
->copy
.iov
.iov_len
;
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
;
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
);
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
);
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
;
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",
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
292 if (random () > (RAND_MAX
/ 2)) {
293 QDEBUG ("PREFETCH: pause requested.\n");
294 s
->pause_prefetch_requested
= TRUE
;
296 QDEBUG ("PREFETCH: continue due to 50%% probability, despite "
298 s
->prefetch_write_throughput
= -1; /*Indicate not initialized.*/
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
);
337 acb
->copy_lock
.begin
= begin
;
338 acb
->copy_lock
.end
= end
;
339 QLIST_INSERT_HEAD (&s
->copy_locks
, acb
, copy_lock
.next
);
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
);
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
);
362 if (s
->pause_prefetch_requested
) {
363 if (s
->num_filled_prefetch_slots
== 0) {
364 if (!s
->prefetch_read_active
) {
367 QDEBUG ("PREFETCH: wait for the read operation to finish in "
368 "order to pause prefetch.\n");
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
;
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
);
409 acb
->copy_lock
.begin
= begin
;
410 acb
->copy_lock
.end
= end
;
411 QLIST_INSERT_HEAD (&s
->copy_locks
, acb
, copy_lock
.next
);
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
);
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
);
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
;
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
492 if (random () > (RAND_MAX
/ 2)) {
493 QDEBUG ("PREFETCH: pause requested.\n");
494 s
->pause_prefetch_requested
= TRUE
;
496 QDEBUG ("PREFETCH: continue due to 50%% probability, "
497 "despite slow read.\n");
498 s
->prefetch_read_throughput
= -1; /*Indicate not initialized.*/
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;
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
);
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;
557 /* The current prefetch slot will be reused to prefetch the next
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");
568 if (s
->pause_prefetch_requested
) {
569 if (s
->num_filled_prefetch_slots
== 0) {
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
) {
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
));