调用blk_mq_init_allocated_queue初始化分配的请求队列(request_queue),blk-mq的request_queue中包含两层队列,即percpu的软件队列(ctx)和与块设备硬件队列一一对应的硬件派发队列(hctx)。这个初始化过程主要包含下面几步: 1.设置队列的mq_ops(q->mq_ops)为set->ops (例如scsi对应的实现是scsi_mq_ops) 2.设...
对应到代码per_cpu_ptr(q->queue_ctx, cpu) 一个ctx根据rq type不同可以对应到多个hctx上, 但同一type的ctx只会有一个hctx. 显然rq知道知己的type, 所以rq映射到唯一的一个hctx上, 具体代码见blk_mq_get_request/blk_mq_map_queue. 这里的核心思想是对于读操作或者高优先级的rq, 可以使用单独的hctx ...
next_cpu = cpumask_first(hctx->cpumask); next_cpu = cpumask_first_and(hctx->cpumask,cpu_online_mask);hctx->next_cpu = next_cpu; hctx->next_cpu_batch = BLK_MQ_CPU_WORK_BATCH; @@ -2220,16 +2221,11 @@ static void blk_mq_init_cpu_queues(struct request_queue *q, INIT_LIST...
data.ctx = __blk_mq_get_ctx(q, cpu); if (!q->elevator) blk_mq_tag_busy(data.hctx); if (q->elevator) data.rq_flags |= RQF_SCHED_TAGS; else data.rq_flags |= RQF_ELV; blk_mq_tag_busy(data.hctx); if (flags & BLK_MQ_REQ_RESERVED) data.rq_flags |= RQF_RESV; @@ -...
mq_ctx:指定这个请求将会发送到的软件队列; bio:组成这个request的bio链表的头指针; biotail:组成这个request的bio链表的尾指针; hash:内核hash表头指针; queuelist:通过list_head可以用来构建一个request类型的双向链表; 1个request中包含了一个或多个bio,为什么要有request这个结构呢?它存在的目的就是为了进行io的...
System crash in blk_mq_free_request() following NVMe controller reset due to NULL mq_hctx. Example 1: Raw nvme nvme0: I/O 71 QID 1 timeout, aborting nvme nvme0: Abort status: 0x0 nvme nvme0: I/O 71 QID 1 timeout, reset controller nvme nvme0: 2/0/0 default/read/poll queues...
-static int blk_mq_init_hctx(struct request_queue *q, - struct blk_mq_tag_set *set, - struct blk_mq_hw_ctx *hctx, unsigned hctx_idx) +static int blk_mq_hw_ctx_size(struct blk_mq_tag_set *tag_set) { - int node; + int hw_ctx_size = sizeof(struct blk_mq_hw_ctx); ...
> However, even though blk_mq_freeze_queue() is returned, there might be > run queue activity not completed, then use-after-free may be triggered > on hctx and its fields. > > Fix this issue by really quiescing queue via blk_mq_quiesce_queue() and ...
blk_get_queue blk_get_request blk_lookup_devt blk_mq_alloc_request blk_mq_alloc_request_hctx blk_mq_alloc_tag_set blk_mq_complete_request blk_mq_delay_kick_requeue_list blk_mq_end_request blk_mq_free_request blk_mq_free_tag_set blk_mq_freeze_queue blk_mq_freeze_qu...
.free_hctx = blk_mq_free_single_hw_queue, .complete = virtblk_request_done, }; request的存储区vbr初始化,结构依旧是scatter-list形式 blk_mq_init_commands(q, virtblk_init_vbr, vblk); 内核中块I/O操作的基本容器由bio结构体表示,该结构体代表了正在现场的(活动的)以片段(segment)链表形式组织的...