diff options
Diffstat (limited to 'include/linux/workqueue.h')
| -rw-r--r-- | include/linux/workqueue.h | 171 |
1 files changed, 152 insertions, 19 deletions
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 8afab27cdbc2..623488fdc1f5 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/lockdep.h> | 11 | #include <linux/lockdep.h> |
| 12 | #include <linux/threads.h> | 12 | #include <linux/threads.h> |
| 13 | #include <linux/atomic.h> | 13 | #include <linux/atomic.h> |
| 14 | #include <linux/cpumask.h> | ||
| 14 | 15 | ||
| 15 | struct workqueue_struct; | 16 | struct workqueue_struct; |
| 16 | 17 | ||
| @@ -68,7 +69,7 @@ enum { | |||
| 68 | WORK_STRUCT_COLOR_BITS, | 69 | WORK_STRUCT_COLOR_BITS, |
| 69 | 70 | ||
| 70 | /* data contains off-queue information when !WORK_STRUCT_PWQ */ | 71 | /* data contains off-queue information when !WORK_STRUCT_PWQ */ |
| 71 | WORK_OFFQ_FLAG_BASE = WORK_STRUCT_FLAG_BITS, | 72 | WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT, |
| 72 | 73 | ||
| 73 | WORK_OFFQ_CANCELING = (1 << WORK_OFFQ_FLAG_BASE), | 74 | WORK_OFFQ_CANCELING = (1 << WORK_OFFQ_FLAG_BASE), |
| 74 | 75 | ||
| @@ -91,6 +92,9 @@ enum { | |||
| 91 | /* bit mask for work_busy() return values */ | 92 | /* bit mask for work_busy() return values */ |
| 92 | WORK_BUSY_PENDING = 1 << 0, | 93 | WORK_BUSY_PENDING = 1 << 0, |
| 93 | WORK_BUSY_RUNNING = 1 << 1, | 94 | WORK_BUSY_RUNNING = 1 << 1, |
| 95 | |||
| 96 | /* maximum string length for set_worker_desc() */ | ||
| 97 | WORKER_DESC_LEN = 24, | ||
| 94 | }; | 98 | }; |
| 95 | 99 | ||
| 96 | struct work_struct { | 100 | struct work_struct { |
| @@ -115,6 +119,20 @@ struct delayed_work { | |||
| 115 | int cpu; | 119 | int cpu; |
| 116 | }; | 120 | }; |
| 117 | 121 | ||
| 122 | /* | ||
| 123 | * A struct for workqueue attributes. This can be used to change | ||
| 124 | * attributes of an unbound workqueue. | ||
| 125 | * | ||
| 126 | * Unlike other fields, ->no_numa isn't a property of a worker_pool. It | ||
| 127 | * only modifies how apply_workqueue_attrs() select pools and thus doesn't | ||
| 128 | * participate in pool hash calculations or equality comparisons. | ||
| 129 | */ | ||
| 130 | struct workqueue_attrs { | ||
| 131 | int nice; /* nice level */ | ||
| 132 | cpumask_var_t cpumask; /* allowed CPUs */ | ||
| 133 | bool no_numa; /* disable NUMA affinity */ | ||
| 134 | }; | ||
| 135 | |||
| 118 | static inline struct delayed_work *to_delayed_work(struct work_struct *work) | 136 | static inline struct delayed_work *to_delayed_work(struct work_struct *work) |
| 119 | { | 137 | { |
| 120 | return container_of(work, struct delayed_work, work); | 138 | return container_of(work, struct delayed_work, work); |
| @@ -283,9 +301,10 @@ enum { | |||
| 283 | WQ_MEM_RECLAIM = 1 << 3, /* may be used for memory reclaim */ | 301 | WQ_MEM_RECLAIM = 1 << 3, /* may be used for memory reclaim */ |
| 284 | WQ_HIGHPRI = 1 << 4, /* high priority */ | 302 | WQ_HIGHPRI = 1 << 4, /* high priority */ |
| 285 | WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ | 303 | WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ |
| 304 | WQ_SYSFS = 1 << 6, /* visible in sysfs, see wq_sysfs_register() */ | ||
| 286 | 305 | ||
| 287 | WQ_DRAINING = 1 << 6, /* internal: workqueue is draining */ | 306 | __WQ_DRAINING = 1 << 16, /* internal: workqueue is draining */ |
| 288 | WQ_RESCUER = 1 << 7, /* internal: workqueue has rescuer */ | 307 | __WQ_ORDERED = 1 << 17, /* internal: workqueue is ordered */ |
| 289 | 308 | ||
| 290 | WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ | 309 | WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ |
| 291 | WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ | 310 | WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ |
| @@ -388,7 +407,7 @@ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active, | |||
| 388 | * Pointer to the allocated workqueue on success, %NULL on failure. | 407 | * Pointer to the allocated workqueue on success, %NULL on failure. |
| 389 | */ | 408 | */ |
| 390 | #define alloc_ordered_workqueue(fmt, flags, args...) \ | 409 | #define alloc_ordered_workqueue(fmt, flags, args...) \ |
| 391 | alloc_workqueue(fmt, WQ_UNBOUND | (flags), 1, ##args) | 410 | alloc_workqueue(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags), 1, ##args) |
| 392 | 411 | ||
| 393 | #define create_workqueue(name) \ | 412 | #define create_workqueue(name) \ |
| 394 | alloc_workqueue((name), WQ_MEM_RECLAIM, 1) | 413 | alloc_workqueue((name), WQ_MEM_RECLAIM, 1) |
| @@ -399,30 +418,23 @@ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active, | |||
| 399 | 418 | ||
| 400 | extern void destroy_workqueue(struct workqueue_struct *wq); | 419 | extern void destroy_workqueue(struct workqueue_struct *wq); |
| 401 | 420 | ||
| 421 | struct workqueue_attrs *alloc_workqueue_attrs(gfp_t gfp_mask); | ||
| 422 | void free_workqueue_attrs(struct workqueue_attrs *attrs); | ||
| 423 | int apply_workqueue_attrs(struct workqueue_struct *wq, | ||
| 424 | const struct workqueue_attrs *attrs); | ||
| 425 | |||
| 402 | extern bool queue_work_on(int cpu, struct workqueue_struct *wq, | 426 | extern bool queue_work_on(int cpu, struct workqueue_struct *wq, |
| 403 | struct work_struct *work); | 427 | struct work_struct *work); |
| 404 | extern bool queue_work(struct workqueue_struct *wq, struct work_struct *work); | ||
| 405 | extern bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, | 428 | extern bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq, |
| 406 | struct delayed_work *work, unsigned long delay); | 429 | struct delayed_work *work, unsigned long delay); |
| 407 | extern bool queue_delayed_work(struct workqueue_struct *wq, | ||
| 408 | struct delayed_work *work, unsigned long delay); | ||
| 409 | extern bool mod_delayed_work_on(int cpu, struct workqueue_struct *wq, | 430 | extern bool mod_delayed_work_on(int cpu, struct workqueue_struct *wq, |
| 410 | struct delayed_work *dwork, unsigned long delay); | 431 | struct delayed_work *dwork, unsigned long delay); |
| 411 | extern bool mod_delayed_work(struct workqueue_struct *wq, | ||
| 412 | struct delayed_work *dwork, unsigned long delay); | ||
| 413 | 432 | ||
| 414 | extern void flush_workqueue(struct workqueue_struct *wq); | 433 | extern void flush_workqueue(struct workqueue_struct *wq); |
| 415 | extern void drain_workqueue(struct workqueue_struct *wq); | 434 | extern void drain_workqueue(struct workqueue_struct *wq); |
| 416 | extern void flush_scheduled_work(void); | 435 | extern void flush_scheduled_work(void); |
| 417 | 436 | ||
| 418 | extern bool schedule_work_on(int cpu, struct work_struct *work); | ||
| 419 | extern bool schedule_work(struct work_struct *work); | ||
| 420 | extern bool schedule_delayed_work_on(int cpu, struct delayed_work *work, | ||
| 421 | unsigned long delay); | ||
| 422 | extern bool schedule_delayed_work(struct delayed_work *work, | ||
| 423 | unsigned long delay); | ||
| 424 | extern int schedule_on_each_cpu(work_func_t func); | 437 | extern int schedule_on_each_cpu(work_func_t func); |
| 425 | extern int keventd_up(void); | ||
| 426 | 438 | ||
| 427 | int execute_in_process_context(work_func_t fn, struct execute_work *); | 439 | int execute_in_process_context(work_func_t fn, struct execute_work *); |
| 428 | 440 | ||
| @@ -435,8 +447,122 @@ extern bool cancel_delayed_work_sync(struct delayed_work *dwork); | |||
| 435 | 447 | ||
| 436 | extern void workqueue_set_max_active(struct workqueue_struct *wq, | 448 | extern void workqueue_set_max_active(struct workqueue_struct *wq, |
| 437 | int max_active); | 449 | int max_active); |
| 438 | extern bool workqueue_congested(unsigned int cpu, struct workqueue_struct *wq); | 450 | extern bool current_is_workqueue_rescuer(void); |
| 451 | extern bool workqueue_congested(int cpu, struct workqueue_struct *wq); | ||
| 439 | extern unsigned int work_busy(struct work_struct *work); | 452 | extern unsigned int work_busy(struct work_struct *work); |
| 453 | extern __printf(1, 2) void set_worker_desc(const char *fmt, ...); | ||
| 454 | extern void print_worker_info(const char *log_lvl, struct task_struct *task); | ||
| 455 | |||
| 456 | /** | ||
| 457 | * queue_work - queue work on a workqueue | ||
| 458 | * @wq: workqueue to use | ||
| 459 | * @work: work to queue | ||
| 460 | * | ||
| 461 | * Returns %false if @work was already on a queue, %true otherwise. | ||
| 462 | * | ||
| 463 | * We queue the work to the CPU on which it was submitted, but if the CPU dies | ||
| 464 | * it can be processed by another CPU. | ||
| 465 | */ | ||
| 466 | static inline bool queue_work(struct workqueue_struct *wq, | ||
| 467 | struct work_struct *work) | ||
| 468 | { | ||
| 469 | return queue_work_on(WORK_CPU_UNBOUND, wq, work); | ||
| 470 | } | ||
| 471 | |||
| 472 | /** | ||
| 473 | * queue_delayed_work - queue work on a workqueue after delay | ||
| 474 | * @wq: workqueue to use | ||
| 475 | * @dwork: delayable work to queue | ||
| 476 | * @delay: number of jiffies to wait before queueing | ||
| 477 | * | ||
| 478 | * Equivalent to queue_delayed_work_on() but tries to use the local CPU. | ||
| 479 | */ | ||
| 480 | static inline bool queue_delayed_work(struct workqueue_struct *wq, | ||
| 481 | struct delayed_work *dwork, | ||
| 482 | unsigned long delay) | ||
| 483 | { | ||
| 484 | return queue_delayed_work_on(WORK_CPU_UNBOUND, wq, dwork, delay); | ||
| 485 | } | ||
| 486 | |||
| 487 | /** | ||
| 488 | * mod_delayed_work - modify delay of or queue a delayed work | ||
| 489 | * @wq: workqueue to use | ||
| 490 | * @dwork: work to queue | ||
| 491 | * @delay: number of jiffies to wait before queueing | ||
| 492 | * | ||
| 493 | * mod_delayed_work_on() on local CPU. | ||
| 494 | */ | ||
| 495 | static inline bool mod_delayed_work(struct workqueue_struct *wq, | ||
| 496 | struct delayed_work *dwork, | ||
| 497 | unsigned long delay) | ||
| 498 | { | ||
| 499 | return mod_delayed_work_on(WORK_CPU_UNBOUND, wq, dwork, delay); | ||
| 500 | } | ||
| 501 | |||
| 502 | /** | ||
| 503 | * schedule_work_on - put work task on a specific cpu | ||
| 504 | * @cpu: cpu to put the work task on | ||
| 505 | * @work: job to be done | ||
| 506 | * | ||
| 507 | * This puts a job on a specific cpu | ||
| 508 | */ | ||
| 509 | static inline bool schedule_work_on(int cpu, struct work_struct *work) | ||
| 510 | { | ||
| 511 | return queue_work_on(cpu, system_wq, work); | ||
| 512 | } | ||
| 513 | |||
| 514 | /** | ||
| 515 | * schedule_work - put work task in global workqueue | ||
| 516 | * @work: job to be done | ||
| 517 | * | ||
| 518 | * Returns %false if @work was already on the kernel-global workqueue and | ||
| 519 | * %true otherwise. | ||
| 520 | * | ||
| 521 | * This puts a job in the kernel-global workqueue if it was not already | ||
| 522 | * queued and leaves it in the same position on the kernel-global | ||
| 523 | * workqueue otherwise. | ||
| 524 | */ | ||
| 525 | static inline bool schedule_work(struct work_struct *work) | ||
| 526 | { | ||
| 527 | return queue_work(system_wq, work); | ||
| 528 | } | ||
| 529 | |||
| 530 | /** | ||
| 531 | * schedule_delayed_work_on - queue work in global workqueue on CPU after delay | ||
| 532 | * @cpu: cpu to use | ||
| 533 | * @dwork: job to be done | ||
| 534 | * @delay: number of jiffies to wait | ||
| 535 | * | ||
| 536 | * After waiting for a given time this puts a job in the kernel-global | ||
| 537 | * workqueue on the specified CPU. | ||
| 538 | */ | ||
| 539 | static inline bool schedule_delayed_work_on(int cpu, struct delayed_work *dwork, | ||
| 540 | unsigned long delay) | ||
| 541 | { | ||
| 542 | return queue_delayed_work_on(cpu, system_wq, dwork, delay); | ||
| 543 | } | ||
| 544 | |||
| 545 | /** | ||
| 546 | * schedule_delayed_work - put work task in global workqueue after delay | ||
| 547 | * @dwork: job to be done | ||
| 548 | * @delay: number of jiffies to wait or 0 for immediate execution | ||
| 549 | * | ||
| 550 | * After waiting for a given time this puts a job in the kernel-global | ||
| 551 | * workqueue. | ||
| 552 | */ | ||
| 553 | static inline bool schedule_delayed_work(struct delayed_work *dwork, | ||
| 554 | unsigned long delay) | ||
| 555 | { | ||
| 556 | return queue_delayed_work(system_wq, dwork, delay); | ||
| 557 | } | ||
| 558 | |||
| 559 | /** | ||
| 560 | * keventd_up - is workqueue initialized yet? | ||
| 561 | */ | ||
| 562 | static inline bool keventd_up(void) | ||
| 563 | { | ||
| 564 | return system_wq != NULL; | ||
| 565 | } | ||
| 440 | 566 | ||
| 441 | /* | 567 | /* |
| 442 | * Like above, but uses del_timer() instead of del_timer_sync(). This means, | 568 | * Like above, but uses del_timer() instead of del_timer_sync(). This means, |
| @@ -466,12 +592,12 @@ static inline bool __deprecated flush_delayed_work_sync(struct delayed_work *dwo | |||
| 466 | } | 592 | } |
| 467 | 593 | ||
| 468 | #ifndef CONFIG_SMP | 594 | #ifndef CONFIG_SMP |
| 469 | static inline long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) | 595 | static inline long work_on_cpu(int cpu, long (*fn)(void *), void *arg) |
| 470 | { | 596 | { |
| 471 | return fn(arg); | 597 | return fn(arg); |
| 472 | } | 598 | } |
| 473 | #else | 599 | #else |
| 474 | long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg); | 600 | long work_on_cpu(int cpu, long (*fn)(void *), void *arg); |
| 475 | #endif /* CONFIG_SMP */ | 601 | #endif /* CONFIG_SMP */ |
| 476 | 602 | ||
| 477 | #ifdef CONFIG_FREEZER | 603 | #ifdef CONFIG_FREEZER |
| @@ -480,4 +606,11 @@ extern bool freeze_workqueues_busy(void); | |||
| 480 | extern void thaw_workqueues(void); | 606 | extern void thaw_workqueues(void); |
| 481 | #endif /* CONFIG_FREEZER */ | 607 | #endif /* CONFIG_FREEZER */ |
| 482 | 608 | ||
| 609 | #ifdef CONFIG_SYSFS | ||
| 610 | int workqueue_sysfs_register(struct workqueue_struct *wq); | ||
| 611 | #else /* CONFIG_SYSFS */ | ||
| 612 | static inline int workqueue_sysfs_register(struct workqueue_struct *wq) | ||
| 613 | { return 0; } | ||
| 614 | #endif /* CONFIG_SYSFS */ | ||
| 615 | |||
| 483 | #endif | 616 | #endif |
