title: How can I shrink the Linux page cache from within kernel space?
body: <p>I'm working on a system that involves some custom hardware and a custom Linux device driver I wrote for the hardware.  The system occasionally needs to move large amounts of data very rapidly and therefore my driver dynamically (i.e. when needed) allocates large (1 GB) DMA buffers which are used and then freed when they are no longer needed.  To allocate such large buffers I actually allocate a bunch of smaller buffers (256 X 4MB) using <code>dma_alloc_coherent</code> and then map them contiguously into user space using <code>remap_pfn_range</code>. This works very well most of the time.</p>
  
  <p>During testing, after the system has been running test cases for a long time, I sometimes see DMA allocation failures where one of the <code>dma_alloc_coherent</code> calls in my driver fails which causes my application layer software to crash.  I was finally able to track down this problem and I discovered that when I see DMA allocation failures the Linux kernel page cache is very full. </p>
  
  <p>For example, on the last failure that I captured the page cache filled 27 GB of the 32 GB of RAM on my system.  I suspected that the page cache "fullness" was causing <code>dma_alloc_coherent</code> calls to fail.  To test this theory I manually emptied the page cache using:</p>
  
  <pre><code># echo 1 &gt; /proc/sys/vm/drop_caches
  </code></pre>
  
  <p>This dropped the size of the cache from 27 GB to 94 MB and I was able to allocate 20+ 1 GB DMA buffers with no issues. </p>
  
  <p>Clearly the page cache is a beneficial thing so I would prefer not to have to completely empty it every time I run out of space when allocating DMA buffers. My questions is this: how can I dynamically shrink the page cache in kernel space such that if a call to <code>dma_alloc_coherent</code> fails I can recover just enough space so that I can retry the call and have it succeed?</p>
  
  <p>My system is x86_64 based running a 3.16.x Linux kernel.</p>
  
  <p>I have found some vague references that suggest what I'm attempting may be possible, for example "These objects are automatically
  reclaimed by the kernel when memory is needed elsewhere on the system." (from: <a href="https://www.kernel.org/doc/Documentation/sysctl/vm.txt" rel="nofollow">https://www.kernel.org/doc/Documentation/sysctl/vm.txt</a>). But I have not yet found any specifics that indicate how the memory is reclaimed.</p>
  
  <p>Any assistance with this would be greatly appreciated!</p>