How can I use BFQ IO scheduler w/ 4.12?

I was looking forward to Kernel 4.12 because BFQ was finally pulled in. Any I/O operation might go plenty fast but locks up my machine in the meantime (BTRFS balance is a major culprit, but other operations do the same). Deadline/NOOP/CFQ all seem to be about the same.

I have not been able to figure out how to enable BFQ. Going through the kernel settings GUI, I can still only see Deadline/NOOP/CFQ. Some sites I have seen reference changing settings in GRUB, etc. to enable it, but these are all pre-4.12 kernels, which I would imagine would be different.

I have also tried installing a BFQ package from the repos, but that didn’t seem to do anything.

How do I get BFQ working?

It’s not enabled by default, fire up YaST bootloader and in the kernel options add after quiet;


Reboot and you should see for example on sda;

cat /sys/block/sda/queue/scheduler
[mq-deadline] kyber bfq none

You will then need to write a udev rule to suit your needs living in /etc/udev/rules.d…

Look at /lib/udev/rules.d/60-ssd-scheduler.rules for an example.

Thanks malcolmlewis, this is far simpler than some of the other ideas I came across.

I am still struggling with the udev rules aspect. I can see what is in the example file you pointed out. However, i am not sure which parts of it to copy. From my understanding, I should:

  1. Clone that example file with some new name into the same directory it is currently in
  2. remove everything extra
  3. Change the scheduler (currently set to deadline) to bfq

Step 2 is where I am a little unsure…what parts of the example should I keep? Or is it enough to actually modify the existing example file?

Thanks again!

Put the file in the /etc/udev/rules.d/ directory since your adding it, then it won’t get touched :wink:


cat /sys/block/sda/queue/scheduler
mq-deadline kyber [bfq] none

cat /sys/block/sdb/queue/scheduler
mq-deadline kyber [bfq] none


vi /etc/udev/rules.d/61-bfq-scheduler.rules

### Rule start ###
ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="0", ATTR{queue/scheduler}="bfq"

ACTION=="add|change", KERNEL=="sd[a-z]", ATTR{queue/rotational}=="1", ATTR{queue/scheduler}="mq-deadline"
### Rule end ###

udevadm control --reload
udevadm trigger

cat /sys/block/sda/queue/scheduler
mq-deadline kyber [bfq] none

cat /sys/block/sdb/queue/scheduler
[mq-deadline] kyber bfq none

Or which ever scheduler you want to use, you can set specific ones for specific disks and types, setting the name beginning with 61 will run after the system one. Check it’s all working after a reboot as well.

Awesome, this did the trick! Thank you for your help…now time to see if this makes any difference in my system.

So the setting for “rotational” with the “1” flag…my understanding is that this is what scheduler will apply to devices loaded after startup, say a flash drive or SD card? And the “0” flag will apply for boot devices?

Well yes and no, the attribute is set in queue/rotational so if it is ‘0’ it’s an SSD, if ‘1’ its rotating rust. No reason you can set both to the same scheduler or don’t use that attribute and only have one line setting all disks :wink:

Got it, so the “rotational” simply means “HDD”. Thanks for clearing that up.