From 58763a297405024d23d8f1d0bba3e6603660c4b6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 4 Feb 2009 15:11:58 -0800 Subject: kernel/async.c: fix printk warnings alpha: kernel/async.c: In function 'run_one_entry': kernel/async.c:141: warning: format '%lli' expects type 'long long int', but argument 2 has type 'async_cookie_t' kernel/async.c:149: warning: format '%lli' expects type 'long long int', but argument 2 has type 'async_cookie_t' kernel/async.c:149: warning: format '%lld' expects type 'long long int', but argument 4 has type 's64' kernel/async.c: In function 'async_synchronize_cookie_special': kernel/async.c:250: warning: format '%lli' expects type 'long long int', but argument 3 has type 's64' Cc: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/async.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'kernel/async.c') diff --git a/kernel/async.c b/kernel/async.c index 608b32b42812..67a2be71f517 100644 --- a/kernel/async.c +++ b/kernel/async.c @@ -138,15 +138,18 @@ static void run_one_entry(void) /* 3) run it (and print duration)*/ if (initcall_debug && system_state == SYSTEM_BOOTING) { - printk("calling %lli_%pF @ %i\n", entry->cookie, entry->func, task_pid_nr(current)); + printk("calling %lli_%pF @ %i\n", (long long)entry->cookie, + entry->func, task_pid_nr(current)); calltime = ktime_get(); } entry->func(entry->data, entry->cookie); if (initcall_debug && system_state == SYSTEM_BOOTING) { rettime = ktime_get(); delta = ktime_sub(rettime, calltime); - printk("initcall %lli_%pF returned 0 after %lld usecs\n", entry->cookie, - entry->func, ktime_to_ns(delta) >> 10); + printk("initcall %lli_%pF returned 0 after %lld usecs\n", + (long long)entry->cookie, + entry->func, + (long long)ktime_to_ns(delta) >> 10); } /* 4) remove it from the running queue */ @@ -247,7 +250,8 @@ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *r delta = ktime_sub(endtime, starttime); printk("async_continuing @ %i after %lli usec\n", - task_pid_nr(current), ktime_to_ns(delta) >> 10); + task_pid_nr(current), + (long long)ktime_to_ns(delta) >> 10); } } EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); -- cgit v1.2.2 From 7a89bbc74937cd74a6bcf109cfc7c032109639be Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 19 Jan 2009 13:45:28 +0100 Subject: async: Fix running list handling. async_schedule() should pass in async_running as the running list, and run_one_entry() should put the entry to be run on the provided running list instead of always on the generic one. Reported-by: Jonathan Corbet Signed-off-by: Cornelia Huck Signed-off-by: Arjan van de Ven --- kernel/async.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'kernel/async.c') diff --git a/kernel/async.c b/kernel/async.c index 67a2be71f517..0c90d500ab68 100644 --- a/kernel/async.c +++ b/kernel/async.c @@ -133,7 +133,7 @@ static void run_one_entry(void) /* 2) move it to the running queue */ list_del(&entry->list); - list_add_tail(&entry->list, &async_running); + list_add_tail(&entry->list, entry->running); spin_unlock_irqrestore(&async_lock, flags); /* 3) run it (and print duration)*/ @@ -210,7 +210,7 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l async_cookie_t async_schedule(async_func_ptr *ptr, void *data) { - return __async_schedule(ptr, data, &async_pending); + return __async_schedule(ptr, data, &async_running); } EXPORT_SYMBOL_GPL(async_schedule); -- cgit v1.2.2 From 86532d8b167e71e24da8b564348b52977b76d15f Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 19 Jan 2009 13:45:31 +0100 Subject: async: Handle kthread_run() return codes. If we fail to create the manager thread, fall back to non-fastboot. If we fail to create an async thread, try again after waiting for a bit. Signed-off-by: Cornelia Huck Signed-off-by: Arjan van de Ven --- kernel/async.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'kernel/async.c') diff --git a/kernel/async.c b/kernel/async.c index 0c90d500ab68..078d5ed150d1 100644 --- a/kernel/async.c +++ b/kernel/async.c @@ -54,6 +54,7 @@ asynchronous and synchronous parts of the kernel. #include #include #include +#include #include static async_cookie_t next_cookie = 1; @@ -319,7 +320,11 @@ static int async_manager_thread(void *unused) ec = atomic_read(&entry_count); while (tc < ec && tc < MAX_THREADS) { - kthread_run(async_thread, NULL, "async/%i", tc); + if (IS_ERR(kthread_run(async_thread, NULL, "async/%i", + tc))) { + msleep(100); + continue; + } atomic_inc(&thread_count); tc++; } @@ -334,7 +339,9 @@ static int async_manager_thread(void *unused) static int __init async_init(void) { if (async_enabled) - kthread_run(async_manager_thread, NULL, "async/mgr"); + if (IS_ERR(kthread_run(async_manager_thread, NULL, + "async/mgr"))) + async_enabled = 0; return 0; } -- cgit v1.2.2 From f30d5b307c694e03368ab55f2f96b0ca4131e775 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Mon, 19 Jan 2009 13:45:33 +0100 Subject: async: Add some documentation. Add some kerneldoc to the async interface. Signed-off-by: Cornelia Huck Signed-off-by: Arjan van de Ven --- kernel/async.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'kernel/async.c') diff --git a/kernel/async.c b/kernel/async.c index 078d5ed150d1..b5f0d4b94937 100644 --- a/kernel/async.c +++ b/kernel/async.c @@ -209,18 +209,43 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l return newcookie; } +/** + * async_schedule - schedule a function for asynchronous execution + * @ptr: function to execute asynchronously + * @data: data pointer to pass to the function + * + * Returns an async_cookie_t that may be used for checkpointing later. + * Note: This function may be called from atomic or non-atomic contexts. + */ async_cookie_t async_schedule(async_func_ptr *ptr, void *data) { return __async_schedule(ptr, data, &async_running); } EXPORT_SYMBOL_GPL(async_schedule); +/** + * async_schedule_special - schedule a function for asynchronous execution with a special running queue + * @ptr: function to execute asynchronously + * @data: data pointer to pass to the function + * @running: list head to add to while running + * + * Returns an async_cookie_t that may be used for checkpointing later. + * @running may be used in the async_synchronize_*_special() functions + * to wait on a special running queue rather than on the global running + * queue. + * Note: This function may be called from atomic or non-atomic contexts. + */ async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *running) { return __async_schedule(ptr, data, running); } EXPORT_SYMBOL_GPL(async_schedule_special); +/** + * async_synchronize_full - synchronize all asynchronous function calls + * + * This function waits until all asynchronous function calls have been done. + */ void async_synchronize_full(void) { do { @@ -229,12 +254,27 @@ void async_synchronize_full(void) } EXPORT_SYMBOL_GPL(async_synchronize_full); +/** + * async_synchronize_full_special - synchronize all asynchronous function calls for a running list + * @list: running list to synchronize on + * + * This function waits until all asynchronous function calls for the running + * list @list have been done. + */ void async_synchronize_full_special(struct list_head *list) { async_synchronize_cookie_special(next_cookie, list); } EXPORT_SYMBOL_GPL(async_synchronize_full_special); +/** + * async_synchronize_cookie_special - synchronize asynchronous function calls on a running list with cookie checkpointing + * @cookie: async_cookie_t to use as checkpoint + * @running: running list to synchronize on + * + * This function waits until all asynchronous function calls for the running + * list @list submitted prior to @cookie have been done. + */ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *running) { ktime_t starttime, delta, endtime; @@ -257,6 +297,13 @@ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *r } EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); +/** + * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing + * @cookie: async_cookie_t to use as checkpoint + * + * This function waits until all asynchronous function calls prior to @cookie + * have been done. + */ void async_synchronize_cookie(async_cookie_t cookie) { async_synchronize_cookie_special(cookie, &async_running); -- cgit v1.2.2 From 766ccb9ed406c230d13c145def08ebea1b932982 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Tue, 20 Jan 2009 15:31:31 +0100 Subject: async: Rename _special -> _domain for clarity. Rename the async_*_special() functions to async_*_domain(), which describes the purpose of these functions much better. [Broke up long lines to silence checkpatch] Signed-off-by: Cornelia Huck Signed-off-by: Arjan van de Ven --- kernel/async.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'kernel/async.c') diff --git a/kernel/async.c b/kernel/async.c index b5f0d4b94937..e23399d88bac 100644 --- a/kernel/async.c +++ b/kernel/async.c @@ -224,22 +224,23 @@ async_cookie_t async_schedule(async_func_ptr *ptr, void *data) EXPORT_SYMBOL_GPL(async_schedule); /** - * async_schedule_special - schedule a function for asynchronous execution with a special running queue + * async_schedule_domain - schedule a function for asynchronous execution within a certain domain * @ptr: function to execute asynchronously * @data: data pointer to pass to the function - * @running: list head to add to while running + * @running: running list for the domain * * Returns an async_cookie_t that may be used for checkpointing later. - * @running may be used in the async_synchronize_*_special() functions - * to wait on a special running queue rather than on the global running - * queue. + * @running may be used in the async_synchronize_*_domain() functions + * to wait within a certain synchronization domain rather than globally. + * A synchronization domain is specified via the running queue @running to use. * Note: This function may be called from atomic or non-atomic contexts. */ -async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *running) +async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, + struct list_head *running) { return __async_schedule(ptr, data, running); } -EXPORT_SYMBOL_GPL(async_schedule_special); +EXPORT_SYMBOL_GPL(async_schedule_domain); /** * async_synchronize_full - synchronize all asynchronous function calls @@ -255,27 +256,29 @@ void async_synchronize_full(void) EXPORT_SYMBOL_GPL(async_synchronize_full); /** - * async_synchronize_full_special - synchronize all asynchronous function calls for a running list + * async_synchronize_full_domain - synchronize all asynchronous function within a certain domain * @list: running list to synchronize on * - * This function waits until all asynchronous function calls for the running - * list @list have been done. + * This function waits until all asynchronous function calls for the + * synchronization domain specified by the running list @list have been done. */ -void async_synchronize_full_special(struct list_head *list) +void async_synchronize_full_domain(struct list_head *list) { - async_synchronize_cookie_special(next_cookie, list); + async_synchronize_cookie_domain(next_cookie, list); } -EXPORT_SYMBOL_GPL(async_synchronize_full_special); +EXPORT_SYMBOL_GPL(async_synchronize_full_domain); /** - * async_synchronize_cookie_special - synchronize asynchronous function calls on a running list with cookie checkpointing + * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing * @cookie: async_cookie_t to use as checkpoint * @running: running list to synchronize on * - * This function waits until all asynchronous function calls for the running - * list @list submitted prior to @cookie have been done. + * This function waits until all asynchronous function calls for the + * synchronization domain specified by the running list @list submitted + * prior to @cookie have been done. */ -void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *running) +void async_synchronize_cookie_domain(async_cookie_t cookie, + struct list_head *running) { ktime_t starttime, delta, endtime; @@ -295,7 +298,7 @@ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *r (long long)ktime_to_ns(delta) >> 10); } } -EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); +EXPORT_SYMBOL_GPL(async_synchronize_cookie_domain); /** * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing @@ -306,7 +309,7 @@ EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); */ void async_synchronize_cookie(async_cookie_t cookie) { - async_synchronize_cookie_special(cookie, &async_running); + async_synchronize_cookie_domain(cookie, &async_running); } EXPORT_SYMBOL_GPL(async_synchronize_cookie); -- cgit v1.2.2 From f7de7621f07495ad14fb23a812003bcf8f6af65a Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Mon, 2 Feb 2009 13:24:34 +0100 Subject: async: use list_move_tail list.h provides a dedicated primitive for "list_del followed by list_add_tail"... list_move_tail. Signed-off-by: Arjan van de Ven Signed-off-by: Stefan Richter --- kernel/async.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'kernel/async.c') diff --git a/kernel/async.c b/kernel/async.c index e23399d88bac..f565891f2c9b 100644 --- a/kernel/async.c +++ b/kernel/async.c @@ -133,8 +133,7 @@ static void run_one_entry(void) entry = list_first_entry(&async_pending, struct async_entry, list); /* 2) move it to the running queue */ - list_del(&entry->list); - list_add_tail(&entry->list, entry->running); + list_move_tail(&entry->list, entry->running); spin_unlock_irqrestore(&async_lock, flags); /* 3) run it (and print duration)*/ -- cgit v1.2.2