STRUCT BLK_MQ_HW_CTX(9)
π 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 byblk_mq_hctx_next_cpufor round-robin CPU selection fromcpumask. 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 byblk_mq_update_dispatch_busyto decide if thehw_queueis 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 thedispatch_waitqueue.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 availabledispatch_waitqueue 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 ascpu<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 inq->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
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms