Commit cb001095 authored by Jeff Mahoney's avatar Jeff Mahoney Committed by David Sterba

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: default avatarJeff Mahoney <jeffm@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 9f8d4909
...@@ -34,6 +34,10 @@ ...@@ -34,6 +34,10 @@
struct __btrfs_workqueue { struct __btrfs_workqueue {
struct workqueue_struct *normal_wq; struct workqueue_struct *normal_wq;
/* File system this workqueue services */
struct btrfs_fs_info *fs_info;
/* List head pointing to ordered work list */ /* List head pointing to ordered work list */
struct list_head ordered_list; struct list_head ordered_list;
...@@ -70,6 +74,18 @@ void btrfs_##name(struct work_struct *arg) \ ...@@ -70,6 +74,18 @@ void btrfs_##name(struct work_struct *arg) \
normal_work_helper(work); \ normal_work_helper(work); \
} }
struct btrfs_fs_info *
btrfs_workqueue_owner(struct __btrfs_workqueue *wq)
{
return wq->fs_info;
}
struct btrfs_fs_info *
btrfs_work_owner(struct btrfs_work *work)
{
return work->wq->fs_info;
}
BTRFS_WORK_HELPER(worker_helper); BTRFS_WORK_HELPER(worker_helper);
BTRFS_WORK_HELPER(delalloc_helper); BTRFS_WORK_HELPER(delalloc_helper);
BTRFS_WORK_HELPER(flush_delalloc_helper); BTRFS_WORK_HELPER(flush_delalloc_helper);
...@@ -94,14 +110,15 @@ BTRFS_WORK_HELPER(scrubnc_helper); ...@@ -94,14 +110,15 @@ BTRFS_WORK_HELPER(scrubnc_helper);
BTRFS_WORK_HELPER(scrubparity_helper); BTRFS_WORK_HELPER(scrubparity_helper);
static struct __btrfs_workqueue * static struct __btrfs_workqueue *
__btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active, __btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info, const char *name,
int thresh) unsigned int flags, int limit_active, int thresh)
{ {
struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_KERNEL); struct __btrfs_workqueue *ret = kzalloc(sizeof(*ret), GFP_KERNEL);
if (!ret) if (!ret)
return NULL; return NULL;
ret->fs_info = fs_info;
ret->limit_active = limit_active; ret->limit_active = limit_active;
atomic_set(&ret->pending, 0); atomic_set(&ret->pending, 0);
if (thresh == 0) if (thresh == 0)
...@@ -143,7 +160,8 @@ __btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active, ...@@ -143,7 +160,8 @@ __btrfs_alloc_workqueue(const char *name, unsigned int flags, int limit_active,
static inline void static inline void
__btrfs_destroy_workqueue(struct __btrfs_workqueue *wq); __btrfs_destroy_workqueue(struct __btrfs_workqueue *wq);
struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info,
const char *name,
unsigned int flags, unsigned int flags,
int limit_active, int limit_active,
int thresh) int thresh)
...@@ -153,7 +171,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, ...@@ -153,7 +171,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
if (!ret) if (!ret)
return NULL; return NULL;
ret->normal = __btrfs_alloc_workqueue(name, flags & ~WQ_HIGHPRI, ret->normal = __btrfs_alloc_workqueue(fs_info, name,
flags & ~WQ_HIGHPRI,
limit_active, thresh); limit_active, thresh);
if (!ret->normal) { if (!ret->normal) {
kfree(ret); kfree(ret);
...@@ -161,8 +180,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, ...@@ -161,8 +180,8 @@ struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name,
} }
if (flags & WQ_HIGHPRI) { if (flags & WQ_HIGHPRI) {
ret->high = __btrfs_alloc_workqueue(name, flags, limit_active, ret->high = __btrfs_alloc_workqueue(fs_info, name, flags,
thresh); limit_active, thresh);
if (!ret->high) { if (!ret->high) {
__btrfs_destroy_workqueue(ret->normal); __btrfs_destroy_workqueue(ret->normal);
kfree(ret); kfree(ret);
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#define __BTRFS_ASYNC_THREAD_ #define __BTRFS_ASYNC_THREAD_
#include <linux/workqueue.h> #include <linux/workqueue.h>
struct btrfs_fs_info;
struct btrfs_workqueue; struct btrfs_workqueue;
/* Internal use only */ /* Internal use only */
struct __btrfs_workqueue; struct __btrfs_workqueue;
...@@ -67,7 +68,8 @@ BTRFS_WORK_HELPER_PROTO(scrubnc_helper); ...@@ -67,7 +68,8 @@ BTRFS_WORK_HELPER_PROTO(scrubnc_helper);
BTRFS_WORK_HELPER_PROTO(scrubparity_helper); BTRFS_WORK_HELPER_PROTO(scrubparity_helper);
struct btrfs_workqueue *btrfs_alloc_workqueue(const char *name, struct btrfs_workqueue *btrfs_alloc_workqueue(struct btrfs_fs_info *fs_info,
const char *name,
unsigned int flags, unsigned int flags,
int limit_active, int limit_active,
int thresh); int thresh);
...@@ -80,4 +82,6 @@ void btrfs_queue_work(struct btrfs_workqueue *wq, ...@@ -80,4 +82,6 @@ void btrfs_queue_work(struct btrfs_workqueue *wq,
void btrfs_destroy_workqueue(struct btrfs_workqueue *wq); void btrfs_destroy_workqueue(struct btrfs_workqueue *wq);
void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max); void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max);
void btrfs_set_work_high_priority(struct btrfs_work *work); void btrfs_set_work_high_priority(struct btrfs_work *work);
struct btrfs_fs_info *btrfs_work_owner(struct btrfs_work *work);
struct btrfs_fs_info *btrfs_workqueue_owner(struct __btrfs_workqueue *wq);
#endif #endif
...@@ -2310,17 +2310,19 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info, ...@@ -2310,17 +2310,19 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info,
unsigned int flags = WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND; unsigned int flags = WQ_MEM_RECLAIM | WQ_FREEZABLE | WQ_UNBOUND;
fs_info->workers = fs_info->workers =
btrfs_alloc_workqueue("worker", flags | WQ_HIGHPRI, btrfs_alloc_workqueue(fs_info, "worker",
max_active, 16); flags | WQ_HIGHPRI, max_active, 16);
fs_info->delalloc_workers = fs_info->delalloc_workers =
btrfs_alloc_workqueue("delalloc", flags, max_active, 2); btrfs_alloc_workqueue(fs_info, "delalloc",
flags, max_active, 2);
fs_info->flush_workers = fs_info->flush_workers =
btrfs_alloc_workqueue("flush_delalloc", flags, max_active, 0); btrfs_alloc_workqueue(fs_info, "flush_delalloc",
flags, max_active, 0);
fs_info->caching_workers = fs_info->caching_workers =
btrfs_alloc_workqueue("cache", flags, max_active, 0); btrfs_alloc_workqueue(fs_info, "cache", flags, max_active, 0);
/* /*
* a higher idle thresh on the submit workers makes it much more * 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,41 +2330,48 @@ static int btrfs_init_workqueues(struct btrfs_fs_info *fs_info,
* devices * devices
*/ */
fs_info->submit_workers = fs_info->submit_workers =
btrfs_alloc_workqueue("submit", flags, btrfs_alloc_workqueue(fs_info, "submit", flags,
min_t(u64, fs_devices->num_devices, min_t(u64, fs_devices->num_devices,
max_active), 64); max_active), 64);
fs_info->fixup_workers = fs_info->fixup_workers =
btrfs_alloc_workqueue("fixup", flags, 1, 0); btrfs_alloc_workqueue(fs_info, "fixup", flags, 1, 0);
/* /*
* endios are largely parallel and should have a very * endios are largely parallel and should have a very
* low idle thresh * low idle thresh
*/ */
fs_info->endio_workers = fs_info->endio_workers =
btrfs_alloc_workqueue("endio", flags, max_active, 4); btrfs_alloc_workqueue(fs_info, "endio", flags, max_active, 4);
fs_info->endio_meta_workers = fs_info->endio_meta_workers =
btrfs_alloc_workqueue("endio-meta", flags, max_active, 4); btrfs_alloc_workqueue(fs_info, "endio-meta", flags,
max_active, 4);
fs_info->endio_meta_write_workers = fs_info->endio_meta_write_workers =
btrfs_alloc_workqueue("endio-meta-write", flags, max_active, 2); btrfs_alloc_workqueue(fs_info, "endio-meta-write", flags,
max_active, 2);
fs_info->endio_raid56_workers = fs_info->endio_raid56_workers =
btrfs_alloc_workqueue("endio-raid56", flags, max_active, 4); btrfs_alloc_workqueue(fs_info, "endio-raid56", flags,
max_active, 4);
fs_info->endio_repair_workers = fs_info->endio_repair_workers =
btrfs_alloc_workqueue("endio-repair", flags, 1, 0); btrfs_alloc_workqueue(fs_info, "endio-repair", flags, 1, 0);
fs_info->rmw_workers = fs_info->rmw_workers =
btrfs_alloc_workqueue("rmw", flags, max_active, 2); btrfs_alloc_workqueue(fs_info, "rmw", flags, max_active, 2);
fs_info->endio_write_workers = fs_info->endio_write_workers =
btrfs_alloc_workqueue("endio-write", flags, max_active, 2); btrfs_alloc_workqueue(fs_info, "endio-write", flags,
max_active, 2);
fs_info->endio_freespace_worker = fs_info->endio_freespace_worker =
btrfs_alloc_workqueue("freespace-write", flags, max_active, 0); btrfs_alloc_workqueue(fs_info, "freespace-write", flags,
max_active, 0);
fs_info->delayed_workers = fs_info->delayed_workers =
btrfs_alloc_workqueue("delayed-meta", flags, max_active, 0); btrfs_alloc_workqueue(fs_info, "delayed-meta", flags,
max_active, 0);
fs_info->readahead_workers = fs_info->readahead_workers =
btrfs_alloc_workqueue("readahead", flags, max_active, 2); btrfs_alloc_workqueue(fs_info, "readahead", flags,
max_active, 2);
fs_info->qgroup_rescan_workers = fs_info->qgroup_rescan_workers =
btrfs_alloc_workqueue("qgroup-rescan", flags, 1, 0); btrfs_alloc_workqueue(fs_info, "qgroup-rescan", flags, 1, 0);
fs_info->extent_workers = fs_info->extent_workers =
btrfs_alloc_workqueue("extent-refs", flags, btrfs_alloc_workqueue(fs_info, "extent-refs", flags,
min_t(u64, fs_devices->num_devices, min_t(u64, fs_devices->num_devices,
max_active), 8); max_active), 8);
......
...@@ -3781,27 +3781,27 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info, ...@@ -3781,27 +3781,27 @@ static noinline_for_stack int scrub_workers_get(struct btrfs_fs_info *fs_info,
if (fs_info->scrub_workers_refcnt == 0) { if (fs_info->scrub_workers_refcnt == 0) {
if (is_dev_replace) if (is_dev_replace)
fs_info->scrub_workers = fs_info->scrub_workers =
btrfs_alloc_workqueue("scrub", flags, btrfs_alloc_workqueue(fs_info, "scrub", flags,
1, 4); 1, 4);
else else
fs_info->scrub_workers = fs_info->scrub_workers =
btrfs_alloc_workqueue("scrub", flags, btrfs_alloc_workqueue(fs_info, "scrub", flags,
max_active, 4); max_active, 4);
if (!fs_info->scrub_workers) if (!fs_info->scrub_workers)
goto fail_scrub_workers; goto fail_scrub_workers;
fs_info->scrub_wr_completion_workers = fs_info->scrub_wr_completion_workers =
btrfs_alloc_workqueue("scrubwrc", flags, btrfs_alloc_workqueue(fs_info, "scrubwrc", flags,
max_active, 2); max_active, 2);
if (!fs_info->scrub_wr_completion_workers) if (!fs_info->scrub_wr_completion_workers)
goto fail_scrub_wr_completion_workers; goto fail_scrub_wr_completion_workers;
fs_info->scrub_nocow_workers = fs_info->scrub_nocow_workers =
btrfs_alloc_workqueue("scrubnc", flags, 1, 0); btrfs_alloc_workqueue(fs_info, "scrubnc", flags, 1, 0);
if (!fs_info->scrub_nocow_workers) if (!fs_info->scrub_nocow_workers)
goto fail_scrub_nocow_workers; goto fail_scrub_nocow_workers;
fs_info->scrub_parity_workers = fs_info->scrub_parity_workers =
btrfs_alloc_workqueue("scrubparity", flags, btrfs_alloc_workqueue(fs_info, "scrubparity", flags,
max_active, 2); max_active, 2);
if (!fs_info->scrub_parity_workers) if (!fs_info->scrub_parity_workers)
goto fail_scrub_parity_workers; goto fail_scrub_parity_workers;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment