Re: [patch 05/14] syslets: core code

2007-02-16 Thread Davide Libenzi
On Thu, 15 Feb 2007, Ingo Molnar wrote:

> + spin_lock(>lock);
> +
> + new_async_thread = pick_ready_cachemiss_thread(ah);
> + if (!new_async_thread)
> + goto out_unlock;
> +
> + async_ready = t->async_ready;
> + WARN_ON(!async_ready);
> + t->async_ready = NULL;
> +
> + new_task = new_async_thread->task;
> +
> + move_user_context(new_task, t);

Since I lost the email where you were describing the todo list, I'll hook 
into this one.
I haven't seen you mentioning it, but at least TID and signal handling 
need to be swapped to. So it'd be better to have a generic 
move_user_context() that does system independent work, and an 
arch_move_user_context() that takes care of system dependent stuff (that 
is called by move_user_context()).



- Davide


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 05/14] syslets: core code

2007-02-16 Thread Davide Libenzi
On Thu, 15 Feb 2007, Ingo Molnar wrote:

 + spin_lock(ah-lock);
 +
 + new_async_thread = pick_ready_cachemiss_thread(ah);
 + if (!new_async_thread)
 + goto out_unlock;
 +
 + async_ready = t-async_ready;
 + WARN_ON(!async_ready);
 + t-async_ready = NULL;
 +
 + new_task = new_async_thread-task;
 +
 + move_user_context(new_task, t);

Since I lost the email where you were describing the todo list, I'll hook 
into this one.
I haven't seen you mentioning it, but at least TID and signal handling 
need to be swapped to. So it'd be better to have a generic 
move_user_context() that does system independent work, and an 
arch_move_user_context() that takes care of system dependent stuff (that 
is called by move_user_context()).



- Davide


-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 05/14] syslets: core code

2007-02-15 Thread Frederik Deweerdt
On Thu, Feb 15, 2007 at 05:52:28PM +0100, Ingo Molnar wrote:
> From: Ingo Molnar <[EMAIL PROTECTED]>
> +static struct syslet_uatom __user *
> +exec_atom(struct async_head *ah, struct task_struct *t,
> +   struct syslet_uatom __user *uatom)
> +{
> + struct syslet_uatom __user *last_uatom;
> + struct syslet_atom atom;
> + long ret;
> +
- run_next:
+   do {
> + if (unlikely(copy_uatom(, uatom)))
> + return ERR_PTR(-EFAULT);
> +
> + last_uatom = uatom;
> + ret = __exec_atom(t, );
> + if (unlikely(signal_pending(t) || need_resched()))
+   break;
-   goto stop;
> +
> + uatom = next_uatom(, uatom, ret);
+   } while(uatom);
-   if (uatom)
-   goto run_next;
-  stop:
> + /*
> +  * We do completion only in async context:
> +  */
> + if (t->at && complete_uatom(ah, t, , last_uatom))
> + return ERR_PTR(-EFAULT);
> +
> + return last_uatom;
> +}
Goto's are cool granted :), but IMO the "do {} while()" is more natural
here.
> +asmlinkage long
> +sys_async_register(struct async_head_user __user *ahu, unsigned int len)
> +{
> + struct task_struct *t = current;
> +
> + /*
> +  * This 'len' check enables future extension of
> +  * the async_head ABI:
> +  */
I'm not sure I understand why this isn't a '>' check. If you want to
extend the ABI, you'll add members to async_head_user. So you just need
to check that you understand all the information that userspace passes
to you, or did I missed something?
> + if (len != sizeof(struct async_head_user))
> + return -EINVAL;
> + /*
> +  * Already registered?
> +  */
> + if (t->ah)
> + return -EEXIST;
> +
> + return async_head_init(t, ahu);
> +}
> +

Regards,
Frederik
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 05/14] syslets: core code

2007-02-15 Thread Zach Brown



+static void
+__mark_async_thread_ready(struct async_thread *at, struct  
async_head *ah)

