aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/async.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-04-08 11:25:42 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-08 11:26:00 -0400
commit5af8c4e0fac9838428bd718040b664043a05f37c (patch)
tree75a01d98ed244db45fe3c734c4a81c1a3d92ac37 /kernel/async.c
parent46e0bb9c12f4bab539736f1714cbf16600f681ec (diff)
parent577c9c456f0e1371cbade38eaf91ae8e8a308555 (diff)
Merge commit 'v2.6.30-rc1' into sched/urgent
Merge reason: update to latest upstream to queue up fix Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/async.c')
-rw-r--r--kernel/async.c94
1 files changed, 71 insertions, 23 deletions
diff --git a/kernel/async.c b/kernel/async.c
index 67a2be71f517..968ef9457d4e 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -49,11 +49,13 @@ asynchronous and synchronous parts of the kernel.
49*/ 49*/
50 50
51#include <linux/async.h> 51#include <linux/async.h>
52#include <linux/bug.h>
52#include <linux/module.h> 53#include <linux/module.h>
53#include <linux/wait.h> 54#include <linux/wait.h>
54#include <linux/sched.h> 55#include <linux/sched.h>
55#include <linux/init.h> 56#include <linux/init.h>
56#include <linux/kthread.h> 57#include <linux/kthread.h>
58#include <linux/delay.h>
57#include <asm/atomic.h> 59#include <asm/atomic.h>
58 60
59static async_cookie_t next_cookie = 1; 61static async_cookie_t next_cookie = 1;
@@ -132,8 +134,7 @@ static void run_one_entry(void)
132 entry = list_first_entry(&async_pending, struct async_entry, list); 134 entry = list_first_entry(&async_pending, struct async_entry, list);
133 135
134 /* 2) move it to the running queue */ 136 /* 2) move it to the running queue */
135 list_del(&entry->list); 137 list_move_tail(&entry->list, entry->running);
136 list_add_tail(&entry->list, &async_running);
137 spin_unlock_irqrestore(&async_lock, flags); 138 spin_unlock_irqrestore(&async_lock, flags);
138 139
139 /* 3) run it (and print duration)*/ 140 /* 3) run it (and print duration)*/
@@ -208,18 +209,44 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l
208 return newcookie; 209 return newcookie;
209} 210}
210 211
212/**
213 * async_schedule - schedule a function for asynchronous execution
214 * @ptr: function to execute asynchronously
215 * @data: data pointer to pass to the function
216 *
217 * Returns an async_cookie_t that may be used for checkpointing later.
218 * Note: This function may be called from atomic or non-atomic contexts.
219 */
211async_cookie_t async_schedule(async_func_ptr *ptr, void *data) 220async_cookie_t async_schedule(async_func_ptr *ptr, void *data)
212{ 221{
213 return __async_schedule(ptr, data, &async_pending); 222 return __async_schedule(ptr, data, &async_running);
214} 223}
215EXPORT_SYMBOL_GPL(async_schedule); 224EXPORT_SYMBOL_GPL(async_schedule);
216 225
217async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *running) 226/**
227 * async_schedule_domain - schedule a function for asynchronous execution within a certain domain
228 * @ptr: function to execute asynchronously
229 * @data: data pointer to pass to the function
230 * @running: running list for the domain
231 *
232 * Returns an async_cookie_t that may be used for checkpointing later.
233 * @running may be used in the async_synchronize_*_domain() functions
234 * to wait within a certain synchronization domain rather than globally.
235 * A synchronization domain is specified via the running queue @running to use.
236 * Note: This function may be called from atomic or non-atomic contexts.
237 */
238async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data,
239 struct list_head *running)
218{ 240{
219 return __async_schedule(ptr, data, running); 241 return __async_schedule(ptr, data, running);
220} 242}
221EXPORT_SYMBOL_GPL(async_schedule_special); 243EXPORT_SYMBOL_GPL(async_schedule_domain);
222 244
245/**
246 * async_synchronize_full - synchronize all asynchronous function calls
247 *
248 * This function waits until all asynchronous function calls have been done.
249 */
223void async_synchronize_full(void) 250void async_synchronize_full(void)
224{ 251{
225 do { 252 do {
@@ -228,13 +255,30 @@ void async_synchronize_full(void)
228} 255}
229EXPORT_SYMBOL_GPL(async_synchronize_full); 256EXPORT_SYMBOL_GPL(async_synchronize_full);
230 257
231void async_synchronize_full_special(struct list_head *list) 258/**
259 * async_synchronize_full_domain - synchronize all asynchronous function within a certain domain
260 * @list: running list to synchronize on
261 *
262 * This function waits until all asynchronous function calls for the
263 * synchronization domain specified by the running list @list have been done.
264 */
265void async_synchronize_full_domain(struct list_head *list)
232{ 266{
233 async_synchronize_cookie_special(next_cookie, list); 267 async_synchronize_cookie_domain(next_cookie, list);
234} 268}
235EXPORT_SYMBOL_GPL(async_synchronize_full_special); 269EXPORT_SYMBOL_GPL(async_synchronize_full_domain);
236 270
237void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *running) 271/**
272 * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing
273 * @cookie: async_cookie_t to use as checkpoint
274 * @running: running list to synchronize on
275 *
276 * This function waits until all asynchronous function calls for the
277 * synchronization domain specified by the running list @list submitted
278 * prior to @cookie have been done.
279 */
280void async_synchronize_cookie_domain(async_cookie_t cookie,
281 struct list_head *running)
238{ 282{
239 ktime_t starttime, delta, endtime; 283 ktime_t starttime, delta, endtime;
240 284
@@ -254,11 +298,18 @@ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *r
254 (long long)ktime_to_ns(delta) >> 10); 298 (long long)ktime_to_ns(delta) >> 10);
255 } 299 }
256} 300}
257EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); 301EXPORT_SYMBOL_GPL(async_synchronize_cookie_domain);
258 302
303/**
304 * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing
305 * @cookie: async_cookie_t to use as checkpoint
306 *
307 * This function waits until all asynchronous function calls prior to @cookie
308 * have been done.
309 */
259void async_synchronize_cookie(async_cookie_t cookie) 310void async_synchronize_cookie(async_cookie_t cookie)
260{ 311{
261 async_synchronize_cookie_special(cookie, &async_running); 312 async_synchronize_cookie_domain(cookie, &async_running);
262} 313}
263EXPORT_SYMBOL_GPL(async_synchronize_cookie); 314EXPORT_SYMBOL_GPL(async_synchronize_cookie);
264 315
@@ -319,7 +370,11 @@ static int async_manager_thread(void *unused)
319 ec = atomic_read(&entry_count); 370 ec = atomic_read(&entry_count);
320 371
321 while (tc < ec && tc < MAX_THREADS) { 372 while (tc < ec && tc < MAX_THREADS) {
322 kthread_run(async_thread, NULL, "async/%i", tc); 373 if (IS_ERR(kthread_run(async_thread, NULL, "async/%i",
374 tc))) {
375 msleep(100);
376 continue;
377 }
323 atomic_inc(&thread_count); 378 atomic_inc(&thread_count);
324 tc++; 379 tc++;
325 } 380 }
@@ -333,18 +388,11 @@ static int async_manager_thread(void *unused)
333 388
334static int __init async_init(void) 389static int __init async_init(void)
335{ 390{
336 if (async_enabled) 391 async_enabled =
337 kthread_run(async_manager_thread, NULL, "async/mgr"); 392 !IS_ERR(kthread_run(async_manager_thread, NULL, "async/mgr"));
338 return 0;
339}
340 393
341static int __init setup_async(char *str) 394 WARN_ON(!async_enabled);
342{ 395 return 0;
343 async_enabled = 1;
344 return 1;
345} 396}
346 397
347__setup("fastboot", setup_async);
348
349
350core_initcall(async_init); 398core_initcall(async_init);