LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [patch 08/14] syslets: x86, add create_async_thread() method
@ 2007-02-15 16:52 Ingo Molnar
  2007-02-15 19:14 ` Davide Libenzi
  2007-02-17 11:44 ` Evgeniy Polyakov
  0 siblings, 2 replies; 3+ messages in thread
From: Ingo Molnar @ 2007-02-15 16:52 UTC (permalink / raw)
  To: linux-kernel
  Cc: Linus Torvalds, Arjan van de Ven, Christoph Hellwig,
	Andrew Morton, Alan Cox, Ulrich Drepper, Zach Brown,
	Evgeniy Polyakov, David S. Miller, Suparna Bhattacharya,
	Davide Libenzi, Thomas Gleixner

From: Ingo Molnar <mingo@elte.hu>

add the create_async_thread() way of creating kernel threads:
these threads first execute a kernel function and when they
return from it they execute user-space.

An architecture must implement this interface before it can turn
CONFIG_ASYNC_SUPPORT on.

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
---
 arch/i386/kernel/entry.S     |   25 +++++++++++++++++++++++++
 arch/i386/kernel/process.c   |   31 +++++++++++++++++++++++++++++++
 include/asm-i386/processor.h |    5 +++++
 3 files changed, 61 insertions(+)

Index: linux/arch/i386/kernel/entry.S
===================================================================
--- linux.orig/arch/i386/kernel/entry.S
+++ linux/arch/i386/kernel/entry.S
@@ -996,6 +996,31 @@ ENTRY(kernel_thread_helper)
 	CFI_ENDPROC
 ENDPROC(kernel_thread_helper)
 
+ENTRY(async_thread_helper)
+	CFI_STARTPROC
+	/*
+	 * Allocate space on the stack for pt-regs.
+	 * sizeof(struct pt_regs) == 64, and we've got 8 bytes on the
+	 * kernel stack already:
+	 */
+	subl $64-8, %esp
+	CFI_ADJUST_CFA_OFFSET 64
+	movl %edx,%eax
+	push %edx
+	CFI_ADJUST_CFA_OFFSET 4
+	call *%ebx
+	addl $4, %esp
+	CFI_ADJUST_CFA_OFFSET -4
+
+	movl %eax, PT_EAX(%esp)
+
+	GET_THREAD_INFO(%ebp)
+
+	jmp syscall_exit
+	CFI_ENDPROC
+ENDPROC(async_thread_helper)
+
+
 .section .rodata,"a"
 #include "syscall_table.S"
 
Index: linux/arch/i386/kernel/process.c
===================================================================
--- linux.orig/arch/i386/kernel/process.c
+++ linux/arch/i386/kernel/process.c
@@ -352,6 +352,37 @@ int kernel_thread(int (*fn)(void *), voi
 EXPORT_SYMBOL(kernel_thread);
 
 /*
+ * This gets run with %ebx containing the
+ * function to call, and %edx containing
+ * the "args".
+ */
+extern void async_thread_helper(void);
+
+/*
+ * Create an async thread
+ */
+int create_async_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+	struct pt_regs regs;
+
+	memset(&regs, 0, sizeof(regs));
+
+	regs.ebx = (unsigned long) fn;
+	regs.edx = (unsigned long) arg;
+
+	regs.xds = __USER_DS;
+	regs.xes = __USER_DS;
+	regs.xgs = __KERNEL_PDA;
+	regs.orig_eax = -1;
+	regs.eip = (unsigned long) async_thread_helper;
+	regs.xcs = __KERNEL_CS | get_kernel_rpl();
+	regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
+
+	/* Ok, create the new task.. */
+	return do_fork(flags, 0, &regs, 0, NULL, NULL);
+}
+
+/*
  * Free current thread data structures etc..
  */
 void exit_thread(void)
