diff options
Diffstat (limited to 'kernel/workqueue.c')
-rw-r--r-- | kernel/workqueue.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 2f445833ae37..1fc2bc20603f 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/kallsyms.h> | 33 | #include <linux/kallsyms.h> |
34 | #include <linux/debug_locks.h> | 34 | #include <linux/debug_locks.h> |
35 | #include <linux/lockdep.h> | 35 | #include <linux/lockdep.h> |
36 | #include <trace/workqueue.h> | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * The per-CPU workqueue (if single thread, we always use the first | 39 | * The per-CPU workqueue (if single thread, we always use the first |
@@ -125,9 +126,13 @@ struct cpu_workqueue_struct *get_wq_data(struct work_struct *work) | |||
125 | return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK); | 126 | return (void *) (atomic_long_read(&work->data) & WORK_STRUCT_WQ_DATA_MASK); |
126 | } | 127 | } |
127 | 128 | ||
129 | DEFINE_TRACE(workqueue_insertion); | ||
130 | |||
128 | static void insert_work(struct cpu_workqueue_struct *cwq, | 131 | static void insert_work(struct cpu_workqueue_struct *cwq, |
129 | struct work_struct *work, struct list_head *head) | 132 | struct work_struct *work, struct list_head *head) |
130 | { | 133 | { |
134 | trace_workqueue_insertion(cwq->thread, work); | ||
135 | |||
131 | set_wq_data(work, cwq); | 136 | set_wq_data(work, cwq); |
132 | /* | 137 | /* |
133 | * Ensure that we get the right work->data if we see the | 138 | * Ensure that we get the right work->data if we see the |
@@ -259,6 +264,8 @@ int queue_delayed_work_on(int cpu, struct workqueue_struct *wq, | |||
259 | } | 264 | } |
260 | EXPORT_SYMBOL_GPL(queue_delayed_work_on); | 265 | EXPORT_SYMBOL_GPL(queue_delayed_work_on); |
261 | 266 | ||
267 | DEFINE_TRACE(workqueue_execution); | ||
268 | |||
262 | static void run_workqueue(struct cpu_workqueue_struct *cwq) | 269 | static void run_workqueue(struct cpu_workqueue_struct *cwq) |
263 | { | 270 | { |
264 | spin_lock_irq(&cwq->lock); | 271 | spin_lock_irq(&cwq->lock); |
@@ -284,7 +291,7 @@ static void run_workqueue(struct cpu_workqueue_struct *cwq) | |||
284 | */ | 291 | */ |
285 | struct lockdep_map lockdep_map = work->lockdep_map; | 292 | struct lockdep_map lockdep_map = work->lockdep_map; |
286 | #endif | 293 | #endif |
287 | 294 | trace_workqueue_execution(cwq->thread, work); | |
288 | cwq->current_work = work; | 295 | cwq->current_work = work; |
289 | list_del_init(cwq->worklist.next); | 296 | list_del_init(cwq->worklist.next); |
290 | spin_unlock_irq(&cwq->lock); | 297 | spin_unlock_irq(&cwq->lock); |
@@ -765,6 +772,8 @@ init_cpu_workqueue(struct workqueue_struct *wq, int cpu) | |||
765 | return cwq; | 772 | return cwq; |
766 | } | 773 | } |
767 | 774 | ||
775 | DEFINE_TRACE(workqueue_creation); | ||
776 | |||
768 | static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) | 777 | static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) |
769 | { | 778 | { |
770 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; | 779 | struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; |
@@ -787,6 +796,8 @@ static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) | |||
787 | sched_setscheduler_nocheck(p, SCHED_FIFO, ¶m); | 796 | sched_setscheduler_nocheck(p, SCHED_FIFO, ¶m); |
788 | cwq->thread = p; | 797 | cwq->thread = p; |
789 | 798 | ||
799 | trace_workqueue_creation(cwq->thread, cpu); | ||
800 | |||
790 | return 0; | 801 | return 0; |
791 | } | 802 | } |
792 | 803 | ||
@@ -868,6 +879,8 @@ struct workqueue_struct *__create_workqueue_key(const char *name, | |||
868 | } | 879 | } |
869 | EXPORT_SYMBOL_GPL(__create_workqueue_key); | 880 | EXPORT_SYMBOL_GPL(__create_workqueue_key); |
870 | 881 | ||
882 | DEFINE_TRACE(workqueue_destruction); | ||
883 | |||
871 | static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq) | 884 | static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq) |
872 | { | 885 | { |
873 | /* | 886 | /* |
@@ -891,6 +904,7 @@ static void cleanup_workqueue_thread(struct cpu_workqueue_struct *cwq) | |||
891 | * checks list_empty(), and a "normal" queue_work() can't use | 904 | * checks list_empty(), and a "normal" queue_work() can't use |
892 | * a dead CPU. | 905 | * a dead CPU. |
893 | */ | 906 | */ |
907 | trace_workqueue_destruction(cwq->thread); | ||
894 | kthread_stop(cwq->thread); | 908 | kthread_stop(cwq->thread); |
895 | cwq->thread = NULL; | 909 | cwq->thread = NULL; |
896 | } | 910 | } |