[yocto] [V2 PATCH 1/1] mm: msync: fix issues of sys_msync on tmpfs
Zumeng Chen
zumeng.chen at windriver.com
Wed Dec 21 19:07:41 PST 2011
There are two problems as follows shown:
1 ) for TMPFS, nothing need to be done in sys_msync,
sys_msync just return 0 for all arches.
2 ) But for MIPS CPUs with cache alias(dmesg|grep alias),
it maybe has the issue, which reported by msync test
suites in ltp-full, when the memory of memset used by
msycn01 has cache alias.
So, in this situation, we have to flush the related
vma to make sure correct read.
Signed-off-by: Zumeng Chen <zumeng.chen at windriver.com>
---
include/linux/shmem_fs.h | 10 ++++++++++
mm/msync.c | 22 +++++++++++++++++++++-
mm/shmem.c | 5 +++++
3 files changed, 36 insertions(+), 1 deletions(-)
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index aa08fa8..62a2d57 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -12,6 +12,15 @@
#define SHMEM_SYMLINK_INLINE_LEN (SHMEM_NR_DIRECT * sizeof(swp_entry_t))
+/*
+
+*/
+#ifndef cpu_has_dc_aliases
+#define CPU_HAS_CACHE_ALIAS 0
+#else
+#define CPU_HAS_CACHE_ALIAS cpu_has_dc_aliases
+#endif
+
struct shmem_inode_info {
spinlock_t lock;
unsigned long flags;
@@ -49,6 +58,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
/*
* Functions in mm/shmem.c called directly from elsewhere:
*/
+extern int is_shmem_file(struct file *file);
extern int init_tmpfs(void);
extern int shmem_fill_super(struct super_block *sb, void *data, int silent);
extern struct file *shmem_file_setup(const char *name,
diff --git a/mm/msync.c b/mm/msync.c
index 632df45..84cb068 100644
--- a/mm/msync.c
+++ b/mm/msync.c
@@ -13,6 +13,8 @@
#include <linux/file.h>
#include <linux/syscalls.h>
#include <linux/sched.h>
+#include <linux/shmem_fs.h>
+#include <asm/cacheflush.h>
/*
* MS_SYNC syncs the entire file - including mappings.
@@ -33,6 +35,7 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
unsigned long end;
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
+ struct file *file;
int unmapped_error = 0;
int error = -EINVAL;
@@ -56,8 +59,25 @@ SYSCALL_DEFINE3(msync, unsigned long, start, size_t, len, int, flags)
*/
down_read(&mm->mmap_sem);
vma = find_vma(mm, start);
+
+#ifdef CONFIG_TMPFS
+ /*
+ * For tmpfs, no matter which flag(ASYNC or SYNC) gets from msync,
+ * there is not so much thing to do for CPUs without cache alias,
+ * But for some CPUs with cache alias, msync has to flush cache
+ * explicitly, which makes sure the data coherency between memory
+ * file and cache.
+ */
+ file = vma->vm_file;
+ if (is_shmem_file(file)) {
+ if(CPU_HAS_CACHE_ALIAS)
+ flush_cache_range(vma, start, start+len);
+ error = 0;
+ goto out_unlock;
+ }
+#endif
+
for (;;) {
- struct file *file;
/* Still start < end. */
error = -ENOMEM;
diff --git a/mm/shmem.c b/mm/shmem.c
index 92e5c15..4fabfac 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -2793,6 +2793,11 @@ static struct file_system_type tmpfs_fs_type = {
.kill_sb = kill_litter_super,
};
+int is_shmem_file(struct file *file)
+{
+ return (file->f_op == &shmem_file_operations)? 1 : 0;
+}
+
int __init init_tmpfs(void)
{
int error;
--
1.7.5.4
More information about the yocto
mailing list