STRUCT BLK_MQ_OPS(9)

πŸ“¦ version 7.3.1, in nixpkgs unstable

okay bestie, so you're looking at struct blk_mq_ops(9) from the Kernel API Manual? This is the callback squad that block drivers use to implement their behaviour. Let's get into it πŸ’…βœ¨

🌸 NAME 🌸

struct blk_mq_ops β€” the callback functions that implement block driver behaviour. It's giving "driver behaviour: the musical" 🎭

✨ SYNOPSIS ✨

       struct blk_mq_ops {
           blk_status_t (*queue_rq)(struct blk_mq_hw_ctx *, const struct
       blk_mq_queue_data *);
           void (*commit_rqs)(struct blk_mq_hw_ctx *);
           void (*queue_rqs)(struct rq_list *rqlist);
           int (*get_budget)(struct request_queue *);
           void (*put_budget)(struct request_queue *, int);
           void (*set_rq_budget_token)(struct request *, int);
           int (*get_rq_budget_token)(struct request *);
           enum blk_eh_timer_return (*timeout)(struct request *);
           int (*poll)(struct blk_mq_hw_ctx *, struct io_comp_batch *);
           void (*complete)(struct request *);
           int (*init_hctx)(struct blk_mq_hw_ctx *, void *, unsigned int);
           void (*exit_hctx)(struct blk_mq_hw_ctx *, unsigned int);
           int (*init_request)(struct blk_mq_tag_set *set, struct request *,
       unsigned int, int);
           void (*exit_request)(struct blk_mq_tag_set *set, struct request *,
       unsigned int);
           void (*cleanup_rq)(struct request *);
           bool (*busy)(struct request_queue *);
           void (*map_queues)(struct blk_mq_tag_set *set);
         #ifdef CONFIG_BLK_DEBUG_FS;
           void (*show_rq)(struct seq_file *m, struct request *rq);
         #endif;
        };

πŸ‘‘ MEMBERS (the callback crew) πŸ‘‘

Here's the squad, one by one:

  • queue_rq β€” queue a new request from block IO. This is literally the main entrance for new requests, the VIP lounge πŸšͺ
  • commit_rqs β€” if a driver uses bd->last to judge when to submit requests to hardware, it must define this function. In case of errors that make us stop issuing further requests, this hook serves the purpose of kicking the hardware (which the last request otherwise would have done). So like, it's the emergency backup kick πŸ’₯
  • queue_rqs β€” queue a list of new requests. Driver is guaranteed that each request belongs to the same queue. If the driver doesn't empty the rqlist completely, then the rest will be queued individually by the block layer upon return. Batch 'em if you want, but leftovers get handled by the block layer 🧹
  • get_budget β€” reserve budget before queue request. Once .queue_rq is run, it is driver's responsibility to release the reserved budget. Also we have to handle failure case of .get_budget for avoiding I/O deadlock. So don't forget to release, and don't ignore failures, or you'll deadlock I/O πŸ’€
  • put_budget β€” release the reserved budget. That's it, that's the tweet 🐦
  • set_rq_budget_token β€” store rq's budget token. Keep that token safe πŸ”‘
  • get_rq_budget_token β€” retrieve rq's budget token. Gimme that token back πŸ”„
  • timeout β€” called on request timeout. When things take too long, this gets the call ⏰
  • poll β€” called to poll for completion of a specific tag. Like checking if your order's ready yet 🍟
  • complete β€” mark the request as complete. Done and dusted βœ…
  • init_hctx β€” called when the block layer side of a hardware queue has been set up, allowing the driver to allocate/init matching structures. Set up your side of the hardware queue πŸ—οΈ
  • exit_hctx β€” ditto for exit/teardown. Tear it down 🧨
  • init_request β€” called for every command allocated by the block layer to allow the driver to set up driver specific data. Tag greater than or equal to queue_depth is for setting up flush request. So set up your driver data, and note the flush request case πŸ’Ύ
  • exit_request β€” ditto for exit/teardown. Clean up after yourself 🧽
  • cleanup_rq β€” called before freeing one request which isn't completed yet, and usually for freeing the driver private data. Cleanup on aisle request 🧼
  • busy β€” if set, returns whether or not this queue currently is busy. Like a "do not disturb" sign for the queue 🚫
  • map_queues β€” this allows drivers specify their own queue mapping by overriding the setup-time function that builds the mq_map. Custom mapping, your rules πŸ—ΊοΈ
  • show_rq β€” used by the debugfs implementation to show driver-specific information about a request. Only present if CONFIG_BLK_DEBUG_FS is defined, btw. For when you need to peek under the hood πŸ”

πŸ’– SEE ALSO πŸ’–

Go check out these other icons:


Source: ./include/linux β€” October 2026. Stay slaying, bestie! πŸ«ΆπŸ’œ

πŸ“¦ where this page comes from