Skip to content

Commit d7abeef

Browse files
markjdbbehlendorf
authored andcommitted
zio: Avoid sleeping in the I/O path
zio_delay_interrupt(), apparently used for fault injection, is executed in the I/O pipeline. It can cause the calling thread to go to sleep, which is not allowed on FreeBSD. This happens only for small delays, though, and there's no apparent reason to avoid deferring to a taskqueue in that case, as it already does otherwise. Simply go to sleep unconditionally. This fixes an occasional panic I see when running the ZTS on FreeBSD. Also remove an unhelpful comment referencing the non-existent timeout_generic(). Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Signed-off-by: Mark Johnston <[email protected]> Closes openzfs#16785
1 parent 7fb7eb9 commit d7abeef

File tree

1 file changed

+8
-19
lines changed

1 file changed

+8
-19
lines changed

module/zfs/zio.c

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,31 +2192,20 @@ zio_delay_interrupt(zio_t *zio)
21922192
} else {
21932193
taskqid_t tid;
21942194
hrtime_t diff = zio->io_target_timestamp - now;
2195-
clock_t expire_at_tick = ddi_get_lbolt() +
2196-
NSEC_TO_TICK(diff);
2195+
int ticks = MAX(1, NSEC_TO_TICK(diff));
2196+
clock_t expire_at_tick = ddi_get_lbolt() + ticks;
21972197

21982198
DTRACE_PROBE3(zio__delay__hit, zio_t *, zio,
21992199
hrtime_t, now, hrtime_t, diff);
22002200

2201-
if (NSEC_TO_TICK(diff) == 0) {
2202-
/* Our delay is less than a jiffy - just spin */
2203-
zfs_sleep_until(zio->io_target_timestamp);
2204-
zio_interrupt(zio);
2205-
} else {
2201+
tid = taskq_dispatch_delay(system_taskq, zio_interrupt,
2202+
zio, TQ_NOSLEEP, expire_at_tick);
2203+
if (tid == TASKQID_INVALID) {
22062204
/*
2207-
* Use taskq_dispatch_delay() in the place of
2208-
* OpenZFS's timeout_generic().
2205+
* Couldn't allocate a task. Just finish the
2206+
* zio without a delay.
22092207
*/
2210-
tid = taskq_dispatch_delay(system_taskq,
2211-
zio_interrupt, zio, TQ_NOSLEEP,
2212-
expire_at_tick);
2213-
if (tid == TASKQID_INVALID) {
2214-
/*
2215-
* Couldn't allocate a task. Just
2216-
* finish the zio without a delay.
2217-
*/
2218-
zio_interrupt(zio);
2219-
}
2208+
zio_interrupt(zio);
22202209
}
22212210
}
22222211
return;

0 commit comments

Comments
 (0)