diff options
author | Dave Kleikamp <shaggy@linux.vnet.ibm.com> | 2009-02-02 14:40:55 -0500 |
---|---|---|
committer | Dave Kleikamp <shaggy@linux.vnet.ibm.com> | 2009-02-02 14:40:55 -0500 |
commit | 8db0c5d5ef3ab99fe9e5151872b75f45c4282e3c (patch) | |
tree | da9759151e00221c58cdd9f4de893c0b08753670 /kernel/async.c | |
parent | 1ad53a98c927a9b5b1b57288ac0edec562fbcf8d (diff) | |
parent | 45c82b5a770be66845687a7d027c8b52946d59af (diff) |
Merge branch 'master' of /home/shaggy/git/linus-clean/
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); |