diff options
Diffstat (limited to 'kernel/async.c')
| -rw-r--r-- | kernel/async.c | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/kernel/async.c b/kernel/async.c index 64cc916299a5..608b32b42812 100644 --- a/kernel/async.c +++ b/kernel/async.c | |||
| @@ -65,6 +65,8 @@ static LIST_HEAD(async_pending); | |||
| 65 | static LIST_HEAD(async_running); | 65 | static LIST_HEAD(async_running); |
| 66 | static DEFINE_SPINLOCK(async_lock); | 66 | static DEFINE_SPINLOCK(async_lock); |
| 67 | 67 | ||
| 68 | static int async_enabled = 0; | ||
| 69 | |||
| 68 | struct async_entry { | 70 | struct async_entry { |
| 69 | struct list_head list; | 71 | struct list_head list; |
| 70 | async_cookie_t cookie; | 72 | async_cookie_t cookie; |
| @@ -88,12 +90,12 @@ extern int initcall_debug; | |||
| 88 | static async_cookie_t __lowest_in_progress(struct list_head *running) | 90 | static async_cookie_t __lowest_in_progress(struct list_head *running) |
| 89 | { | 91 | { |
| 90 | struct async_entry *entry; | 92 | struct async_entry *entry; |
| 91 | if (!list_empty(&async_pending)) { | 93 | if (!list_empty(running)) { |
| 92 | entry = list_first_entry(&async_pending, | 94 | entry = list_first_entry(running, |
| 93 | struct async_entry, list); | 95 | struct async_entry, list); |
| 94 | return entry->cookie; | 96 | return entry->cookie; |
| 95 | } else if (!list_empty(running)) { | 97 | } else if (!list_empty(&async_pending)) { |
| 96 | entry = list_first_entry(running, | 98 | entry = list_first_entry(&async_pending, |
| 97 | struct async_entry, list); | 99 | struct async_entry, list); |
| 98 | return entry->cookie; | 100 | return entry->cookie; |
| 99 | } else { | 101 | } else { |
| @@ -102,6 +104,17 @@ static async_cookie_t __lowest_in_progress(struct list_head *running) | |||
| 102 | } | 104 | } |
| 103 | 105 | ||
| 104 | } | 106 | } |
| 107 | |||
| 108 | static async_cookie_t lowest_in_progress(struct list_head *running) | ||
| 109 | { | ||
| 110 | unsigned long flags; | ||
| 111 | async_cookie_t ret; | ||
| 112 | |||
| 113 | spin_lock_irqsave(&async_lock, flags); | ||
| 114 | ret = __lowest_in_progress(running); | ||
| 115 | spin_unlock_irqrestore(&async_lock, flags); | ||
| 116 | return ret; | ||
| 117 | } | ||
| 105 | /* | 118 | /* |
| 106 | * pick the first pending entry and run it | 119 | * pick the first pending entry and run it |
| 107 | */ | 120 | */ |
| @@ -169,7 +182,7 @@ static async_cookie_t __async_schedule(async_func_ptr *ptr, void *data, struct l | |||
| 169 | * If we're out of memory or if there's too much work | 182 | * If we're out of memory or if there's too much work |
| 170 | * pending already, we execute synchronously. | 183 | * pending already, we execute synchronously. |
| 171 | */ | 184 | */ |
| 172 | if (!entry || atomic_read(&entry_count) > MAX_WORK) { | 185 | if (!async_enabled || !entry || atomic_read(&entry_count) > MAX_WORK) { |
| 173 | kfree(entry); | 186 | kfree(entry); |
| 174 | spin_lock_irqsave(&async_lock, flags); | 187 | spin_lock_irqsave(&async_lock, flags); |
| 175 | newcookie = next_cookie++; | 188 | newcookie = next_cookie++; |
| @@ -227,7 +240,7 @@ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *r | |||
| 227 | starttime = ktime_get(); | 240 | starttime = ktime_get(); |
| 228 | } | 241 | } |
| 229 | 242 | ||
| 230 | wait_event(async_done, __lowest_in_progress(running) >= cookie); | 243 | wait_event(async_done, lowest_in_progress(running) >= cookie); |
| 231 | 244 | ||
| 232 | if (initcall_debug && system_state == SYSTEM_BOOTING) { | 245 | if (initcall_debug && system_state == SYSTEM_BOOTING) { |
| 233 | endtime = ktime_get(); | 246 | endtime = ktime_get(); |
| @@ -316,8 +329,18 @@ static int async_manager_thread(void *unused) | |||
| 316 | 329 | ||
| 317 | static int __init async_init(void) | 330 | static int __init async_init(void) |
| 318 | { | 331 | { |
| 319 | kthread_run(async_manager_thread, NULL, "async/mgr"); | 332 | if (async_enabled) |
| 333 | kthread_run(async_manager_thread, NULL, "async/mgr"); | ||
| 320 | return 0; | 334 | return 0; |
| 321 | } | 335 | } |
| 322 | 336 | ||
| 337 | static int __init setup_async(char *str) | ||
| 338 | { | ||
| 339 | async_enabled = 1; | ||
| 340 | return 1; | ||
| 341 | } | ||
| 342 | |||
| 343 | __setup("fastboot", setup_async); | ||
| 344 | |||
| 345 | |||
| 323 | core_initcall(async_init); | 346 | core_initcall(async_init); |
