nvme_reset_work(struct work_struct * work) from nvme_probe
->struct nvme_dev * dev = container_of(work, struct nvme_dev, ctrl.reset_work);
->nvme_pci_configure_admin_queues(dev);
->nvmeq = dev->queues[0];
->nvmeq = nvme_alloc_queue(...);
->nvmeq = kzalloc_node(sizeof(*nvmeq), GFP_KERNEL, node);
->nvmeq->cqes = dma_zalloc_coherent(...);
->dev->queues[qid] = nvmeq;
->dev->ctrl.queue_count++;
->nvmeq->cq_vector = 0;
->queue_request_irq(nvmeq);
->pci_request_irq(...);
->nvme_init_queue(dev->queues[0], 0);
->dev->online_queues++;
->nvme_alloc_admin_tags(dev);
->nvme_setup_io_queues(dev);
->...
->if (dev->online_queues < 2)
->fail
->else
->nvme_dev_add(dev);
->blk_mq_alloc_tag_set(&dev->tagset));
->...
->dev->ctrl.tagset = &dev->tagset;
->nvme_start_ctrl(&dev->ctrl);
->...nvme_alloc_ns(ctrl, nsid)
->struct nvme_ns * ns = kzalloc_node(...);
->ns->queue = blk_mq_init_queue(ctrl->tagset);
->struct gendisk * disk = alloc_disk_node(0, node);
->disk->queue = ns->queue;
->ns->disk = disk;
->device_add_disk(ctrl->device, ns->disk);
...한 부분은 두가지 의미가 있는데,
첫번째는 그 코드 흐름을 따로 정리할 계획과
두번째는 매개변수를 다 적기 힘든 점이 있어서이다.
이어서, 위 흐름을 말로 정리하면,
1. qid == 0, 관리자 큐를 위한 메모리를 할당하고, 이를 적절히 초기화 한 후 인터럽트 핸들러를 등록한다.
2. 관리자 큐를 위한 tagset 및 tags를 할당하고 초기화 한다.
3. io를 위한 nvme_queue 를 위한 메모리 할당 및 초기화를 진행한다.
4. 그 큐들을 정상적으로 만든 경우에 io를 위한 tagset 및 tags를 할당하고 초기화 한다.
5. 컨트롤러를 실행 시키고, io를 위한 sw 큐, hw 큐를 생성하고 초기화 한다.
6. gendisk에 io를 위한 request_queue 가 등록되어, 나중에 io요청 시 이를 활용하는 듯 하다.
'리눅스 커널 > 블록 멀티 큐' 카테고리의 다른 글
nvme command 관련 추가 내용 (0) | 2021.10.26 |
---|---|
nvme command (0) | 2021.10.26 |
nvme_setup_io_queues 흐름 (0) | 2021.10.26 |
nvme 자료구조 관계 (0) | 2021.10.26 |
NVMe 디바이스 드라이버 초기화 흐름 (0) | 2021.10.26 |