diff options
author | Jeff Mahoney <jeffm@suse.com> | 2016-06-09 16:22:11 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2016-07-26 07:53:15 -0400 |
commit | cb001095ca705dcd95f57fe98867e38a4889916d (patch) | |
tree | 14a4d7643bf5b4a436f085615fbafd2575a09108 | |
parent | 9f8d49095b86d3494ee184f6ede4a5b179d5dc5c (diff) |
btrfs: plumb fs_info into btrfs_work
In order to provide an fsid for trace events, we'll need a btrfs_fs_info
pointer. The most lightweight way to do that for btrfs_work structures
is to associate it with the __btrfs_workqueue structure. Each queued
btrfs_work structure has a workqueue associated with it, so that's
a natural fit. It's a privately defined structures, so we add accessors
to retrieve the fs_info pointer.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r-- | fs/btrfs/async-thread.c | 31 | ||||
-rw-r--r-- | fs/btrfs/async-thread.h | 6 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 47 | ||||
-rw-r--r-- | fs/btrfs/scrub.c | 10 |
4 files changed, 63 insertions, 31 deletions
diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c index 5fb60ea7eee2..e0f071f6b5a7 100644 --- a/fs/btrfs/async-thread.c +++ b/fs/btrfs/async-thread.c | |||
@@ -34,6 +34,10 @@ | |||
34 | 34 | ||
35 | struct __btrfs_workqueue { | 35 | struct __btrfs_workqueue { |
36 | struct workqueue_struct *normal_wq; | 36 | struct workqueue_struct *normal_wq; |
37 | |||
38 | /* File system this workqueue services */ | ||
39 | struct btrfs_fs_info *fs_info; | ||
40 | |||
37 | /* List head pointing to ordered work list */ | 41 | /* List head pointing to ordered work list */ |
38 | struct list_head ordered_list; | 42 | struct list_head ordered_list; |
39 | 43 | ||
@@ -70,6 +74,18 @@ void btrfs_##name(struct work_struct *arg) \ | |||
70 | normal_work_helper(work); \ | 74 | normal_work_helper(work); \ |
71 | } | 75 | } |
72 | 76 | ||
77 | struct btrfs_fs_info * | ||
78 | btrfs_workqueue_owner(struct __btrfs_workqueue *wq) | ||
79 | { | ||
80 | return wq->fs_info; | ||
81 | } | ||
82 | |||
83 | struct btrfs_fs_info * | ||
84 | btrfs_work_owner(struct btrfs_work *work) | ||
85 | { | ||
86 | return work->wq->fs_info; | ||
87 | } | ||
88 | |||
73 | BTRFS_WORK_HELPER(worker_helper); | 89 | BTRFS_WORK_HELPER(worker_helper); |
74 | BTRFS_WORK_HELPER(delalloc_helper); | 90 | BTRFS_WORK_HELPER(delalloc_helper); |
75 | BTRFS_WORK_HELPER(flush_delalloc_helper); | 91 | BTRFS_WORK_HELPER(flush_delalloc_helper); |
@@ -94,14 +110,15 @@ BTRFS_WORK_HELPER(scrubnc_helper); | |||
94 | BTRFS_WORK_HELPER(scrubparity_helper); | 110 | BTRFS_WORK_HELPER(scrubparity_helper); |
95 | 111 | ||
96 | static struct __btrfs_workqueue * | 112 | static struct __btrfs_workqueue * |
97 | __btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active, | 113 | __btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info, const char *name, |
98 | int thresh) | 114 | unsigned int flags, int limit_active, int thresh) |
99 | { | 115 | { |
100 | struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_KERNEL); | 116 | struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_KERNEL); |
101 | 117 | ||
102 | if (!ret) | 118 | if (!ret) |
103 | return NULL; | 119 | return NULL; |
104 | 120 | ||
121 | ret->fs_info = fs_info; | ||
105 | ret->limit_active = limit_active; | 122 | ret->limit_active = limit_active; |
106 | atomic_set(&ret->pending, 0); | 123 | atomic_set(&ret->pending, 0); |
107 | if (thresh == 0) | 124 | if (thresh == 0) |
@@ -143,7 +160,8 @@ __btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active, | |||
143 | static inline void | 160 | static inline void |
144 | __btrfs_destroy_workqueue(struct __btrfs_workqueue *wq); | 161 | __btrfs_destroy_workqueue(struct __btrfs_workqueue *wq); |
145 | 162 | ||
146 | struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, | 163 | struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info, |
164 | const char *name, | ||
147 | unsigned int flags, | 165 | unsigned int flags, |
148 | int limit_active, | 166 | int limit_active, |
149 | int thresh) | 167 | int thresh) |
@@ -153,7 +171,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, | |||
153 | if (!ret) | 171 | if (!ret) |
154 | return NULL; | 172 | return NULL; |
155 | 173 | ||
156 | ret->normal = __btrfs_alloc_workqueue(name, flags & ~WQ_HIGHPRI, | 174 | ret->normal = __btrfs_alloc_workqueue(fs_info, name, |
175 | flags & ~WQ_HIGHPRI, | ||
157 | limit_active, thresh); | 176 | limit_active, thresh); |
158 | if (!ret->normal) { | 177 | if (!ret->normal) { |
159 | kfree(ret); | 178 | kfree(ret); |
@@ -161,8 +180,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, | |||
161 | } | 180 | } |
162 | 181 | ||
163 | if (flags & WQ_HIGHPRI) { | 182 | if (flags & WQ_HIGHPRI) { |
164 | ret->high = __btrfs_alloc_workqueue(name, flags, limit_active, | 183 | ret->high = __btrfs_alloc_workqueue(fs_info, name, flags, |
165 | thresh); | 184 | limit_active, thresh); |
166 | if (!ret->high) { | 185 | if (!ret->high) { |
167 | __btrfs_destroy_workqueue(ret->normal); | 186 | __btrfs_destroy_workqueue(ret->normal); |
168 | kfree(ret); | 187 | kfree(ret); |
diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h index ad4d0647d1a6..8e52484cd461 100644 --- a/fs/btrfs/async-thread.h +++ b/fs/btrfs/async-thread.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #define __BTRFS_ASYNC_THREAD_ | 21 | #define __BTRFS_ASYNC_THREAD_ |
22 | #include <linux/workqueue.h> | 22 | #include <linux/workqueue.h> |
23 | 23 | ||
24 | struct btrfs_fs_info; | ||
24 | struct btrfs_workqueue; | 25 | struct btrfs_workqueue; |
25 | /* Internal use only */ | 26 | /* Internal use only */ |
26 | struct __btrfs_workqueue; | 27 | struct __btrfs_workqueue; |
@@ -67,7 +68,8 @@ BTRFS_WORK_HELPER_PROTO(scrubnc_helper); | |||
67 | BTRFS_WORK_HELPER_PROTO(scrubparity_helper); | 68 | BTRFS_WORK_HELPER_PROTO(scrubparity_helper); |
68 | 69 | ||
69 | 70 | ||
70 | struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, | 71 | struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info, |
72 | const char *name, | ||
71 | unsigned int flags, | 73 | unsigned int flags, |
72 | int limit_active, | 74 | int limit_active, |
73 | int thresh); | 75 | int thresh); |
@@ -80,4 +82,6 @@ void btrfs_queue_work(struct btrfs_workqueue *wq, | |||
80 | void btrfs_destroy_workqueue(struct btrfs_workqueue *wq); | 82 | void btrfs_destroy_workqueue(struct btrfs_workqueue *wq); |
81 | void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max); | 83 | void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max); |
82 | void btrfs_set_work_high_priority(struct btrfs_work *work); | 84 | void btrfs_set_work_high_priority(struct btrfs_work *work); |
85 | struct btrfs_fs_info *btrfs_work_owner(struct btrfs_work *work); | ||
86 | struct btrfs_fs_info *btrfs_workqueue_owner(struct __btrfs_workqueue *wq); | ||
83 | #endif | 87 | #endif |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 49565626321e..cb6d13c39bee 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -2310,17 +2310,19 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info, | |||
2310 | unsigned int flags = WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND; | 2310 | unsigned int flags = WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND; |
2311 | 2311 | ||
2312 | fs_info->workers = | 2312 | fs_info->workers = |
2313 | btrfs_alloc_workqueue("worker", flags | WQ_HIGHPRI, | 2313 | btrfs_alloc_workqueue(fs_info, "worker", |
2314 | max_active, 16); | 2314 | flags | WQ_HIGHPRI, max_active, 16); |
2315 | 2315 | ||
2316 | fs_info->delalloc_workers = | 2316 | fs_info->delalloc_workers = |
2317 | btrfs_alloc_workqueue("delalloc", flags, max_active, 2); | 2317 | btrfs_alloc_workqueue(fs_info, "delalloc", |
2318 | flags, max_active, 2); | ||
2318 | 2319 | ||
2319 | fs_info->flush_workers = | 2320 | fs_info->flush_workers = |
2320 | btrfs_alloc_workqueue("flush_delalloc", flags, max_active, 0); | 2321 | btrfs_alloc_workqueue(fs_info, "flush_delalloc", |
2322 | flags, max_active, 0); | ||
2321 | 2323 | ||
2322 | fs_info->caching_workers = | 2324 | fs_info->caching_workers = |
2323 | btrfs_alloc_workqueue("cache", flags, max_active, 0); | 2325 | btrfs_alloc_workqueue(fs_info, "cache", flags, max_active, 0); |
2324 | 2326 | ||
2325 | /* | 2327 | /* |
2326 | * a higher idle thresh on the submit workers makes it much more | 2328 | * a higher idle thresh on the submit workers makes it much more |
@@ -2328,41 +2330,48 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info, | |||
2328 | * devices | 2330 | * devices |
2329 | */ | 2331 | */ |
2330 | fs_info->submit_workers = | 2332 | fs_info->submit_workers = |
2331 | btrfs_alloc_workqueue("submit", flags, | 2333 | btrfs_alloc_workqueue(fs_info, "submit", flags, |
2332 | min_t(u64, fs_devices->num_devices, | 2334 | min_t(u64, fs_devices->num_devices, |
2333 | max_active), 64); | 2335 | max_active), 64); |
2334 | 2336 | ||
2335 | fs_info->fixup_workers = | 2337 | fs_info->fixup_workers = |
2336 | btrfs_alloc_workqueue("fixup", flags, 1, 0); | 2338 | btrfs_alloc_workqueue(fs_info, "fixup", flags, 1, 0); |
2337 | 2339 | ||
2338 | /* | 2340 | /* |
2339 | * endios are largely parallel and should have a very | 2341 | * endios are largely parallel and should have a very |
2340 | * low idle thresh | 2342 | * low idle thresh |
2341 | */ | 2343 | */ |
2342 | fs_info->endio_workers = | 2344 | fs_info->endio_workers = |
2343 | btrfs_alloc_workqueue("endio", flags, max_active, 4); | 2345 | btrfs_alloc_workqueue(fs_info, "endio", flags, max_active, 4); |
2344 | fs_info->endio_meta_workers = | 2346 | fs_info->endio_meta_workers = |
2345 | btrfs_alloc_workqueue("endio-meta", flags, max_active, 4); | 2347 | btrfs_alloc_workqueue(fs_info, "endio-meta", flags, |
2348 | max_active, 4); | ||
2346 | fs_info->endio_meta_write_workers = | 2349 | fs_info->endio_meta_write_workers = |
2347 | btrfs_alloc_workqueue("endio-meta-write", flags, max_active, 2); | 2350 | btrfs_alloc_workqueue(fs_info, "endio-meta-write", flags, |
2351 | max_active, 2); | ||
2348 | fs_info->endio_raid56_workers = | 2352 | fs_info->endio_raid56_workers = |
2349 | btrfs_alloc_workqueue("endio-raid56", flags, max_active, 4); | 2353 | btrfs_alloc_workqueue(fs_info, "endio-raid56", flags, |
2354 | max_active, 4); | ||
2350 | fs_info->endio_repair_workers = | 2355 | fs_info->endio_repair_workers = |
2351 | btrfs_alloc_workqueue("endio-repair", flags, 1, 0); | 2356 | btrfs_alloc_workqueue(fs_info, "endio-repair", flags, 1, 0); |
2352 | fs_info->rmw_workers = | 2357 | fs_info->rmw_workers = |
2353 | btrfs_alloc_workqueue("rmw", flags, max_active, 2); | 2358 | btrfs_alloc_workqueue(fs_info, "rmw", flags, max_active, 2); |
2354 | fs_info->endio_write_workers = | 2359 | fs_info->endio_write_workers = |
2355 | btrfs_alloc_workqueue("endio-write", flags, max_active, 2); | 2360 | btrfs_alloc_workqueue(fs_info, "endio-write", flags, |
2361 | max_active, 2); | ||
2356 | fs_info->endio_freespace_worker = | 2362 | fs_info->endio_freespace_worker = |
2357 | btrfs_alloc_workqueue("freespace-write", flags, max_active, 0); | 2363 | btrfs_alloc_workqueue(fs_info, "freespace-write", flags, |
2364 | max_active, 0); | ||
2358 | fs_info->delayed_workers = | 2365 | fs_info->delayed_workers = |
2359 | btrfs_alloc_workqueue("delayed-meta", flags, max_active, 0); | 2366 | btrfs_alloc_workqueue(fs_info, "delayed-meta", flags, |
2367 | max_active, 0); | ||
2360 | fs_info->readahead_workers = | 2368 | fs_info->readahead_workers = |
2361 | btrfs_alloc_workqueue("readahead", flags, max_active, 2); | 2369 | btrfs_alloc_workqueue(fs_info, "readahead", flags, |
2370 | max_active, 2); | ||
2362 | fs_info->qgroup_rescan_workers = | 2371 | fs_info->qgroup_rescan_workers = |
2363 | btrfs_alloc_workqueue("qgroup-rescan", flags, 1, 0); | 2372 | btrfs_alloc_workqueue(fs_info, "qgroup-rescan", flags, 1, 0); |
2364 | fs_info->extent_workers = | 2373 | fs_info->extent_workers = |
2365 | btrfs_alloc_workqueue("extent-refs", flags, | 2374 | btrfs_alloc_workqueue(fs_info, "extent-refs", flags, |
2366 | min_t(u64, fs_devices->num_devices, | 2375 | min_t(u64, fs_devices->num_devices, |
2367 | max_active), 8); | 2376 | max_active), 8); |
2368 | 2377 | ||
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index acfe72004646..68c8a09ae7e5 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -3781,27 +3781,27 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info, | |||
3781 | if (fs_info->scrub_workers_refcnt == 0) { | 3781 | if (fs_info->scrub_workers_refcnt == 0) { |
3782 | if (is_dev_replace) | 3782 | if (is_dev_replace) |
3783 | fs_info->scrub_workers = | 3783 | fs_info->scrub_workers = |
3784 | btrfs_alloc_workqueue("scrub", flags, | 3784 | btrfs_alloc_workqueue(fs_info, "scrub", flags, |
3785 | 1, 4); | 3785 | 1, 4); |
3786 | else | 3786 | else |
3787 | fs_info->scrub_workers = | 3787 | fs_info->scrub_workers = |
3788 | btrfs_alloc_workqueue("scrub", flags, | 3788 | btrfs_alloc_workqueue(fs_info, "scrub", flags, |
3789 | max_active, 4); | 3789 | max_active, 4); |
3790 | if (!fs_info->scrub_workers) | 3790 | if (!fs_info->scrub_workers) |
3791 | goto fail_scrub_workers; | 3791 | goto fail_scrub_workers; |
3792 | 3792 | ||
3793 | fs_info->scrub_wr_completion_workers = | 3793 | fs_info->scrub_wr_completion_workers = |
3794 | btrfs_alloc_workqueue("scrubwrc", flags, | 3794 | btrfs_alloc_workqueue(fs_info, "scrubwrc", flags, |
3795 | max_active, 2); | 3795 | max_active, 2); |
3796 | if (!fs_info->scrub_wr_completion_workers) | 3796 | if (!fs_info->scrub_wr_completion_workers) |
3797 | goto fail_scrub_wr_completion_workers; | 3797 | goto fail_scrub_wr_completion_workers; |
3798 | 3798 | ||
3799 | fs_info->scrub_nocow_workers = | 3799 | fs_info->scrub_nocow_workers = |
3800 | btrfs_alloc_workqueue("scrubnc", flags, 1, 0); | 3800 | btrfs_alloc_workqueue(fs_info, "scrubnc", flags, 1, 0); |
3801 | if (!fs_info->scrub_nocow_workers) | 3801 | if (!fs_info->scrub_nocow_workers) |
3802 | goto fail_scrub_nocow_workers; | 3802 | goto fail_scrub_nocow_workers; |
3803 | fs_info->scrub_parity_workers = | 3803 | fs_info->scrub_parity_workers = |
3804 | btrfs_alloc_workqueue("scrubparity", flags, | 3804 | btrfs_alloc_workqueue(fs_info, "scrubparity", flags, |
3805 | max_active, 2); | 3805 | max_active, 2); |
3806 | if (!fs_info->scrub_parity_workers) | 3806 | if (!fs_info->scrub_parity_workers) |
3807 | goto fail_scrub_parity_workers; | 3807 | goto fail_scrub_parity_workers; |