Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/arjan/linux-2.6-async-update

* git://git.kernel.org/pub/scm/linux/kernel/git/arjan/linux-2.6-async-update:
async: use list_move_tail
async: Rename _special -> _domain for clarity.
async: Add some documentation.
async: Handle kthread_run() return codes.
async: Fix running list handling.

+76 -18
+2 -2
fs/super.c
··· 301 301 /* 302 302 * wait for asynchronous fs operations to finish before going further 303 303 */ 304 - async_synchronize_full_special(&sb->s_async_list); 304 + async_synchronize_full_domain(&sb->s_async_list); 305 305 306 306 /* bad name - it should be evict_inodes() */ 307 307 invalidate_inodes(sb); ··· 470 470 sb->s_count++; 471 471 spin_unlock(&sb_lock); 472 472 down_read(&sb->s_umount); 473 - async_synchronize_full_special(&sb->s_async_list); 473 + async_synchronize_full_domain(&sb->s_async_list); 474 474 if (sb->s_root && (wait || sb->s_dirt)) 475 475 sb->s_op->sync_fs(sb, wait); 476 476 up_read(&sb->s_umount);
+5 -3
include/linux/async.h
··· 17 17 typedef void (async_func_ptr) (void *data, async_cookie_t cookie); 18 18 19 19 extern async_cookie_t async_schedule(async_func_ptr *ptr, void *data); 20 - extern async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *list); 20 + extern async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, 21 + struct list_head *list); 21 22 extern void async_synchronize_full(void); 22 - extern void async_synchronize_full_special(struct list_head *list); 23 + extern void async_synchronize_full_domain(struct list_head *list); 23 24 extern void async_synchronize_cookie(async_cookie_t cookie); 24 - extern void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *list); 25 + extern void async_synchronize_cookie_domain(async_cookie_t cookie, 26 + struct list_head *list); 25 27
+69 -13
kernel/async.c
··· 54 54 #include <linux/sched.h> 55 55 #include <linux/init.h> 56 56 #include <linux/kthread.h> 57 + #include <linux/delay.h> 57 58 #include <asm/atomic.h> 58 59 59 60 static async_cookie_t next_cookie = 1; ··· 133 132 entry = list_first_entry(&async_pending, struct async_entry, list); 134 133 135 134 /* 2) move it to the running queue */ 136 - list_del(&entry->list); 137 - list_add_tail(&entry->list, &async_running); 135 + list_move_tail(&entry->list, entry->running); 138 136 spin_unlock_irqrestore(&async_lock, flags); 139 137 140 138 /* 3) run it (and print duration)*/ ··· 208 208 return newcookie; 209 209 } 210 210 211 + /** 212 + * async_schedule - schedule a function for asynchronous execution 213 + * @ptr: function to execute asynchronously 214 + * @data: data pointer to pass to the function 215 + * 216 + * Returns an async_cookie_t that may be used for checkpointing later. 217 + * Note: This function may be called from atomic or non-atomic contexts. 218 + */ 211 219 async_cookie_t async_schedule(async_func_ptr *ptr, void *data) 212 220 { 213 - return __async_schedule(ptr, data, &async_pending); 221 + return __async_schedule(ptr, data, &async_running); 214 222 } 215 223 EXPORT_SYMBOL_GPL(async_schedule); 216 224 217 - async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *running) 225 + /** 226 + * async_schedule_domain - schedule a function for asynchronous execution within a certain domain 227 + * @ptr: function to execute asynchronously 228 + * @data: data pointer to pass to the function 229 + * @running: running list for the domain 230 + * 231 + * Returns an async_cookie_t that may be used for checkpointing later. 232 + * @running may be used in the async_synchronize_*_domain() functions 233 + * to wait within a certain synchronization domain rather than globally. 234 + * A synchronization domain is specified via the running queue @running to use. 235 + * Note: This function may be called from atomic or non-atomic contexts. 236 + */ 237 + async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data, 238 + struct list_head *running) 218 239 { 219 240 return __async_schedule(ptr, data, running); 220 241 } 221 - EXPORT_SYMBOL_GPL(async_schedule_special); 242 + EXPORT_SYMBOL_GPL(async_schedule_domain); 222 243 244 + /** 245 + * async_synchronize_full - synchronize all asynchronous function calls 246 + * 247 + * This function waits until all asynchronous function calls have been done. 248 + */ 223 249 void async_synchronize_full(void) 224 250 { 225 251 do { ··· 254 228 } 255 229 EXPORT_SYMBOL_GPL(async_synchronize_full); 256 230 257 - void async_synchronize_full_special(struct list_head *list) 231 + /** 232 + * async_synchronize_full_domain - synchronize all asynchronous function within a certain domain 233 + * @list: running list to synchronize on 234 + * 235 + * This function waits until all asynchronous function calls for the 236 + * synchronization domain specified by the running list @list have been done. 237 + */ 238 + void async_synchronize_full_domain(struct list_head *list) 258 239 { 259 - async_synchronize_cookie_special(next_cookie, list); 240 + async_synchronize_cookie_domain(next_cookie, list); 260 241 } 261 - EXPORT_SYMBOL_GPL(async_synchronize_full_special); 242 + EXPORT_SYMBOL_GPL(async_synchronize_full_domain); 262 243 263 - void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *running) 244 + /** 245 + * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing 246 + * @cookie: async_cookie_t to use as checkpoint 247 + * @running: running list to synchronize on 248 + * 249 + * This function waits until all asynchronous function calls for the 250 + * synchronization domain specified by the running list @list submitted 251 + * prior to @cookie have been done. 252 + */ 253 + void async_synchronize_cookie_domain(async_cookie_t cookie, 254 + struct list_head *running) 264 255 { 265 256 ktime_t starttime, delta, endtime; 266 257 ··· 297 254 (long long)ktime_to_ns(delta) >> 10); 298 255 } 299 256 } 300 - EXPORT_SYMBOL_GPL(async_synchronize_cookie_special); 257 + EXPORT_SYMBOL_GPL(async_synchronize_cookie_domain); 301 258 259 + /** 260 + * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing 261 + * @cookie: async_cookie_t to use as checkpoint 262 + * 263 + * This function waits until all asynchronous function calls prior to @cookie 264 + * have been done. 265 + */ 302 266 void async_synchronize_cookie(async_cookie_t cookie) 303 267 { 304 - async_synchronize_cookie_special(cookie, &async_running); 268 + async_synchronize_cookie_domain(cookie, &async_running); 305 269 } 306 270 EXPORT_SYMBOL_GPL(async_synchronize_cookie); 307 271 ··· 369 319 ec = atomic_read(&entry_count); 370 320 371 321 while (tc < ec && tc < MAX_THREADS) { 372 - kthread_run(async_thread, NULL, "async/%i", tc); 322 + if (IS_ERR(kthread_run(async_thread, NULL, "async/%i", 323 + tc))) { 324 + msleep(100); 325 + continue; 326 + } 373 327 atomic_inc(&thread_count); 374 328 tc++; 375 329 } ··· 388 334 static int __init async_init(void) 389 335 { 390 336 if (async_enabled) 391 - kthread_run(async_manager_thread, NULL, "async/mgr"); 337 + if (IS_ERR(kthread_run(async_manager_thread, NULL, 338 + "async/mgr"))) 339 + async_enabled = 0; 392 340 return 0; 393 341 } 394 342