I recently found out that btrfs is slightly faster when the I/O schedule is set to “none”.
I started testing by setting the I/O scheduler on the command line: echo none > /sys/block/sda/queue/scheduler
Once I was satisfied that there was an improvement, I added it to the system startup:
# sed 's;bfq;none;' /usr/lib/udev/rules.d/60-block-scheduler.rules \
> /etc/udev/rules.d/90-ioschedulers.rules
But then I thought that if this is a btrfs issue, all disks should not have to be set to the same scheduler. A udev rule should set the scheduler based on file system type.
How can I set I/O scheduler based on file system type?
IO scheduler decision is mainly based on the workload and the hardware. Multiqueue hardware includes most newer SSDs and all NVMe drives. Single queue include USB and rotating drives. For multiqueue use mq-deadline or none. Certain very high performance NVMe drives, and write centric workloads, benefit from kyber. And single queue or rotational devices benefit from bfq.
Fedora’s IO scheduler defaults are in /usr/lib/udev/rules.d/60-block-scheduler.rules and can be overridden by putting a rule in /etc.
This rule currently does not check sysfs to see if the device is rotating or not.
A draft idea for changing the behavior:
#Most things will use mq-deadline, including flash drives that often lie that they are rotational
ACTION=="add", SUBSYSTEM=="block", \
KERNEL=="hd*[!0-9]|mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|sd*[!0-9]|nvme*", \
ATTR{queue/scheduler}="mq-deadline"
#Only drives that tend to reliably report rotational, and do report rotational, will use BFQ.
ACTION=="add", SUBSYSTEM=="block", \
KERNEL=="hd*[!0-9]|sd*[!0-9]|sr*", \
ATTR{queue/rotational}=="1", \
ATTR{queue/scheduler}="bfq"
Other possibilities: Omit nvme from the above list, thereby keeping its IO scheduler as none. Only use bfq for hd* sd* sr* when rotational; but understand that rotational i information is often misreported or lost with some (USB SATA) bridge chipsets.