diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2016-10-25 15:14:36 -0700 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2016-10-26 16:41:08 -0700 |
commit | 39bbc0a9e345b30ef6a8122220f85bd1d691ea82 (patch) | |
tree | 8f522ad718adba89971c2189bb928e24805f9d2c | |
parent | 7f168643f47146150654aa0593c9b47b766ea26b (diff) | |
download | xfsprogs-dev-39bbc0a9e345b30ef6a8122220f85bd1d691ea82.tar.gz |
xfs_repair: use thread pools to sort rmap data
Since each slab is a collection of independent mini-slabs, we can
fire up a bunch of threads to sort the mini-slabs in parallel.
This speeds up the sorting phase of the rmapbt rebuilding if we
have a large number of mini slabs.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r-- | repair/slab.c | 46 |
1 files changed, 44 insertions, 2 deletions
diff --git a/repair/slab.c b/repair/slab.c index 97c13d39f7..86092704ab 100644 --- a/repair/slab.c +++ b/repair/slab.c @@ -201,6 +201,27 @@ slab_add( return 0; } +#include "threads.h" + +struct qsort_slab { + struct xfs_slab *slab; + struct xfs_slab_hdr *hdr; + int (*compare_fn)(const void *, const void *); +}; + +static void +qsort_slab_helper( + struct work_queue *wq, + xfs_agnumber_t agno, + void *arg) +{ + struct qsort_slab *qs = arg; + + qsort(slab_ptr(qs->slab, qs->hdr, 0), qs->hdr->sh_inuse, + qs->slab->s_item_sz, qs->compare_fn); + free(qs); +} + /* * Sort the items in the slab. Do not run this method if there are any * cursors holding on to the slab. @@ -210,14 +231,35 @@ qsort_slab( struct xfs_slab *slab, int (*compare_fn)(const void *, const void *)) { + struct work_queue wq; struct xfs_slab_hdr *hdr; + struct qsort_slab *qs; + + /* + * If we don't have that many slabs, we're probably better + * off skipping all the thread overhead. + */ + if (slab->s_nr_slabs <= 4) { + hdr = slab->s_first; + while (hdr) { + qsort(slab_ptr(slab, hdr, 0), hdr->sh_inuse, + slab->s_item_sz, compare_fn); + hdr = hdr->sh_next; + } + return; + } + create_work_queue(&wq, NULL, libxfs_nproc()); hdr = slab->s_first; while (hdr) { - qsort(slab_ptr(slab, hdr, 0), hdr->sh_inuse, slab->s_item_sz, - compare_fn); + qs = malloc(sizeof(struct qsort_slab)); + qs->slab = slab; + qs->hdr = hdr; + qs->compare_fn = compare_fn; + queue_work(&wq, qsort_slab_helper, 0, qs); hdr = hdr->sh_next; } + destroy_work_queue(&wq); } /* |