The previous patch db203d53d474aa068984e409d807628f5841da1b ("mm: tiny-shmem fix lock ordering: mmap_sem vs i_mutex") to fix the lock ordering in tiny-shmem breaks shared anonymous and IPC memory on NOMMU architectures because it was using the expanding truncate to signal ramfs to allocate a physically contiguous RAM backing the inode (otherwise it is unusable for "memory mapping" it to userspace). However do_truncate is what caused the lock ordering error, due to it taking i_mutex. In this case, we can actually just call ramfs directly to allocate memory for the mapping, rather than go via truncate.
Unified · Split
| @@ -58,7 +58,7 @@ const struct inode_operations ramfs_file_inode_operations = { · 57 unmodified lines | ||
| 58 | 58 | * size 0 on the assumption that it's going to be used for an mmap of shared |
| 59 | 59 | * memory |
| 60 | 60 | */ |
| 61 | −static int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |
| 61 | +int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize) | |
| 62 | 62 | { |
| 63 | 63 | struct pagevec lru_pvec; |
| 64 | 64 | unsigned long npages, xpages, loop, limit; |
| @@ -6,6 +6,7 @@ extern int ramfs_get_sb(struct file_system_type *fs_type, · 5 unmodified lines | ||
| 6 | 6 | int flags, const char *dev_name, void *data, struct vfsmount *mnt); |
| 7 | 7 | |
| 8 | 8 | #ifndef CONFIG_MMU |
| 9 | +extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize); | |
| 9 | 10 | extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file, |
| 10 | 11 | unsigned long addr, |
| 11 | 12 | unsigned long len, |
| @@ -80,6 +80,12 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags) · 79 unmodified lines | ||
| 80 | 80 | inode->i_nlink = 0; /* It is unlinked */ |
| 81 | 81 | init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ, |
| 82 | 82 | &ramfs_file_operations); |
| 83 | + | |
| 84 | +#ifndef CONFIG_MMU | |
| 85 | + error = ramfs_nommu_expand_for_mapping(inode, size); | |
| 86 | + if (error) | |
| 87 | + goto close_file; | |
| 88 | +#endif | |
| 83 | 89 | return file; |
| 84 | 90 | |
| 85 | 91 | close_file: |