关于Controller Memory Buffer(CMB)
每块SSD上,不管是SATA还是PCIE口的,都会有一定量的DRAM来做数据缓存。但是,这个数据缓存对Host端是不可见的,也就是说,Host端的代码是不可能直接使用访存指令访问到这块数据缓存的,这块内存空间并没有被映射到Host物理地址空间中。
我们知道,Host端的程序只能通过访问某个或者某些物理地址从而与SSD控制器通信。通常,Host端的驱动程序会将由上层协议栈准备好的IO指令及数据在Host主存中的基地址(也就是指针)采用Stor指令写入到SSD控制器的前端PCIE控制器模块所暴露的寄存器中,SSD控制器接收到该指针,便可以从Host主存中取回对应的指令及数据从而执行。SSD控制器的这些寄存器会被映射到Host物理地址空间中的某处,该动作由host端PCIE bus driver在枚举PCIE设备之后即执行。底层细节和过程冬瓜哥就不过多描述了。
可以看到,SSD控制器只向host端暴露了很少量的寄存器存储空间,并未将其内部的数百兆甚至上GB的DRAM空间映射到host物理地址空间。而且,驱动程序先把对应的指针通知给SSD控制器,然后SSD控制器需要主动从Host主存取指令和数据。有人可能会想,为何驱动程序不直接将指令及数据写入到SSD的DRAM中呢?原因是CPU如果把这事都自己干了,那就忙不过来了,会深陷到Load/Stor指令移动数据,其他活就没法干了。SSD控制器上有个DMA模块,在收到指针之后,DMA模块会主动读取host主存,此时host CPU可以做其他事情。
但是如果CPU将整条指令而不是指针直接写到SSD端的DRAM的话,并不耗费太多资源,此时能够节省一次PCIE往返及一次SSD控制器内部的中断处理。于是,人们就想将SSD控制器上的一小段DRAM空间映射到host物理地址空间从而可以让驱动直接写指令进去,甚至写一些数据进去也是可以的。这块被映射到host物理地址空间的DRAM空间便被称为CMB了。