如何从内核空间中缩小Linux页面缓存?
我正在研究一个涉及一些自定义硬件和我为硬件编写的自定义
Linux设备驱动程序的系统.系统偶尔需要非常快速地移动大量数据,因此我的驱动程序动态地(即在需要时)分配大的(1 GB)DMA缓冲区,这些缓冲区被使用,然后在不再需要时释放.为了分配这么大的缓冲区,我实际上使用dma_alloc_coherent分配了一堆较小的缓冲区(256 X 4MB),然后使用remap_pfn_range将它们连续映射到用户空间.这在大多数情况下非常有效.
在测试期间,在系统长时间运行测试用例之后,我有时会看到DMA分配失败,其中我的驱动程序中的一个dma_alloc_coherent调用失败,导致我的应用层软件崩溃.我终于能够找到这个问题,我发现当我看到DMA分配失败时,Linux内核页面缓存非常充分. 例如,在我捕获页面缓存的最后一次失败中,在我的系统上填充了27 GB的32 GB RAM.我怀疑页面缓存“fullness”导致dma_alloc_coherent调用失败.为了测试这个理论,我使用以下方法手动清空页面缓存: # echo 1 > /proc/sys/vm/drop_caches 这将缓存的大小从27 GB减少到94 MB,并且我能够分配20个1 GB DMA缓冲区而没有任何问题. 很明显,页面缓存是一件有益的事情,所以在分配DMA缓冲区时,每次空间不足时,我都不希望完全清空它.我的问题是:如何动态缩小内核空间中的页面缓存,这样如果调用dma_alloc_coherent失败,我可以恢复足够的空间,以便我可以重试调用并使其成功? 我的系统是基于x86_64的,运行3.16.x Linux内核. 我发现了一些模糊的引用,表明我正在尝试的可能,例如“这些对象是自动的 对此的任何帮助将不胜感激! 解决方法
TL; DR:扫描活动超级块并删除对非脏块的引用,直到您根据需要回收了尽可能多的系统内存. (或者你最终用尽了对活动超级块的引用.)
要回答这个问题,让我们看一下“drop_caches操作”在您的系统上将fs页面缓存从27GB减少到94MB的功能. > echo 1>的/ proc / sys目录/ VM / drop_caches 接下来发生的事情是iterate_supers()扫描活动超级块,每次找到一个时,它调用drop_pagecache_sb(),向活动超级块传递一个引用. 该迭代过程继续,直到从fs页面高速缓存中释放对所有活动超级块的引用.这是一种非破坏性操作,只会释放完全未使用的块.脏对象将继续使用,直到写入磁盘并且不可用.如果先运行同步将它们刷新到磁盘,“drop_caches操作”往往会释放更多内存.
要记住以下几点,以进一步优化此过程: >某些块设备是否优先于其他块设备? 请注意,这是一个推测性解决方案,完全基于您已经观察到已经解决问题的Linux内核中现有代码的分析.一旦实现了上述方法,它将只允许您控制相同的操作,即仅尝试回收fs页面缓存内存,仅满足您的即时需求. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |