History

workqueue: implement WQ_NON_REENTRANT

With gcwq managing all the workers and work->data pointing to the last gcwq it was on, non-reentrance can be easily implemented by checking whether the work is still running on the previous gcwq on queueing. Implement it.

Tejun Heo committed 16 years ago

Commit 18aa9ef1 parent 7a22ad72 files · +30 −3Browse files

Showing the changes to kernel/workqueue.c (1 of 2 files). Show all

Unified · Split

kernel/workqueue.c+29−3
@@ -534,11 +534,37 @@ static void __queue_work(unsigned int cpu, struct workqueue_struct *wq, · 533 unmodified lines
534 534
535 debug_work_activate(work);535 debug_work_activate(work);
536 536
537 /* determine gcwq to use */537 /*
538 * Determine gcwq to use. SINGLE_CPU is inherently
539 * NON_REENTRANT, so test it first.
540 */
538 if (!(wq->flags & WQ_SINGLE_CPU)) {541 if (!(wq->flags & WQ_SINGLE_CPU)) {
539 /* just use the requested cpu for multicpu workqueues */542 struct global_cwq *last_gcwq;
543
544 /*
545 * It's multi cpu. If @wq is non-reentrant and @work
546 * was previously on a different cpu, it might still
547 * be running there, in which case the work needs to
548 * be queued on that cpu to guarantee non-reentrance.
549 */
540 gcwq = get_gcwq(cpu);550 gcwq = get_gcwq(cpu);
541 spin_lock_irqsave(&gcwq->lock, flags);551 if (wq->flags & WQ_NON_REENTRANT &&
552 (last_gcwq = get_work_gcwq(work)) && last_gcwq != gcwq) {
553 struct worker *worker;
554
555 spin_lock_irqsave(&last_gcwq->lock, flags);
556
557 worker = find_worker_executing_work(last_gcwq, work);
558
559 if (worker && worker->current_cwq->wq == wq)
560 gcwq = last_gcwq;
561 else {
562 /* meh... not running there, queue here */
563 spin_unlock_irqrestore(&last_gcwq->lock, flags);
564 spin_lock_irqsave(&gcwq->lock, flags);
565 }
566 } else
567 spin_lock_irqsave(&gcwq->lock, flags);
542 } else {568 } else {
543 unsigned int req_cpu = cpu;569 unsigned int req_cpu = cpu;
544 570

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t