Set the I/O scheduler based on file system type?

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?

What if there are multiple filesystems on a device?

What if there are multiple filesystems on a device?

That falls under the scope of my question.

Maybe I’m just missing something. What would you want to happen if one partition is xfs and another btrfs?

Maybe I’m just missing something. What would you want to happen if one partition is xfs and another btrfs?

I appreciate your question. It is what I am asking too.

Here is an example of a filesystem specific rule:
systemd/64-btrfs.rules.in at main · systemd/systemd · GitHub

Maybe I’m just missing something. What would you want to happen if one partition is xfs and another btrfs?

Consider VM hosts where the guests are using different file system types.

I think there are more issues. Consider LVM where the same partition could have multiple logical volumes with different file system types.

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.

Currently the rule is:

ACTION=="add", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", \
  KERNEL=="mmcblk*[0-9]|msblk*[0-9]|mspblk*[0-9]|sd*[!0-9]|sr*", \
  ATTR{queue/scheduler}="bfq"

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.

2 Likes