Fwd: Memory leakage when using read_swap_cache_async() ?

From: Viacheslav Fedorov
Date: Mon Oct 12 2015 - 19:43:43 EST


Hi ladies and gentlemen,

Please help - I am stuck.
Looks like memory pages go unaccounted for, somewhere in the system,
when I am prefetching pages from swap file. Using kernel 3.8.0 (Ubuntu
distribution).

So what I do is I have two simple applications that allocate 1GB
memory each and then proceed to write arbitrary data to the allocated
memory, with page granularity.
The system has a total of 1.3GB RAM to simulate memory pressure etc
and encourage swapping.

To test the basic functionality of my approach, I included a simple
"next-page" prefetch code into the mm/memory.c, just after the call to
do_swap_page (http://lxr.free-electrons.com/source/mm/memory.c?v=3.8#L3637)
What it should do is prefetch 10 pages following the one that has just
been swapped in on-demand. I don't really care which ones, what
matters is want to try something different than reading sequentially
from the swap file (read-ahead).
See the code below.

The problem is, if I run the test apps for the sufficient amount of
time, the "used" memory increases to the point where the applications
are killed by an OOM-killer.
After that, the available system memory is about half of what it
should have been (e.g. 600MB/1.3GB). Same thing happens to memory
usage if I stop the applications before the OOM-killer is triggered,
I am also attaching the /proc/meminfo contents for comparison on a
freshly-booted system vs. one where the two apps have been running for
200 seconds before quitting, with and without the prefetch code in
kernel.
Note how Active and Inactive show a lot of memory being "used" for something.
The printouts were made when the system is completely idle with
nothing running etc.


I also tried prefetching from within the swapin_readahead() function
(http://lxr.free-electrons.com/source/mm/swap_state.c?v=3.8#L373) with
the same result - memory gets "used up".


I would greatly appreciate any help!
Pretty much ran out of ideas as to what could be causing this.
Thanks a lot,
Slava

============== code fragment used for prefetching ============

(( at the beginning of handle_pte_fault() function...
int rett, ii;
pte_t *ptee;
swp_entry_t sentry;
struct page *page;
))

rett = do_swap_page(mm, vma, address,
pte, pmd, flags, entry);

////////////////////////////////////////////////////////////////
/// test for memory leaks////////////////////
for(ii=1;ii<10;ii++){
ptee = pte_offset_map(pmd, address + (ii*2)<<12);
if(pte_present(*ptee) || pte_none(*ptee) ||
pte_file(*ptee)) return rett; // no such page in page table
sentry = pte_to_swp_entry(*ptee);
if (non_swap_entry(sentry)){
// printk(KERN_ALERT " non swap entry\n");
return rett;
}
delayacct_set_flag(DELAYACCT_PF_SWAPIN);
page = lookup_swap_cache(sentry);
if (!page) {
page = read_swap_cache_async(sentry,
GFP_HIGHUSER_MOVABLE, vma, address);
if(page) page_cache_release(page);
}
lru_add_drain();
// if(page) unlock_page(page);
delayacct_clear_flag(DELAYACCT_PF_SWAPIN);
}
// printk(KERN_ALERT "swapped pages\n");
////////////////////////////////////////////
//////////////////////////////////////////

return rett;

===================== end code fragment =====================
prefetch: 200s run:

MemTotal: 1270536 kB
MemFree: 668748 kB
Buffers: 5304 kB
Cached: 33248 kB
SwapCached: 120424 kB
Active: 336016 kB
Inactive: 221792 kB
Active(anon): 328280 kB
Inactive(anon): 190984 kB
Active(file): 7736 kB
Inactive(file): 30808 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 4191228 kB
SwapFree: 4052040 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 6008 kB
Mapped: 4596 kB
Shmem: 8 kB
Slab: 23656 kB
SReclaimable: 10304 kB
SUnreclaim: 13352 kB
KernelStack: 800 kB
PageTables: 2008 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 4826496 kB
Committed_AS: 72232 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 267280 kB
VmallocChunk: 34359469179 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 34816 kB
DirectMap2M: 1378304 kB




fresh boot:
MemTotal: 1270536 kB
MemFree: 1118524 kB
Buffers: 13236 kB
Cached: 79364 kB
SwapCached: 0 kB
Active: 37896 kB
Inactive: 71008 kB
Active(anon): 16336 kB
Inactive(anon): 252 kB
Active(file): 21560 kB
Inactive(file): 70756 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 4191228 kB
SwapFree: 4191228 kB
Dirty: 24 kB
Writeback: 0 kB
AnonPages: 16212 kB
Mapped: 7320 kB
Shmem: 280 kB
Slab: 23496 kB
SReclaimable: 11060 kB
SUnreclaim: 12436 kB
KernelStack: 856 kB
PageTables: 1656 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 4826496 kB
Committed_AS: 60072 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 267280 kB
VmallocChunk: 34359470199 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 36864 kB
DirectMap2M: 1376256 kB



no prefetch: 200s run:
MemTotal: 1270536 kB
MemFree: 1219856 kB
Buffers: 344 kB
Cached: 4348 kB
SwapCached: 1512 kB
Active: 1768 kB
Inactive: 6284 kB
Active(anon): 172 kB
Inactive(anon): 3124 kB
Active(file): 1596 kB
Inactive(file): 3160 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 4191228 kB
SwapFree: 4168800 kB
Dirty: 0 kB
Writeback: 0 kB
AnonPages: 3340 kB
Mapped: 1948 kB
Shmem: 0 kB
Slab: 22416 kB
SReclaimable: 9580 kB
SUnreclaim: 12836 kB
KernelStack: 768 kB
PageTables: 1972 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 4826496 kB
Committed_AS: 71036 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 267280 kB
VmallocChunk: 34359470199 kB
HardwareCorrupted: 0 kB
AnonHugePages: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 36864 kB
DirectMap2M: 1376256 kB

#include <stdio.h>
#include <stdlib.h>

int main(){
unsigned long i=2;

char *mem = (char*)malloc(1024*1024*1424); // 1 gig

if(mem)
while(1){
mem[i] = rand();
i+=4096;
i = i%(1024*1024*1024);
}
return 0;

}