On Tue, Mar 29, 2011 at 8:02 AM, Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> wrote: > On Mon, 28 Mar 2011 13:32:35 +0800 > Bob Liu <lliubbo@xxxxxxxxx> wrote: > >> On no-mmu arch, there is a memleak duirng shmem test. >> The cause of this memleak is ramfs_nommu_expand_for_mapping() added page >> refcount to 2 which makes iput() can't free that pages. >> >> The simple test file is like this: >> int main(void) >> { >> Â Â Â int i; >> Â Â Â key_t k = ftok("/etc", 42); >> >> Â Â Â for ( i=0; i<100; ++i) { >> Â Â Â Â Â Â Â int id = shmget(k, 10000, 0644|IPC_CREAT); >> Â Â Â Â Â Â Â if (id == -1) { >> Â Â Â Â Â Â Â Â Â Â Â printf("shmget error\n"); >> Â Â Â Â Â Â Â } >> Â Â Â Â Â Â Â if(shmctl(id, IPC_RMID, NULL ) == -1) { >> Â Â Â Â Â Â Â Â Â Â Â printf("shm Ârm error\n"); >> Â Â Â Â Â Â Â Â Â Â Â return -1; >> Â Â Â Â Â Â Â } >> Â Â Â } >> Â Â Â printf("run ok...\n"); >> Â Â Â return 0; >> } >> >> ... >> >> diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c >> index 9eead2c..fbb0b47 100644 >> --- a/fs/ramfs/file-nommu.c >> +++ b/fs/ramfs/file-nommu.c >> @@ -112,6 +112,7 @@ int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) >> Â Â Â Â Â Â Â SetPageDirty(page); >> >> Â Â Â Â Â Â Â unlock_page(page); >> + Â Â Â Â Â Â put_page(page); >> Â Â Â } >> >> Â Â Â return 0; > > Something is still wrong here. > > A live, in-use page should have a refcount of three. ÂOne for the > existence of the page, one for its presence on the page LRU and one for > its existence in the pagecache radix tree. > > So allocation should do: > > Â Â Â Âalloc_pages() > Â Â Â Âadd_to_page_cache() > Â Â Â Âadd_to_lru() > > and deallocation should do > > Â Â Â Âremove_from_lru() > Â Â Â Âremove_from_page_cache() > Â Â Â Âput_page() > > If this protocol is followed correctly, there is no need to do a > put_page() during the allocation/setup phase! > > I suspect that the problem in nommu really lies in the > deallocation/teardown phase. > > Yes, And in my understanding in nommu deallocation phase: 1. iput() call default generate_drop_inode(). 2. and then in evict() call truncate_inode_pages() which just remove pages from_lru and pagecache. There is no pace call put_page() so pages can't be freed at last. Maybe we need to implement evict_inode() or drop_inode() in ramfs. I will try it soon but I am not familiar with fs, any ideas is welcome. Thanks -- Regards, --Bob -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxxx For more info on Linux MM, see: http://www.linux-mm.org/ . Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/ Don't email: <a href