본문 바로가기

리눅스 커널/블록 멀티 큐

NVMe 디바이스 드라이버 초기화 흐름

NVMe Device Driver init flow, kernel version 4.13.10

from drivers/nvme/host/pci.c

static struct pci_driver nvme_driver = {
	.name		= "nvme",
	.id_table	= nvme_id_table,
	.probe		= nvme_probe,
	.remove		= nvme_remove,
	.shutdown	= nvme_shutdown,
	.driver		= {
		.pm	= &nvme_dev_pm_ops,
	},
	.sriov_configure = nvme_pci_sriov_configure,
	.err_handler	= &nvme_err_handler,
};

static int __init nvme_init(void)
{
	return pci_register_driver(&nvme_driver);
}

static void __exit nvme_exit(void)
{
	pci_unregister_driver(&nvme_driver);
	_nvme_check_size();
}

MODULE_AUTHOR("Matthew Wilcox <willy@linux.intel.com>");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
module_init(nvme_init);
module_exit(nvme_exit);

모듈 형식으로 되어 있다.

이 후 흐름을 정리하면 아래와 같다.

insmod
->nvme_init()
	->pci_register_driver()
    	->__pci_register_driver()
        	->driver_register()
            	->drvier_find()
                ->bus_add_driver()
                ->drvier_add_groups()
                ->kobject_uevent()
                ...

이 후 어디선가 nvme_probe() 가 호출되어야 하는데, 정확한 흐름은 찾지 못했다.

 

다음은 nvme_probe() 의 흐름이다.

nvme_probe()
	//
    ->dev = kzalloc_node(sizeof(*dev), GFP_KERNEL, node);
    ->dev->queues = kzalloc_node((num_possible_cpus() + 1) * sizeof(void *), GFP_KERNEL, node)
    ->nvme_dev_map(dev)
    	//
        ->nvme_remap_bar(dev, NVME_REG_DBS + 4096)
        	//
            ->dev->bar = ioremap(pci_resource_start(pdev, 0), size);
            ->dev->bar_mapped_size = size;
            ->dev->dbs = dev->bar + NVME_REG_DBS;
    ->INIT_WORK(&dev->ctrl.reset_work, nvme_reset_work);
    ->queue_work(nvme_wq, &dev->ctrl.resetwork);
    ->return 0;

전체 코드는 drivers/nvme/host/pci.c 에서 확인 할 수 있고, 여기서는 필자가 이해한 바를 토대로 그 흐름을 적었다.

 

1. nvme_dev 를 위한 메모리를 할당한다.

2. nvme_queue 관리를 위한 포인터 배열을 위한 메모리를 할당한다. 그 길이는, 코어 개수 + 1 로

각 코어에 할당을 위한 io 큐와 관리자 큐의 전체 개수를 의미한다.

3. pci 장치에 물리메모리에 매핑되는 가상메모리 주소를 ioremap을 통하여 얻는다.

이 부분은 NVMe spec과 같이 보아야 할 부분이다. //나중에 한 차례 정리 해보겠다.

4. nvme_reset_work() 가 호출된다.



'리눅스 커널 > 블록 멀티 큐' 카테고리의 다른 글

nvme command 관련 추가 내용  (0) 2021.10.26
nvme command  (0) 2021.10.26
nvme_setup_io_queues 흐름  (0) 2021.10.26
nvme_reset_work 흐름  (0) 2021.10.26
nvme 자료구조 관계  (0) 2021.10.26