From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751119Ab2ATFVS (ORCPT ); Fri, 20 Jan 2012 00:21:18 -0500 Received: from mail.windriver.com ([147.11.1.11]:55460 "EHLO mail.windriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750736Ab2ATFVR (ORCPT ); Fri, 20 Jan 2012 00:21:17 -0500 From: Zumeng Chen To: CC: , , , Subject: [PATCH 1/1] mm: msync: fix issues of sys_msync on tmpfs Date: Fri, 20 Jan 2012 13:18:39 +0800 Message-ID: <1327036719-1965-1-git-send-email-zumeng.chen@windriver.com> X-Mailer: git-send-email 1.7.0.4 MIME-Version: 1.0 Content-Type: text/plain Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch fixes two issues as follows: For some filesystem with fsync == noop_fsync, there is not so much thing to do, so sys_msync just passes by for all arches but some CPUs. For some CPUs with cache aliases(dmesg|grep alias), it maybe has an issue, which reported by msync test suites in ltp-full when the memory of memset used by msync01 runs into cache alias randomly. Consider the following scenario used by msync01 in ltp-full: fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0); .../* initialization fildes by write(fildes); */ addr = mmap(0, page_sz, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fildes, 0); /* set buf with memset */ memset(addr + OFFSET_1, 1, BUF_SIZE); /* msync the addr before using, or MS_SYNC*/ msync(addr, page_sz, MS_ASYNC) /* Tries to read fildes */ lseek(fildes, (off_t) OFFSET_1, SEEK_SET) != (off_t) OFFSET_1) { nread = read(fildes, read_buf, sizeof(read_buf)); /* Then test the result */ if (read_buf[count] != 1) { The test result is random too for CPUs with cache alias. So in this situation, we have to flush the related vma to make sure the read is correct. Signed-off-by: Zumeng Chen --- mm/msync.c | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-) diff --git a/mm/msync.c b/mm/msync.c index 632df45..0021a7e 100644 --- a/mm/msync.c +++ b/mm/msync.c @@ -13,6 +13,14 @@ #include #include #include +#include + +/* Cache aliases should be taken into accounts when msync. */ +#ifdef cpu_has_dc_aliases +#define CPU_HAS_CACHE_ALIAS cpu_has_dc_aliases +#else +#define CPU_HAS_CACHE_ALIAS 0 +#endif /* * MS_SYNC syncs the entire file - including mappings. @@ -78,6 +86,28 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags) } file = vma->vm_file; start = vma->vm_end; + + /* + * For some filesystems with fsync == noop_fsync, msync just + * passes by but some CPUs. + * For CPUs with cache alias, msync has to flush the related + * vma explicitly to make sure data coherency between memory + * and cache, which includes MS_SYNC or MS_ASYNC. That is to + * say, cache aliases should not be an async factor, so does + * msync on other arches without cache aliases. + */ + if (file && file->f_op && file->f_op->fsync == noop_fsync) { + if (CPU_HAS_CACHE_ALIAS) + flush_cache_range(vma, vma->vm_start, + vma->vm_end); + if (start >= end) { + error = 0; + goto out_unlock; + } + vma = find_vma(mm, start); + continue; + } + if ((flags & MS_SYNC) && file && (vma->vm_flags & VM_SHARED)) { get_file(file); -- 1.7.0.4