> > +unsigned long shmem_get_unmapped_area(struct file *file, > + unsigned long uaddr, unsigned long len, > + unsigned long pgoff, unsigned long flags) > +{ > + unsigned long (*get_area)(struct file *, > + unsigned long, unsigned long, unsigned long, unsigned long); > + unsigned long addr; > + unsigned long offset; > + unsigned long inflated_len; > + unsigned long inflated_addr; > + unsigned long inflated_offset; > + > + if (len > TASK_SIZE) > + return -ENOMEM; > + > + get_area = current->mm->get_unmapped_area; > + addr = get_area(file, uaddr, len, pgoff, flags); > + > + if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) > + return addr; > + if (IS_ERR_VALUE(addr)) > + return addr; > + if (addr & ~PAGE_MASK) > + return addr; > + if (addr > TASK_SIZE - len) > + return addr; > + > + if (shmem_huge == SHMEM_HUGE_DENY) > + return addr; > + if (len < HPAGE_PMD_SIZE) > + return addr; > + if (flags & MAP_FIXED) > + return addr; > + /* > + * Our priority is to support MAP_SHARED mapped hugely; > + * and support MAP_PRIVATE mapped hugely too, until it is COWed. > + * But if caller specified an address hint, respect that as before. > + */ > + if (uaddr) > + return addr; > + > + if (shmem_huge != SHMEM_HUGE_FORCE) { > + struct super_block *sb; > + > + if (file) { > + VM_BUG_ON(file->f_op != &shmem_file_operations); > + sb = file_inode(file)->i_sb; > + } else { > + /* > + * Called directly from mm/mmap.c, or drivers/char/mem.c > + * for "/dev/zero", to create a shared anonymous object. > + */ > + if (IS_ERR(shm_mnt)) > + return addr; > + sb = shm_mnt->mnt_sb; > + } > + if (SHMEM_SB(sb)->huge != SHMEM_HUGE_NEVER) > + return addr; Try to ask for a larger arena if huge page is not disabled for the mount(s/!=/==/)? > + } > + > + offset = (pgoff << PAGE_SHIFT) & (HPAGE_PMD_SIZE-1); > + if (offset && offset + len < 2 * HPAGE_PMD_SIZE) > + return addr; > + if ((addr & (HPAGE_PMD_SIZE-1)) == offset) > + return addr; > + > + inflated_len = len + HPAGE_PMD_SIZE - PAGE_SIZE; > + if (inflated_len > TASK_SIZE) > + return addr; > + if (inflated_len < len) > + return addr; > + > + inflated_addr = get_area(NULL, 0, inflated_len, 0, flags); > + if (IS_ERR_VALUE(inflated_addr)) > + return addr; > + if (inflated_addr & ~PAGE_MASK) > + return addr; > + > + inflated_offset = inflated_addr & (HPAGE_PMD_SIZE-1); > + inflated_addr += offset - inflated_offset; > + if (inflated_offset > offset) > + inflated_addr += HPAGE_PMD_SIZE; > + > + if (inflated_addr > TASK_SIZE - len) > + return addr; > + return inflated_addr; > +} > + > -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a>