[yocto] [V2 PATCH 1/1] mm: msync: fix issues of sys_msync on tmpfs
Bruce Ashfield
bruce.ashfield at windriver.com
Thu Dec 22 06:24:57 PST 2011
On 11-12-21 10:07 PM, Zumeng Chen wrote:
> 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.
Looks good. I'll queue this for the next kernel update.
Cheers,
Bruce
>
> 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;
More information about the yocto
mailing list