Re: questions about segment and its relationship with TLS/NPTL

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

 



Mulyadi Santosa (mulyadi.santosa@xxxxxxxxx) wrote:
> Hello everyone..
> 
> I try to observe how TLS and NPTL work on kernel side.  I use Redhat 9 
> with stock kernel 2.4.20-19.9 and glibc-2.3.2-11.9.
> 
> I create a simple pthread test program which forks 2 threads and simply 
> print "Hello world" message. At the end, I call pthread_join two times 
> to cleanly terminate these two threads and finally terminate the main 
> program.
> 
> Strace-ing on the program shows me these interesting outputs (i am sorry 
> if the line wrapping screws code pasted below):
> 
> mmap2(NULL, 8388608, PROT_READ|PROT_WRITE|PROT_EXEC, 
> MAP_PRIVATE|MAP_ANONYMOUS,
> -1, 0) = 0x40037000
> brk(0)                                  = 0x8049824
> brk(0x804a824)                          = 0x804a824
> brk(0)                                  = 0x804a824
> brk(0x804b000)                          = 0x804b000
> mprotect(0x40037000, 4096, PROT_NONE)   = 0
> clone(child_stack=0x408368d0,flags=CLONE_VM|CLONE_FS|CLONE_FILES|
> CLONE_SIGHAND|CLONE_THREAD|CLONE_SETTLS|CLONE_PARENT_SETTID|
> CLONE_CHILD_CLEARTID|CLONE_DETACHED, 
> [4954],{entry_number:6,base_addr:0x40836cc0, 
> limit:1048575,seg_32bit:1,contents:0, read_exec_only:0, 
> limit_in_pages:1,seg_not_present:0, useable:1}) = 4954
> 
> On the other hand, inside arch/i386/kernel/process.c, i found codes that 
> handles CLONE_SETTLS flag (copy_thread() function ):
> 
> if (clone_flags & CLONE_SETTLS) {
>                 struct desc_struct *desc;
>                 struct user_desc info;
>                 int idx;
> 
>                 if (copy_from_user(&info, (void *)childregs->esi, 
> sizeof(info)))
>                         return -EFAULT;
>                 if (LDT_empty(&info))
>                         return -EINVAL;
> 
>                 idx = info.entry_number;
>                 if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
>                         return -EINVAL;
> 
>                 desc = p->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
>                 desc->a = LDT_entry_a(&info);
>                 desc->b = LDT_entry_b(&info);
>         }
> My questions is:
> 1. What is the purpose of allocating new LDT entry? Is it to provide new 
> segment for freshly created thread to store its thread-local data?
> 
> 2. Is the format of LDT entry 100% similar with GDT entry? If yes, what 
> is the advantage of using LDT for this threading purpose instead of 
> GDT?

Yes, it is the same on x86. See IA-32 Arch Software Developper Manual 3
, 3.4.5.1 and 3.5.

> 3. Observing strace results, it seems that the user space program 
> defines certain base address for new allocated segment along with other 
> attributes. On the kernel side, seems like these informations are 
> retrieved to construct new LDT entry. My early conclusions is: base 
> address is needed because thread local data (defined by __thread) only 
> contains offset, thus it needs base address to form a complete linear 
> address. Is this correct?
> 
> 4. I read somewhere on the Internet that gs register is used to point on 
> the currently used LDT entry related with currently running thread. Is 
> this just a convention which is used inside the libpthread? or is there 
> other explanation on why using gs register for this purpose?
> 
> thank your for your help...again, sorry for this long e-mail.......

						- Christophe

--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
FAQ:           http://kernelnewbies.org/faq/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux