본문 바로가기

리눅스 커널/블록 멀티 큐

nvme_reset_work 흐름

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