Set the 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.

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.