STRUCT BFQ_SCHED_DATA(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ‘‘ struct bfq_sched_data β€” multi-class scheduler

okay so bestie, we're in the Kernel API Manual today and the star of the show is struct bfq_sched_data. it's giving scheduler royalty, no cap. let's get into it πŸ’…


✨ SYNOPSIS ✨

struct bfq_sched_data {
    struct bfq_entity *in_service_entity;
    struct bfq_entity *next_in_service;
    struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES];
    unsigned long bfq_class_idle_last_service;
 };

🫢 Members

  • in_service_entity β€” a struct bfq_entity *, the entity that's currently, y'know, in service. main character energy fr.
  • next_in_service β€” a struct bfq_entity * that points to the entity on the active trees who's up next, but only if a whole list of conditions holds (more on that below, don't worry 🫢).
  • service_tree β€” a struct bfq_service_tree array sized [BFQ_IOPRIO_CLASSES]. this is where the scheduling actually gets implemented. iconic.
  • bfq_class_idle_last_service β€” an unsigned long. honestly? the page does not spill the tea on what this one does. it's just here, living its life 🌸.

πŸ’– DESCRIPTION πŸ’–

so bfq_sched_data is the basic scheduler queue. it supports three ioprio_classes, and it's flexible like that β€” you can use it either as a toplevel queue or as an intermediate queue in a hierarchical setup. versatile queen πŸ‘‘.

the supported ioprio_classes are literally the same ones as in CFQ, listed in descending priority order:

  1. IOPRIO_CLASS_RT
  2. IOPRIO_CLASS_BE
  3. IOPRIO_CLASS_IDLE

requests from higher priority queues get served before all the requests from lower priority queues β€” periodt. and among requests of the same queue? those get served according to B-WF2Q+. iykyk ✨


🌈 how the schedule actually works

the schedule is implemented by the service trees, plus the next_in_service field. that field points to the entity on the active trees that will be served next β€” but only if all three of these are true, so pay attention bestie:

  1. no changes in the schedule occur before the current in-service entity is expired,
  2. the in-service queue becomes idle when it expires, and
  3. if the entity pointed by in_service_entity is not a queue, then the in-service child entity of the entity pointed by in_service_entity becomes idle on expiration.
this is a peculiar definition β€” that's the page's word, not mine β€” and the reason it's defined this way is that it allows for the following optimization, not yet exploited: while a given entity is still in service, we already know which is the best candidate for next service among the other active entities in the same parent entity. so we can then quickly compare the timestamps of the in-service entity with those of such best candidate. lowkey genius, highkey underused 😭

πŸ”’ locking, bestie

all fields are protected by the lock of the containing bfqd. every single one. do not come for them without the lock, i'm serious πŸ™ˆ


πŸ”₯ SEE ALSO πŸ”₯

  • Kernel file ./block/bfq-iosched.h
  • struct bfq_service_tree(9)
  • struct bfq_weight_counter(9)
  • struct bfq_entity(9)
  • struct bfq_ttime(9)
  • struct bfq_queue(9)
  • struct bfq_io_cq(9)
  • struct bfq_data(9)
  • struct bfq_group(9)

and that's the whole vibe check πŸ¦‹ this page lives in ./block, it's dated October 2026, and it's filed under struct bfq_sched_data(9). go read the whole family, they're all linked above. mwah πŸ’‹πŸŽ€

πŸ“¦ where this page comes from