From: Darrick J. Wong Date: Tue, 25 Oct 2016 22:14:36 +0000 (-0700) Subject: xfs_repair: use thread pools to sort rmap data X-Git-Tag: v4.9.0-rc1~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39bbc0a9e345b30ef6a8122220f85bd1d691ea82;p=thirdparty%2Fxfsprogs-dev.git 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 --- diff --git a/repair/slab.c b/repair/slab.c index 97c13d39f..86092704a 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); } /*