From: Alex L. <ale...@st...> - 2005-05-17 09:38:51
|
Hi,all: In UML,when do_fork was called,the new process P will be created in UML. = Then in copy_thread_tt(in fact in start_fork_tramp)the corresponding = process Q will be created in the host linux. I know the pid of the = corresponding host process Q is appointed as the extern_pid of the UML = process P. But then how will the 2 processes do next individually? In UML,the function copy_thread_tt call start_fork_tramp, which cloned a = thread. Once the thread was created it will run the outer_tramp = function,in which cloned another thread. Once the second thread was = created it will run the tramp function(fork_tramp or new_thread_proc). = In fact the first thread is a temp one.it will kill itself later.Then = why does UML clone 2 threads in copy_thread_tt? In UML,when the kernel_thread was called,the UML kernel thread P will be = created in copy_process. And the corresponding host thread Q will be = create in copy_thread_tt. Then the host thread Q will run its SIGUSR1 = signal handler new_thread_handler,which will call run_kernel_thread = function and exited at last. But I think it should be the UML kernel = thread P that call run_kernel_thread function, any problems?=20 Thanks a lot! Alex |
From: Jeff D. <jd...@ad...> - 2005-05-17 16:25:48
|
On Tue, May 17, 2005 at 05:38:21PM +0800, Alex LIU wrote: > In UML,when do_fork was called,the new process P will be created in UML. Then in copy_thread_tt(in fact in start_fork_tramp)the corresponding process Q will be created in the host linux. I know the pid of the corresponding host process Q is appointed as the extern_pid of the UML process P. But then how will the 2 processes do next individually? They aren't really two processes. But they set up signal handlers, and the timer, and then go to sleep until that process is scheduled. > In UML,the function copy_thread_tt call start_fork_tramp, which cloned a thread. Once the thread was created it will run the outer_tramp function,in which cloned another thread. Once the second thread was created it will run the tramp function(fork_tramp or new_thread_proc). In fact the first thread is a temp one.it will kill itself later.Then why does UML clone 2 threads in copy_thread_tt? To avoid zombies - the parent process is expected to reap exited children, but as far as UML is concerned, the parent may not wake up for along time, leaving the child as a zombie for an arbitrary time. The two threads are the double-fork trick. The parent of the new process is the first temporary thread, which exits immediately, leaving the new child to be inherited by init, which will reap children immediately, eliminating zombies. > In UML,when the kernel_thread was called,the UML kernel thread P will be created in copy_process. And the corresponding host thread Q will be create in copy_thread_tt. Then the host thread Q will run its SIGUSR1 signal handler new_thread_handler,which will call run_kernel_thread function and exited at last. But I think it should be the UML kernel thread P that call run_kernel_thread function, any problems? P and Q are the same thing, so it makes no sense to say the handler should be run in one rather than the other. Jeff |
From: Alex L. <ale...@st...> - 2005-05-18 10:11:15
|
On May 17, 2005 11:54 PM, Jeff Dike wrote: >> In UML,when the kernel_thread was called,the UML kernel thread P will = >> be created in copy_process. And the corresponding host thread Q will=20 >> be create in copy_thread_tt. Then the host thread Q will run its=20 >> SIGUSR1 signal handler new_thread_handler,which will call=20 >> run_kernel_thread function and exited at last. But I think it should=20 >> be the UML kernel thread P that call run_kernel_thread function, any=20 >> problems? > P and Q are the same thing, so it makes no sense to say the handler = should be run in one rather than the other. But P and Q are different threads and they will be scheduled differently,right? Another question: when a kernel thread is created in UML, in the function outer_tramp the = temp thread A will clone the corresponding host thread B and then wait for it = to stop. The code is following: t->pid =3D clone(t->tramp, (void *) t->temp_stack + page_size()/2, t->flags, t->tramp_data); if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); And once the host thread B is created it will run new_thread_proc,in the function the thread send the signal SIGUSR1 to itself: os_usr1_process(os_getpid()); change_sig(SIGUSR1, 1); return(0); But I found the thread B will be blocked in the function = change_sig(SIGUSR1, 1). Why? And in the function outer_tramp, the thread A see the thread B was = stopped with a SIGSTOP signal. Why? Since the thread B is blocked by the signal SIGUSR1... Thanks a lot! Alex |
From: Jeff D. <jd...@ad...> - 2005-05-18 13:53:36
|
On Wed, May 18, 2005 at 06:04:31PM +0800, Alex LIU wrote: > But P and Q are different threads and they will be scheduled > differently,right? No, they're two different ways of looking at the same thread. They're scheduled somewhat differently, but that's just reflecting the two ways of looking at it. If it's runnable on the host, it's runnable inside UML, but not the other way around. > Another question: > when a kernel thread is created in UML, in the function outer_tramp the temp > thread A will clone the corresponding host thread B and then wait for it to > stop. The code is following: > > t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2, > t->flags, t->tramp_data); > if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); > > And once the host thread B is created it will run new_thread_proc,in the > function the thread send the signal SIGUSR1 to itself: > > os_usr1_process(os_getpid()); > change_sig(SIGUSR1, 1); > return(0); > > But I found the thread B will be blocked in the function change_sig(SIGUSR1, > 1). Why? It's not blocked there. That makes it enter the SIGUSR1 handler, which puts it on its kernel stack. > And in the function outer_tramp, the thread A see the thread B was stopped > with a SIGSTOP signal. Why? Since the thread B is blocked by the signal > SIGUSR1... The handler calls suspend_new_thread, which stops itself. Jeff |
From: Alex L. <ale...@st...> - 2005-05-19 09:58:30
|
On May 18, 2005 9:31 PM, Jeff wrote: >> But P and Q are different threads and they will be scheduled=20 >> differently,right? > No, they're two different ways of looking at the same thread. They're = > scheduled somewhat differently, but that's just reflecting the two = ways of looking at it. If it's runnable on the host, it's runnable inside UML, = but not the other way around. Then how does the UML thread interact with its corresponding host thread = in TT mode? Also use the switch_pipe? >> And in the function outer_tramp, the thread A see the thread B was=20 >> stopped with a SIGSTOP signal. Why? Since the thread B is blocked by=20 >> the signal SIGUSR1... > The handler calls suspend_new_thread, which stops itself. Exactly! I'm wrong... Then I have another question: In UML function new_thread_handler, the current sigcontext is defined as following: UPT_SC(¤t->thread.regs.regs) =3D (void *) (&sig + 1); Why? What does "&sig + 1" mean? Thanks a lot! Alex |
From: Blaisorblade <bla...@ya...> - 2005-05-19 13:32:06
|
On Thursday 19 May 2005 11:57, Alex LIU wrote: > On May 18, 2005 9:31 PM, Jeff wrote: > >> But P and Q are different threads and they will be scheduled > >> differently,right? > > No, they're two different ways of looking at the same thread. They're > > scheduled somewhat differently, but that's just reflecting the two ways > > of > looking at it. If it's runnable on the host, it's runnable inside UML, but > not the other way around. > Then how does the UML thread interact with its corresponding host thread in > TT mode? Also use the switch_pipe? > >> And in the function outer_tramp, the thread A see the thread B was > >> stopped with a SIGSTOP signal. Why? Since the thread B is blocked by > >> the signal SIGUSR1... > > The handler calls suspend_new_thread, which stops itself. > Exactly! I'm wrong... > Then I have another question: > In UML function new_thread_handler, the current sigcontext is defined as > following: > UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); > Why? What does "&sig + 1" mean? I think that's because sig is on the stack, and &sig + 1 points to the datas saved by the kernel when entering the signal handler, i.e. the registers of the caller, saved to be restored on return. -- Paolo Giarrusso, aka Blaisorblade Skype user "PaoloGiarrusso" Linux registered user n. 292729 http://www.user-mode-linux.org/~blaisorblade |
From: Jeff D. <jd...@ad...> - 2005-05-19 15:02:21
|
On Thu, May 19, 2005 at 03:31:30PM +0200, Blaisorblade wrote: > > Why? What does "&sig + 1" mean? > I think that's because sig is on the stack, and &sig + 1 points to the datas > saved by the kernel when entering the signal handler, i.e. the registers of > the caller, saved to be restored on return. Officially, it's the sigcontext structure. Jeff |