STRUCT BLK_MQ_HW_CTX(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

πŸ’… struct blk_mq_hw_ctx(9) β€” the Kernel API Manual, bestie edition

okay so picture this: it's struct blk_mq_hw_ctx(9), from the Kernel API Manual, and it's literally the state for a hardware queue facing the hardware block device. like, the whole vibe of one hardware queue, tracked in one struct. iconic behavior honestly πŸŽ€


✨ SYNOPSIS ✨

struct blk_mq_hw_ctx {
    struct {
      spinlock_t lock;
      struct list_head        dispatch;
      unsigned long           state;
    };
    struct delayed_work     run_work;
    cpumask_var_t cpumask;
    int next_cpu;
    int next_cpu_batch;
    unsigned long           flags;
    void *sched_data;
    struct request_queue    *queue;
    struct blk_flush_queue  *fq;
    void *driver_data;
    struct sbitmap          ctx_map;
    struct blk_mq_ctx       *dispatch_from;
    unsigned int            dispatch_busy;
    unsigned short          type;
    unsigned short          nr_ctx;
    struct blk_mq_ctx       **ctxs;
    spinlock_t dispatch_wait_lock;
    wait_queue_entry_t dispatch_wait;
    atomic_t wait_index;
    struct blk_mq_tags      *tags;
    struct blk_mq_tags      *sched_tags;
    int numa_node;
    unsigned int            queue_num;
    atomic_t nr_active;
    struct hlist_node       cpuhp_online;
    struct hlist_node       cpuhp_dead;
    struct kobject          kobj;
  #ifdef CONFIG_BLK_DEBUG_FS;
    struct dentry           *debugfs_dir;
    struct dentry           *sched_debugfs_dir;
  #endif;
    struct list_head        hctx_list;
 };

🌸 Members 🌸

okay this is the part where we go field by field, no skipping, no cap πŸ’–

  • {unnamed_struct} β€” anonymous. yeah she's just... there. mysterious. we don't ask questions 🫢

πŸ¦‹ the dispatch trio (the anonymous struct crew)

  • lock β€” protects the dispatch list. that's it, that's her job. bodyguard energy.
  • dispatch β€” for requests that are ready to be dispatched to the hardware but for some reason (e.g. lack of resources) could not be sent to the hardware. and the moment the driver can send new requests, requests at this list get sent first, for a fairer dispatch. so it's like the VIP holding area but make it fair ⭐
  • state β€” BLK_MQ_S_* flags. defines the state of the hw queue (active, scheduled to restart, stopped). it's giving status update.

🌈 scheduling & CPU stuff

  • run_work β€” used for scheduling a hardware queue run at a later time. procrastination, but make it kernel-legal.
  • cpumask β€” map of available CPUs where this hctx can run.
  • next_cpu β€” used by blk_mq_hctx_next_cpu for round-robin CPU selection from cpumask. taking turns, as one does πŸ’…
  • next_cpu_batch β€” counter of how many works left in the batch before changing to the next CPU. the countdown, basically.
  • flags β€” BLK_MQ_F_* flags. defines the behaviour of the queue. her personality traits.

πŸŽ€ pointers & ownership

  • sched_data β€” pointer owned by the IO scheduler attached to a request queue. it's up to the IO scheduler how to use this pointer. not our business, not our problem πŸ™ˆ
  • queue β€” pointer to the request queue that owns this hardware context. the parent, the main character.
  • fq β€” queue of requests that need to perform a flush operation.
  • driver_data β€” pointer to data owned by the block driver that created this hctx. lowkey the driver's little stash.
  • ctx_map β€” bitmap for each software queue. if bit is on, there is a pending request in that software queue. bit = on, request = pending, iykyk.
  • dispatch_from β€” software queue to be used when no scheduler was selected. the fallback queen πŸ‘‘
  • dispatch_busy β€” number used by blk_mq_update_dispatch_busy to decide if the hw_queue is busy using Exponential Weighted Moving Average algorithm. she's doing math, she's doing the most.

🧚 types, counts & arrays

  • type β€” HCTX_TYPE_* flags. type of hardware queue.
  • nr_ctx β€” number of software queues.
  • ctxs β€” array of software queues.

πŸ’œ the waiting room

  • dispatch_wait_lock β€” lock for the dispatch_wait queue.
  • dispatch_wait β€” waitqueue to put requests when there is no tag available at the moment, to wait for another try in the future. literally "no tag rn, come back later" energy.
  • wait_index β€” index of next available dispatch_wait queue to insert requests. the ticket number, fr fr.

πŸ”₯ tags

  • tags β€” tags owned by the block driver. a tag at this set is only assigned when a request is dispatched from a hardware queue.
  • sched_tags β€” tags owned by I/O scheduler. if there is an I/O scheduler associated with a request queue, a tag is assigned when that request is allocated. else, this member is not used. conditional icon ✨

🌸 node & index & count

  • numa_node β€” NUMA node the storage adapter has been connected to.
  • queue_num β€” index of this hardware queue.
  • nr_active β€” number of active requests. only used when a tag set is shared across request queues. exclusive little field, only sometimes relevant πŸ’…

🫢 CPU hotplug lists

  • cpuhp_online β€” list to store request if CPU is going to die. dramatic but accurate 😭
  • cpuhp_dead β€” list to store request if some CPU die. also dramatic, also accurate.

πŸŽ€ sysfs & debugfs

  • kobj β€” kernel object for sysfs.
  • debugfs_dir β€” debugfs directory for this hardware queue. named as cpu<cpu_number>.
  • sched_debugfs_dir β€” debugfs directory for the scheduler.

⭐ the last one

  • hctx_list β€” if this hctx is not in use, this is an entry in q->unused_hctx_list. benched but still on the roster.

πŸ” SEE ALSO πŸ”

kernel file ./include/linux/blk-mq.h, plus the whole friend group: enum blk_eh_timer_return(9), struct blk_mq_queue_map(9), enum hctx_type(9), struct blk_mq_tag_set(9), struct blk_mq_queue_data(9), struct blk_mq_ops(9), blk_mq_rq_state(9), blk_mq_add_to_batch(9), blk_mq_rq_from_pdu(9), blk_mq_rq_to_pdu(9), blk_rq_nr_bvec(9), blk_rq_passthrough_stats(9). go read them, they're all slay, no notes 🌈


ok that's the whole struct, every single field, nothing skipped. go forth and dispatch responsibly πŸ’–

and that's a wrap, bestie β€” brought to you by ./include/linux, dated October 2026, filed under struct blk_mq_hw_ctx(9). mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from