aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2016-10-25 15:14:36 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2016-10-26 16:41:08 -0700
commit39bbc0a9e345b30ef6a8122220f85bd1d691ea82 (patch)
tree8f522ad718adba89971c2189bb928e24805f9d2c
parent7f168643f47146150654aa0593c9b47b766ea26b (diff)
downloadxfsprogs-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.c46
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);
}
/*