mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 18:40:43 +03:00
Support re-prioritizing asynchronous prefetches
When sequential scrubs were merged, all calls to arc_read() (including prefetch IOs) were given ZIO_PRIORITY_ASYNC_READ. Unfortunately, this behaves badly with an existing issue where prefetch IOs cannot be re-prioritized after the issue. The result is that synchronous reads end up in the same vdev_queue as the scrub IOs and can have (in some workloads) multiple seconds of latency. This patch incorporates 2 changes. The first ensures that all scrub IOs are given ZIO_PRIORITY_SCRUB to allow the vdev_queue code to differentiate between these I/Os and user prefetches. Second, this patch introduces zio_change_priority() to provide the missing capability to upgrade a zio's priority. Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Tom Caputi <tcaputi@datto.com> Closes #6921 Closes #6926
This commit is contained in:
committed by
Brian Behlendorf
parent
993669a7bf
commit
a8b2e30685
@@ -803,6 +803,48 @@ vdev_queue_io_done(zio_t *zio)
|
||||
mutex_exit(&vq->vq_lock);
|
||||
}
|
||||
|
||||
void
|
||||
vdev_queue_change_io_priority(zio_t *zio, zio_priority_t priority)
|
||||
{
|
||||
vdev_queue_t *vq = &zio->io_vd->vdev_queue;
|
||||
avl_tree_t *tree;
|
||||
|
||||
ASSERT3U(zio->io_priority, <, ZIO_PRIORITY_NUM_QUEUEABLE);
|
||||
ASSERT3U(priority, <, ZIO_PRIORITY_NUM_QUEUEABLE);
|
||||
|
||||
if (zio->io_type == ZIO_TYPE_READ) {
|
||||
if (priority != ZIO_PRIORITY_SYNC_READ &&
|
||||
priority != ZIO_PRIORITY_ASYNC_READ &&
|
||||
priority != ZIO_PRIORITY_SCRUB)
|
||||
priority = ZIO_PRIORITY_ASYNC_READ;
|
||||
} else {
|
||||
ASSERT(zio->io_type == ZIO_TYPE_WRITE);
|
||||
if (priority != ZIO_PRIORITY_SYNC_WRITE &&
|
||||
priority != ZIO_PRIORITY_ASYNC_WRITE)
|
||||
priority = ZIO_PRIORITY_ASYNC_WRITE;
|
||||
}
|
||||
|
||||
mutex_enter(&vq->vq_lock);
|
||||
|
||||
/*
|
||||
* If the zio is in none of the queues we can simply change
|
||||
* the priority. If the zio is waiting to be submitted we must
|
||||
* remove it from the queue and re-insert it with the new priority.
|
||||
* Otherwise, the zio is currently active and we cannot change its
|
||||
* priority.
|
||||
*/
|
||||
tree = vdev_queue_class_tree(vq, zio->io_priority);
|
||||
if (avl_find(tree, zio, NULL) == zio) {
|
||||
avl_remove(vdev_queue_class_tree(vq, zio->io_priority), zio);
|
||||
zio->io_priority = priority;
|
||||
avl_add(vdev_queue_class_tree(vq, zio->io_priority), zio);
|
||||
} else if (avl_find(&vq->vq_active_tree, zio, NULL) != zio) {
|
||||
zio->io_priority = priority;
|
||||
}
|
||||
|
||||
mutex_exit(&vq->vq_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* As these two methods are only used for load calculations we're not
|
||||
* concerned if we get an incorrect value on 32bit platforms due to lack of
|
||||
|
||||
Reference in New Issue
Block a user