Skip to content

Commit

Permalink
thinktime: Avoid calculating a negative time left to wait
Browse files Browse the repository at this point in the history
When the thinktime_spin option specifies a value that is within
a few milliseconds of the thinktime value, in handle_thinktime()
it's possible in a VM environment for the duration of usec_spin()
to exceed the thinktime value. While doing usec_spin(), the vCPU
could get de-scheduled or the hypervisor could steal CPU time
from the vCPU. When the guest vCPU runs after being scheduled
again, it may read the clock and find that more time has elapsed
than intended. In such a case, the time left to wait could be
calculated as a negative value. Subsequent calculations then go
awry because the time left is cast as unsigned.

Fix this by detecting when the time left would go negative and
just set it to zero.

Fixes: 1a9bf81 ("Add option to ignore thinktime for rated IO")
Fixes: #1588
Link: https://lore.kernel.org/fio/1689354334-131024-1-git-send-email-mikelley@microsoft.com/T/#u
Signed-off-by: Michael Kelley <mikelley@microsoft.com>
Signed-off-by: Vincent Fu <vincent.fu@samsung.com>
  • Loading branch information
kelleymh authored and vincentkfu committed Jul 14, 2023
1 parent bb08a26 commit 14adf6e
Showing 1 changed file with 10 additions and 1 deletion.
11 changes: 10 additions & 1 deletion backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,16 @@ static void handle_thinktime(struct thread_data *td, enum fio_ddir ddir,
if (left)
total = usec_spin(left);

left = td->o.thinktime - total;
/*
* usec_spin() might run for slightly longer than intended in a VM
* where the vCPU could get descheduled or the hypervisor could steal
* CPU time. Ensure "left" doesn't become negative.
*/
if (total < td->o.thinktime)
left = td->o.thinktime - total;
else
left = 0;

if (td->o.timeout) {
runtime_left = td->o.timeout - utime_since_now(&td->epoch);
if (runtime_left < (unsigned long long)left)
Expand Down

0 comments on commit 14adf6e

Please sign in to comment.