Nishanth,  

    I went through "munmap" code and found that core kernel (arch independent) 
code removes all "vma" references of the passed vaddr and then it calls arch 
dependent hooks. MIPS code removes all pagetable reference of the passed vaddr 
and flushes tlbs on all cpus. So after munmap returns, if process will try to 
access the same address again then it will receive a SIGSEGV signal. 

   I wrote a simple program (not linked with libhugetlbfs - see attachment) to 
cross check this on MIPS. The moment program does the "munmap" of the code 
segment it immediately receives a SIGSEGV.  Same program also crashes on x86 
with SIGSEGV. 

  Is this program, at a high level, very similar to libhugetlb init 
(constructor - munmap/mmap sequence) code ? If yes, then, Is there anything 
specific libhugetlbfs does before unmapping the code segment apart from copying 
all segments in to hugepages to make this work ?

Thanks,
Mehul.


--- On Wed, 12/31/08, Nishanth Aravamudan <n...@us.ibm.com> wrote:
From: Nishanth Aravamudan <n...@us.ibm.com>
Subject: Re: [Libhugetlbfs-devel] Lib hugetlbfs
To: "mehul vora" <mehu...@yahoo.com>
Cc: libhugetlbfs-devel@lists.sourceforge.net, a...@us.ibm.com
Date: Wednesday, December 31, 2008, 1:01 PM

On 31.12.2008 [07:26:38 -0800], mehul vora wrote:
> Nishanth,
> 
>  Couple of doubts... 
> 
> 1) Can't text remapping cause any problem with the "code"
being
> executed ? I mean, from  code (function - remap_segments() ) it looks
> like "code remaps itself". If any tlb exception  comes after
"munmap"
> then there is no valid pagetable entry for the code segment as
>  "munmap" removes page table reference ??

Right. That's why we resolve the mmap() symbol so that we don't need to
rely on the PLT or anything when we try to run mmap() without a text
segment. It's a real black hole there. If you take an exception, it will
fail, you're right. We've not seen that happen on power, x86, x86_64,
but is there something specific about MIPS that makes that a concern? I
don't know much about the MIPS arch. requirements or VM.

> 2) Why "prepare_segment" routine which copies passed
segment's data in
> to the hugepages is called from child process ? Can't parent do the
> same ? 

prepare_segment() is called by each process to try and remap a given
segment. I should say first, but that only matters in the case of
sharing.  In the non-sharing case, it doesn't, as there is no relation
between parent and child segments in terms of hugetlbfs. Each process is
independent, because we unlink the files (and thus hide the data from
any other process).

The only time you should consider parent/child relationships in
libhugetlbfs' remapping code, I'd say, is with sharing of segments
enabled. And then it's only for the text segment, and only because it's
read-only.

Thanks,
Nish

-- 
Nishanth Aravamudan <n...@us.ibm.com>
IBM Linux Technology Center



      
#define _GNU_SOURCE
#include <link.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static int
callback(struct dl_phdr_info *info, size_t size, void *data)
{
        int i;
        ElfW(Phdr) *phdr = NULL;

        printf("name=%s (%d segments)\n", info->dlpi_name,
                info->dlpi_phnum);

        mmap(0, 0, 0, 0, 0);
        for (i = 0; i < info->dlpi_phnum; i++) {
                if (info->dlpi_phdr[i].p_type != PT_LOAD){
                        printf("\nSegment %d is not PT_LOAD\n",i);
                        phdr = (ElfW(Phdr)*)&info->dlpi_phdr[i];
                        printf("p_vaddr [%#lx], file_size [%#lx], mem_size 
[%#lx], index = %d\n",
                                (unsigned long)phdr->p_vaddr,
                                (unsigned long)phdr->p_filesz, (unsigned 
long)phdr->p_memsz, i);
                }else{
                        printf("\nSegment %d is PT_LOAD\n",i);
                        phdr = (ElfW(Phdr)*)&info->dlpi_phdr[i];
                        printf("p_vaddr [%#lx], file_size [%#lx], mem_size 
[%#lx], index = %d\n",
                                (unsigned long)phdr->p_vaddr,
                                (unsigned long)phdr->p_filesz, (unsigned 
long)phdr->p_memsz, i);
                        printf("unmapping vaddr = %#lx, size 
%#lx\n",phdr->p_vaddr, phdr->p_memsz);
                        if(munmap(phdr->p_vaddr, phdr->p_memsz))
                        {
                                printf("munmap failed \n");
                        }
                        while(1);
                }
        }
    return 1;
}
static void __attribute__ ((constructor)) setup_libhugetlbfs(void)
{
        printf("Constructor called!!\n");
        dl_iterate_phdr(callback, NULL);
}

int main()
{
        printf("Hello World\n");
}
------------------------------------------------------------------------------
_______________________________________________
Libhugetlbfs-devel mailing list
Libhugetlbfs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel

Reply via email to