延迟可能是由于内核将可移动页面(用于块设备缓存等)迁移出 CMA 以获得足够大的连续区域来满足您的请求。避免延迟的一种方法是在设备树中为您的设备保留一个特定的内存块,这样就不必从全局 CMA 池中分配。
以下假设您正在开发一个使用设备树的嵌入式系统,并且可以修改驱动程序代码以利用保留的内存区域。
如果专门为您的设备保留一个内存区域,您可以静态或动态地保留该区域(让内核确定该区域的起始地址)。详情请见reserved-memory.txt。
设置no-map 属性以停止内核将内存映射为其标准系统内存的一部分。
如果您不希望内存被内核的其他部分(块页面缓存等)用于临时存储,请不要设置reusable 属性。
如果要从缓冲区分配一致的 DMA 内存,请设置 compatible = "shared-dma-pool";。尽管池是“共享的”,但它仅由专门使用此保留内存区域的设备共享。
在您的设备节点中,将 memory-region 属性设置为引用保留内存区域的 phandle。
例如:
/ {
/* ... */
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
my_dev_reserved: region_my_dev_buffer {
compatible = "shared-dma-pool";
no-map;
size = <0x02000000>; /* 32 MiB size */
alignment = <0x1000>; /* 4 KiB alignment */
};
};
/* ... */
my_dev: mydev@xxxx {
compatible = "foo,barbaz-1.0";
/* ... */
memory-region = <&my_dev_reserved>;
/* ... */
};
/* ... */
};
在您的设备驱动程序“探测”函数中,您可以调用of_reserved_mem_device_init(hwdev);(其中hwdev 是指向您的硬件设备的struct device 的指针,通常嵌入在其他一些结构中,例如struct platform_device) .返回值0 表示设备将使用特定于设备的保留内存进行一致的 DMA 内存分配(如果该区域的compatible 字符串为"shared-dma-pool",否则一致的 DMA 内存分配将回退到使用全局池.
如果of_reserved_mem_device_init(hwdev); 成功,您应该在您的设备驱动程序“删除”函数中调用of_reserved_mem_release(hwdev); 以释放分配的资源。 (您可能还需要在“探测”函数的错误清理代码中调用它。)