]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: use thread pools to sort rmap data
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 25 Oct 2016 22:14:36 +0000 (15:14 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 26 Oct 2016 23:41:08 +0000 (16:41 -0700)
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>
repair/slab.c

index 97c13d39f71902c7225e2a220fd0b53ea95d875d..86092704ab2a80d8d2521efc185a528f1695e2ec 100644 (file)
@@ -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);
 }
 
 /*