+{
+   list_del(>entry);
+   list_add_tail(>entry, >ready_async_threads);


+__mark_async_thread_busy(struct async_thread *at, struct  
async_head *ah)

+{
+   list_del(>entry);
+   list_add_tail(>entry, >busy_async_threads);


list_move_tail()?

- z
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[patch 05/14] syslets: core code

2007-02-15 Thread Ingo Molnar
From: Ingo Molnar <[EMAIL PROTECTED]>

the core syslet / async system calls infrastructure code.

Is built only if CONFIG_ASYNC_SUPPORT is enabled.

Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
Signed-off-by: Arjan van de Ven <[EMAIL PROTECTED]>
---
 kernel/Makefile |1 
 kernel/async.c  |  897 
 2 files changed, 898 insertions(+)

Index: linux/kernel/Makefile
===
--- linux.orig/kernel/Makefile
+++ linux/kernel/Makefile
@@ -10,6 +10,7 @@ obj-y = sched.o fork.o exec_domain.o
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
 
+obj-$(CONFIG_ASYNC_SUPPORT) += async.o
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
Index: linux/kernel/async.c
===
--- /dev/null
+++ linux/kernel/async.c
@@ -0,0 +1,897 @@
+/*
+ * kernel/async.c
+ *
+ * The syslet subsystem - asynchronous syscall execution support.
+ *
+ * Started by Ingo Molnar:
+ *
+ *  Copyright (C) 2007 Red Hat, Inc., Ingo Molnar <[EMAIL PROTECTED]>
+ *
+ * This file is released under the GPLv2.
+ *
+ * This code implements asynchronous syscalls via 'syslets'.
+ *
+ * Syslets consist of a set of 'syslet atoms' which are residing
+ * purely in user-space memory and have no kernel-space resource
+ * attached to them. These atoms can be linked to each other via
+ * pointers. Besides the fundamental ability to execute system
+ * calls, syslet atoms can also implement branches, loops and
+ * arithmetics.
+ *
+ * Thus syslets can be used to build small autonomous programs that
+ * the kernel can execute purely from kernel-space, without having
+ * to return to any user-space context. Syslets can be run by any
+ * unprivileged user-space application - they are executed safely
+ * by the kernel.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "async.h"
+
+typedef asmlinkage long (*syscall_fn_t)(long, long, long, long, long, long);
+
+extern syscall_fn_t sys_call_table[NR_syscalls];
+
+static void
+__mark_async_thread_ready(struct async_thread *at, struct async_head *ah)
+{
+   list_del(>entry);
+   list_add_tail(>entry, >ready_async_threads);
+   if (list_empty(>busy_async_threads))
+   wake_up(>wait);
+}
+
+static void
+mark_async_thread_ready(struct async_thread *at, struct async_head *ah)
+{
+   spin_lock(>lock);
+   __mark_async_thread_ready(at, ah);
+   spin_unlock(>lock);
+}
+
+static void
+__mark_async_thread_busy(struct async_thread *at, struct async_head *ah)
+{
+   list_del(>entry);
+   list_add_tail(>entry, >busy_async_threads);
+}
+
+static void
+mark_async_thread_busy(struct async_thread *at, struct async_head *ah)
+{
+   spin_lock(>lock);
+   __mark_async_thread_busy(at, ah);
+   spin_unlock(>lock);
+}
+
+static void
+__async_thread_init(struct task_struct *t, struct async_thread *at,
+   struct async_head *ah)
+{
+   INIT_LIST_HEAD(>entry);
+   at->exit = 0;
+   at->task = t;
+   at->ah = ah;
+   at->work = NULL;
+
+   t->at = at;
+   ah->nr_threads++;
+}
+
+static void
+async_thread_init(struct task_struct *t, struct async_thread *at,
+ struct async_head *ah)
+{
+   spin_lock(>lock);
+   __async_thread_init(t, at, ah);
+   __mark_async_thread_ready(at, ah);
+   spin_unlock(>lock);
+}
+
+
+static void
+async_thread_exit(struct async_thread *at, struct task_struct *t)
+{
+   struct async_head *ah = at->ah;
+
+   spin_lock(>lock);
+   list_del_init(>entry);
+   if (at->exit)
+   complete(>exit_done);
+   t->at = NULL;
+   at->task = NULL;
+   WARN_ON(!ah->nr_threads);
+   ah->nr_threads--;
+   spin_unlock(>lock);
+}
+
+static struct async_thread *
+pick_ready_cachemiss_thread(struct async_head *ah)
+{
+   struct list_head *head = >ready_async_threads;
+   struct async_thread *at;
+
+   if (list_empty(head))
+   return NULL;
+
+   at = list_entry(head->next, struct async_thread, entry);
+
+   return at;
+}
+
+void __async_schedule(struct task_struct *t)
+{
+   struct async_thread *new_async_thread;
+   struct async_thread *async_ready;
+   struct async_head *ah = t->ah;
+   struct task_struct *new_task;
+
+   spin_lock(>lock);
+
+   new_async_thread = pick_ready_cachemiss_thread(ah);
+   if (!new_async_thread)
+   goto out_unlock;
+
+   async_ready = t->async_ready;
+   WARN_ON(!async_ready);
+   t->async_ready = NULL;
+
+   new_task = new_async_thread->task;
+
+   move_user_context(new_task, t);
+
+   new_task->at = NULL;
+   t->ah = NULL;
+   new_task->ah = ah;
+
+   

[patch 05/14] syslets: core code

2007-02-15 Thread Ingo Molnar
From: Ingo Molnar [EMAIL PROTECTED]

the core syslet / async system calls infrastructure code.

Is built only if CONFIG_ASYNC_SUPPORT is enabled.

Signed-off-by: Ingo Molnar [EMAIL PROTECTED]
Signed-off-by: Arjan van de Ven [EMAIL PROTECTED]
---
 kernel/Makefile |1 
 kernel/async.c  |  897 
 2 files changed, 898 insertions(+)

Index: linux/kernel/Makefile
===
--- linux.orig/kernel/Makefile
+++ linux/kernel/Makefile
@@ -10,6 +10,7 @@ obj-y = sched.o fork.o exec_domain.o
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
hrtimer.o rwsem.o latency.o nsproxy.o srcu.o
 
+obj-$(CONFIG_ASYNC_SUPPORT) += async.o
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
Index: linux/kernel/async.c
===
--- /dev/null
+++ linux/kernel/async.c
@@ -0,0 +1,897 @@
+/*
+ * kernel/async.c
+ *
+ * The syslet subsystem - asynchronous syscall execution support.
+ *
+ * Started by Ingo Molnar:
+ *
+ *  Copyright (C) 2007 Red Hat, Inc., Ingo Molnar [EMAIL PROTECTED]
+ *
+ * This file is released under the GPLv2.
+ *
+ * This code implements asynchronous syscalls via 'syslets'.
+ *
+ * Syslets consist of a set of 'syslet atoms' which are residing
+ * purely in user-space memory and have no kernel-space resource
+ * attached to them. These atoms can be linked to each other via
+ * pointers. Besides the fundamental ability to execute system
+ * calls, syslet atoms can also implement branches, loops and
+ * arithmetics.
+ *
+ * Thus syslets can be used to build small autonomous programs that
+ * the kernel can execute purely from kernel-space, without having
+ * to return to any user-space context. Syslets can be run by any
+ * unprivileged user-space application - they are executed safely
+ * by the kernel.
+ */
+#include linux/syscalls.h
+#include linux/syslet.h
+#include linux/delay.h
+#include linux/async.h
+#include linux/sched.h
+#include linux/init.h
+#include linux/err.h
+
+#include asm/uaccess.h
+#include asm/unistd.h
+
+#include async.h
+
+typedef asmlinkage long (*syscall_fn_t)(long, long, long, long, long, long);
+
+extern syscall_fn_t sys_call_table[NR_syscalls];
+
+static void
+__mark_async_thread_ready(struct async_thread *at, struct async_head *ah)
+{
+   list_del(at-entry);
+   list_add_tail(at-entry, ah-ready_async_threads);
+   if (list_empty(ah-busy_async_threads))
+   wake_up(ah-wait);
+}
+
+static void
+mark_async_thread_ready(struct async_thread *at, struct async_head *ah)
+{
+   spin_lock(ah-lock);
+   __mark_async_thread_ready(at, ah);
+   spin_unlock(ah-lock);
+}
+
+static void
+__mark_async_thread_busy(struct async_thread *at, struct async_head *ah)
+{
+   list_del(at-entry);
+   list_add_tail(at-entry, ah-busy_async_threads);
+}
+
+static void
+mark_async_thread_busy(struct async_thread *at, struct async_head *ah)
+{
+   spin_lock(ah-lock);
+   __mark_async_thread_busy(at, ah);
+   spin_unlock(ah-lock);
+}
+
+static void
+__async_thread_init(struct task_struct *t, struct async_thread *at,
+   struct async_head *ah)
+{
+   INIT_LIST_HEAD(at-entry);
+   at-exit = 0;
+   at-task = t;
+   at-ah = ah;
+   at-work = NULL;
+
+   t-at = at;
+   ah-nr_threads++;
+}
+
+static void
+async_thread_init(struct task_struct *t, struct async_thread *at,
+ struct async_head *ah)
+{
+   spin_lock(ah-lock);
+   __async_thread_init(t, at, ah);
+   __mark_async_thread_ready(at, ah);
+   spin_unlock(ah-lock);
+}
+
+
+static void
+async_thread_exit(struct async_thread *at, struct task_struct *t)
+{
+   struct async_head *ah = at-ah;
+
+   spin_lock(ah-lock);
+   list_del_init(at-entry);
+   if (at-exit)
+   complete(ah-exit_done);
+   t-at = NULL;
+   at-task = NULL;
+   WARN_ON(!ah-nr_threads);
+   ah-nr_threads--;
+   spin_unlock(ah-lock);
+}
+
+static struct async_thread *
+pick_ready_cachemiss_thread(struct async_head *ah)
+{
+   struct list_head *head = ah-ready_async_threads;
+   struct async_thread *at;
+
+   if (list_empty(head))
+   return NULL;
+
+   at = list_entry(head-next, struct async_thread, entry);
+
+   return at;
+}
+
+void __async_schedule(struct task_struct *t)
+{
+   struct async_thread *new_async_thread;
+   struct async_thread *async_ready;
+   struct async_head *ah = t-ah;
+   struct task_struct *new_task;
+
+   spin_lock(ah-lock);
+
+   new_async_thread = pick_ready_cachemiss_thread(ah);
+   if (!new_async_thread)
+   goto out_unlock;
+
+   async_ready = t-async_ready;
+   WARN_ON(!async_ready);
+   t-async_ready = NULL;
+
+   new_task = new_async_thread-task;
+
+   

Re: [patch 05/14] syslets: core code

2007-02-15 Thread Zach Brown



+static void
+__mark_async_thread_ready(struct async_thread *at, struct  
async_head *ah)

+{
+   list_del(at-entry);
+   list_add_tail(at-entry, ah-ready_async_threads);


+__mark_async_thread_busy(struct async_thread *at, struct  
async_head *ah)

+{
+   list_del(at-entry);
+   list_add_tail(at-entry, ah-busy_async_threads);


list_move_tail()?

- z
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [patch 05/14] syslets: core code

2007-02-15 Thread Frederik Deweerdt
On Thu, Feb 15, 2007 at 05:52:28PM +0100, Ingo Molnar wrote:
 From: Ingo Molnar [EMAIL PROTECTED]
 +static struct syslet_uatom __user *
 +exec_atom(struct async_head *ah, struct task_struct *t,
 +   struct syslet_uatom __user *uatom)
 +{
 + struct syslet_uatom __user *last_uatom;
 + struct syslet_atom atom;
 + long ret;
 +
- run_next:
+   do {
 + if (unlikely(copy_uatom(atom, uatom)))
 + return ERR_PTR(-EFAULT);
 +
 + last_uatom = uatom;
 + ret = __exec_atom(t, atom);
 + if (unlikely(signal_pending(t) || need_resched()))
+   break;
-   goto stop;
 +
 + uatom = next_uatom(atom, uatom, ret);
+   } while(uatom);
-   if (uatom)
-   goto run_next;
-  stop:
 + /*
 +  * We do completion only in async context:
 +  */
 + if (t-at  complete_uatom(ah, t, atom, last_uatom))
 + return ERR_PTR(-EFAULT);
 +
 + return last_uatom;
 +}
Goto's are cool granted :), but IMO the do {} while() is more natural
here.
 +asmlinkage long
 +sys_async_register(struct async_head_user __user *ahu, unsigned int len)
 +{
 + struct task_struct *t = current;
 +
 + /*
 +  * This 'len' check enables future extension of
 +  * the async_head ABI:
 +  */
I'm not sure I understand why this isn't a '' check. If you want to
extend the ABI, you'll add members to async_head_user. So you just need
to check that you understand all the information that userspace passes
to you, or did I missed something?
 + if (len != sizeof(struct async_head_user))
 + return -EINVAL;
 + /*
 +  * Already registered?
 +  */
 + if (t-ah)
 + return -EEXIST;
 +
 + return async_head_init(t, ahu);
 +}
 +

Regards,
Frederik
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/