dev_dax
当我们生成了nd_dax设备后,nvdimm驱动的任务就基本结束了。或者应该说,nvdimm驱动最后的任务是创建一个dev_dax设备,由这个设备接过最后的枪。
构造dev_dax的过程
从nd_dax构造dev_dax的过程在dax_pmem_probe中完成。
dax_pmem_probe()
nvdimm_setup_pfn(nd_pfn, &pgmap);
nd_pfn_init(nd_pfn);
__nvdimm_setup_pfn(nd_pfn, pgmap);
dax_region = alloc_dax_region(dev, region_id, &res,
le32_to_cpu(pfn_sb->align), addr, PFN_DEV|PFN_MAP);
dev_dax = __devm_create_dev_dax(dax_region, id, &pgmap, subsys);
dax_dev = alloc_dax(dev_dax, NULL, NULL);
dax_dev = dax_dev_get(devt);
...
alloc_inode(super_block)
dev_dax->dax_dev = dax_dev;上面的流程就是从nd_dax/nd_pfn设备构造到dev_dax的过程。大致可以分成三个步骤:
nvdimm_setup_pfn() 对nd_pfn中的成员做了设置,比如对齐和计算page struct的空间
alloc_dax_region() 这是构造dev_dax所需的信息
函数__devm_create_dev_dax用来创建dax_dev,也就是dax文件系统。值得注意的是这个数据结构是通过super_block创建inode时候创建的。
dev_dax是个庞大的结构体,就让我们来看一看吧。
dev_dax, dax_dev, dax_region
着重讲几点:
最终的目标是生成dev_dax设备,该设备对应一个字符类型的文件/dev/dax0.0
/dev/dax0.0的fops是dax_fops,所以后面的mmap就靠它了
dev_dax生成的信息在dax_region中
dax_region中res就是对齐过后,去掉元数据的部分;
怎么样,这下是不是够爽?
dev_dax的驱动device_dax_driver
既然有了dev_dax,那么这个设备是如何开始它的工作的呢?再来回顾一下dev_dax结构体中新创建的设备。
这部分已经超出了nvdimm驱动的范畴,但是为了把故事讲完,我们还是要看一下生成的这个设备是如何被使用到的。
因为这个设备是在dax_bus_type总线上的,所以它的驱动也应该是在同一个总线上的了。这个默认的驱动就是device_dax_driver.
探测
这个驱动的探测函数dev_dax_probe主要做了两件事情:
devm_memremap_pages(dev, &dev->pgmap)
cdev_init(cdev, &dax_fops);
Last updated
Was this helpful?