Re: [PATCH v2] nommu: add page_align to mmap

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Jun 3, 2011 at 2:37 PM, Greg Ungerer <gerg@xxxxxxxxxxxx> wrote:
> Hi Bob,
>
> On 06/05/11 16:03, Bob Liu wrote:
>>
>> Currently on nommu arch mmap(),mremap() and munmap() doesn't do
>> page_align()
>> which isn't consist with mmu arch and cause some issues.
>>
>> First, some drivers' mmap() function depends on vma->vm_end - vma->start
>> is
>> page aligned which is true on mmu arch but not on nommu. eg: uvc camera
>> driver.
>>
>> Second munmap() may return -EINVAL[split file] error in cases when end is
>> not
>> page aligned(passed into from userspace) but vma->vm_end is aligned dure
>> to
>> split or driver's mmap() ops.
>>
>> This patch add page align to fix those issues.
>
> This is actually causing me problems on head at the moment.
> git bisected to this patch as the cause.
>
> When booting on a ColdFire (m68knommu) target the init process (or
> there abouts at least) fails. Last console messages are:
>
> Â...
> ÂVFS: Mounted root (romfs filesystem) readonly on device 31:0.
> ÂFreeing unused kernel memory: 52k freed (0x401aa000 - 0x401b6000)
> ÂUnable to mmap process text, errno 22
>

Oh, bad news. I will try to reproduce it on my board.
If you are free please enable debug in nommu.c and then we can see what
caused the problem.

Thanks!

