이 함수는 nvme_reset_work() 에서 nvme_alloc_admin_tags() 에서도 호출된다. 그러나 이 때에는 관리자 큐를 위한 tagset 및 tags를 할당하기 위한 것이나 그 흐름은 거의 유사하다.
nvme_dev_add(struct nvme_dev * dev) from nvme_reset_work
->dev->tagset.ops = &nvme_mq_ops;
->dev->tagset.nr_hw_queues = dev->online_queues - 1;
->dev->tagset.queue_depth = min_t(int, dev->q_depth, BLK_MQ_MAX_DEPTH) - 1;
->dev->tagset.driver_data = dev;
->blk_mq_alloc_tag_set(&dev->tagset);
->...
->dev->ctrl.tagset = &dev->tagset;
->nvme_dbbuf_set(dev);
->nvme_submit_sync_cmd(...);
blk_mq_alloc_tag_set(struct blk_mq_tag_set * set) from nvme_dev_add
->set->tags = kzalloc_node(nr_cpu_ids * sizeof(struct blk_mq_tags *), ...);
->set->mq_map = kzalloc_node(sizeof(*set->mq_map) * nr_cpu_ids, ...);
->blk_mq_updated_queue_map(set);
->set->ops->map_queues(set); //nvme_pci_map_queues()
->blk_mq_alloc_rq_maps(set);
->__blk_mq_alloc_rq_maps(set);
->for (0 to set->nr_hw_queues)
->__blk_mq_alloc_rq_map(set, i);
->set->tags[hctx_idx] = blk_mq_alloc_rq_map(...);
->tags = blk_mq_init_tags(...);
->tags->rqs = kzalloc_node(nr_tags * sizeof(struct request *), ...);
->tags->static_rqs = kzalloc_node(nr_tags * sizeof(struct request *), ...);
->blk_mq_alloc_rqs(...);
->for (0 to depth)
->p = page_address(page);
->struct request * rq = p;
->tags->static_rqs[i] = rq;
->set->ops->init_request(...); //nvme_init_request
->if fail, return -ENOMEM;
->return 0;
1. nvme_dev_add() 에서 blk_mq_alloc_tag_set()을 호출하기 전에 먼저 기본적인 작업을 준비한다.
2. tags를 위한 blk_mq_tags 포인터 배열을 준비한다. 그 길이는 cpu개수 만큼이다.
3. sw 큐와 hw 큐간 매핑정보를 저장할 배열을 위한 메모리를 준비한다.
4. nvme_pci_map_queues()를 이용하여 큐 들간 매핑된 정보를 저장한다.
5. tags배열의 각 tags를 위한 메모리를 할당하고, 초기화한다.
6. request pool을 준비한다.
7. tags를 위한 초기화가 하나라도 실패하면 blk_mq_alloc_rq_maps()에서 queue_depth를 절반으로 줄여 다시 진행하게 되는데, 그 queue_depth 가 0이 되어버리면, 더 이상 진행하지 못하고 nvme device driver 초기화는 실패하게 된다.
'리눅스 커널 > 블록 멀티 큐' 카테고리의 다른 글
urgent queue 를 위한 tag 예약 (0) | 2021.10.26 |
---|---|
blk_mq_init_queue (0) | 2021.10.26 |
nvme command 관련 추가 내용 (0) | 2021.10.26 |
nvme command (0) | 2021.10.26 |
nvme_setup_io_queues 흐름 (0) | 2021.10.26 |