Index: linux/include/asm-i386/processor.h
===================================================================
--- linux.orig/include/asm-i386/processor.h
+++ linux/include/asm-i386/processor.h
@@ -472,6 +472,11 @@ extern void prepare_to_copy(struct task_
  */
 extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 
+/*
+ * create an async thread:
+ */
+extern int create_async_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
 extern unsigned long thread_saved_pc(struct task_struct *tsk);
 void show_trace(struct task_struct *task, struct pt_regs *regs, unsigned long *stack);
 

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [patch 08/14] syslets: x86, add create_async_thread() method
  2007-02-15 16:52 [patch 08/14] syslets: x86, add create_async_thread() method Ingo Molnar
@ 2007-02-15 19:14 ` Davide Libenzi
  2007-02-17 11:44 ` Evgeniy Polyakov
  1 sibling, 0 replies; 3+ messages in thread
From: Davide Libenzi @ 2007-02-15 19:14 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linux Kernel Mailing List, Linus Torvalds, Arjan van de Ven,
	Christoph Hellwig, Andrew Morton, Alan Cox, Ulrich Drepper,
	Zach Brown, Evgeniy Polyakov, David S. Miller,
	Suparna Bhattacharya, Thomas Gleixner

On Thu, 15 Feb 2007, Ingo Molnar wrote:

> +ENTRY(async_thread_helper)
> +	CFI_STARTPROC
> +	/*
> +	 * Allocate space on the stack for pt-regs.
> +	 * sizeof(struct pt_regs) == 64, and we've got 8 bytes on the
> +	 * kernel stack already:
> +	 */
> +	subl $64-8, %esp
> +	CFI_ADJUST_CFA_OFFSET 64

Maybe a comment here would help in explaining why we do need space for the 
extra pt_regs (on top of the one already allocated in do_fork()) ;)
It's not immediately clear that ret_from_fork and syscall_exit will issue 
two nested RESTORE_REGS.



- Davide



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [patch 08/14] syslets: x86, add create_async_thread() method
  2007-02-15 16:52 [patch 08/14] syslets: x86, add create_async_thread() method Ingo Molnar
  2007-02-15 19:14 ` Davide Libenzi
@ 2007-02-17 11:44 ` Evgeniy Polyakov
  1 sibling, 0 replies; 3+ messages in thread
From: Evgeniy Polyakov @ 2007-02-17 11:44 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, Linus Torvalds, Arjan van de Ven,
	Christoph Hellwig, Andrew Morton, Alan Cox, Ulrich Drepper,
	Zach Brown, David S. Miller, Suparna Bhattacharya,
	Davide Libenzi, Thomas Gleixner

On Thu, Feb 15, 2007 at 05:52:39PM +0100, Ingo Molnar (mingo@elte.hu) wrote:
> +/*
> + * Create an async thread
> + */
> +int create_async_thread(int (*fn)(void *), void * arg, unsigned long flags)
> +{
> +	struct pt_regs regs;
> +
> +	memset(&regs, 0, sizeof(regs));
> +
> +	regs.ebx = (unsigned long) fn;
> +	regs.edx = (unsigned long) arg;
> +
> +	regs.xds = __USER_DS;
> +	regs.xes = __USER_DS;
> +	regs.xgs = __KERNEL_PDA;
> +	regs.orig_eax = -1;
> +	regs.eip = (unsigned long) async_thread_helper;
> +	regs.xcs = __KERNEL_CS | get_kernel_rpl();
> +	regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
> +
> +	/* Ok, create the new task.. */
> +	return do_fork(flags, 0, &regs, 0, NULL, NULL);
> +}

What about complete disabling of signals and only enabling them in the
thread which returns to userspace?

-- 
	Evgeniy Polyakov

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2007-02-17 11:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-15 16:52 [patch 08/14] syslets: x86, add create_async_thread() method Ingo Molnar
2007-02-15 19:14 ` Davide Libenzi
2007-02-17 11:44 ` Evgeniy Polyakov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).