> I haven't really debugged it any further yet. But that error message
> comes from fs/binfmt_flat.c, it is reporting a failed do_mmap() call.
>
> Reverting that this patch and no more problem.
>
> Regards
> Greg
>
>
>
>> Changelog v1->v2:
>> - added more commit message
>>
>> Signed-off-by: Bob Liu<lliubbo@xxxxxxxxx>
>> ---
>> Âmm/nommu.c | Â 24 ++++++++++++++----------
>> Â1 files changed, 14 insertions(+), 10 deletions(-)
>>
>> diff --git a/mm/nommu.c b/mm/nommu.c
>> index c4c542c..3febfd9 100644
>> --- a/mm/nommu.c
>> +++ b/mm/nommu.c
>> @@ -1133,7 +1133,7 @@ static int do_mmap_private(struct vm_area_struct
>> *vma,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â unsigned long capabilities)
>> Â{
>> Â Â Â Âstruct page *pages;
>> - Â Â Â unsigned long total, point, n, rlen;
>> + Â Â Â unsigned long total, point, n;
>> Â Â Â Âvoid *base;
>> Â Â Â Âint ret, order;
>>
>> @@ -1157,13 +1157,12 @@ static int do_mmap_private(struct vm_area_struct
>> *vma,
>> Â Â Â Â Â Â Â Â * make a private copy of the data and map that instead */
>> Â Â Â Â}
>>
>> - Â Â Â rlen = PAGE_ALIGN(len);
>>
>> Â Â Â Â/* allocate some memory to hold the mapping
>> Â Â Â Â * - note that this may not return a page-aligned address if the
>> object
>> Â Â Â Â * Â we're allocating is smaller than a page
>> Â Â Â Â */
>> - Â Â Â order = get_order(rlen);
>> + Â Â Â order = get_order(len);
>> Â Â Â Âkdebug("alloc order %d for %lx", order, len);
>>
>> Â Â Â Âpages = alloc_pages(GFP_KERNEL, order);
>> @@ -1173,7 +1172,7 @@ static int do_mmap_private(struct vm_area_struct
>> *vma,
>> Â Â Â Âtotal = 1<< Âorder;
>> Â Â Â Âatomic_long_add(total,&mmap_pages_allocated);
>>
>> - Â Â Â point = rlen>> ÂPAGE_SHIFT;
>> + Â Â Â point = len>> ÂPAGE_SHIFT;
>>
>> Â Â Â Â/* we allocated a power-of-2 sized page set, so we may want to trim
>> off
>> Â Â Â Â * the excess */
>> @@ -1195,7 +1194,7 @@ static int do_mmap_private(struct vm_area_struct
>> *vma,
>> Â Â Â Âbase = page_address(pages);
>> Â Â Â Âregion->vm_flags = vma->vm_flags |= VM_MAPPED_COPY;
>> Â Â Â Âregion->vm_start = (unsigned long) base;
>> -    region->vm_end  = region->vm_start + rlen;
>> +    region->vm_end  = region->vm_start + len;
>>    Âregion->vm_top  = region->vm_start + (total<< ÂPAGE_SHIFT);
>>
>> Â Â Â Âvma->vm_start = region->vm_start;
>> @@ -1211,15 +1210,15 @@ static int do_mmap_private(struct vm_area_struct
>> *vma,
>>
>> Â Â Â Â Â Â Â Âold_fs = get_fs();
>> Â Â Â Â Â Â Â Âset_fs(KERNEL_DS);
>> - Â Â Â Â Â Â Â ret = vma->vm_file->f_op->read(vma->vm_file, base,
>> rlen,&fpos);
>> + Â Â Â Â Â Â Â ret = vma->vm_file->f_op->read(vma->vm_file, base,
>> len,&fpos);
>> Â Â Â Â Â Â Â Âset_fs(old_fs);
>>
>> Â Â Â Â Â Â Â Âif (ret< Â0)
>> Â Â Â Â Â Â Â Â Â Â Â Âgoto error_free;
>>
>> Â Â Â Â Â Â Â Â/* clear the last little bit */
>> - Â Â Â Â Â Â Â if (ret< Ârlen)
>> - Â Â Â Â Â Â Â Â Â Â Â memset(base + ret, 0, rlen - ret);
>> + Â Â Â Â Â Â Â if (ret< Âlen)
>> + Â Â Â Â Â Â Â Â Â Â Â memset(base + ret, 0, len - ret);
>>
>> Â Â Â Â}
>>
>> @@ -1268,6 +1267,7 @@ unsigned long do_mmap_pgoff(struct file *file,
>>
>> Â Â Â Â/* we ignore the address hint */
>> Â Â Â Âaddr = 0;
>> + Â Â Â len = PAGE_ALIGN(len);
>>
>> Â Â Â Â/* we've determined that we can make the mapping, now translate
>> what we
>> Â Â Â Â * now know into VMA flags */
>> @@ -1645,14 +1645,16 @@ int do_munmap(struct mm_struct *mm, unsigned long
>> start, size_t len)
>> Â{
>> Â Â Â Âstruct vm_area_struct *vma;
>> Â Â Â Âstruct rb_node *rb;
>> - Â Â Â unsigned long end = start + len;
>> + Â Â Â unsigned long end;
>> Â Â Â Âint ret;
>>
>> Â Â Â Âkenter(",%lx,%zx", start, len);
>>
>> - Â Â Â if (len == 0)
>> + Â Â Â if ((len = PAGE_ALIGN(len)) == 0)
>> Â Â Â Â Â Â Â Âreturn -EINVAL;
>>
>> + Â Â Â end = start + len;
>> +
>> Â Â Â Â/* find the first potentially overlapping VMA */
>> Â Â Â Âvma = find_vma(mm, start);
>> Â Â Â Âif (!vma) {
>> @@ -1773,6 +1775,8 @@ unsigned long do_mremap(unsigned long addr,
>> Â Â Â Âstruct vm_area_struct *vma;
>>
>> Â Â Â Â/* insanity checks first */
>> + Â Â Â old_len = PAGE_ALIGN(old_len);
>> + Â Â Â new_len = PAGE_ALIGN(new_len);
>> Â Â Â Âif (old_len == 0 || new_len == 0)
>> Â Â Â Â Â Â Â Âreturn (unsigned long) -EINVAL;
>>
>
>
> --
> ------------------------------------------------------------------------
> Greg Ungerer Â-- ÂPrincipal Engineer    ÂEMAIL:   gerg@xxxxxxxxxxxx
> SnapGear Group, McAfee           ÂPHONE:    +61 7 3435 2888
> 8 Gardner Close               FAX:     +61 7 3217 5323
> Milton, QLD, 4064, Australia        ÂWEB: http://www.SnapGear.com
>

-- 
Regards,
--Bob

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@xxxxxxxxxx  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]