hammer2 - Beef up bulkfree buffering
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 21 May 2018 05:59:37 +0000 (22:59 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 21 May 2018 05:59:37 +0000 (22:59 -0700)
* Beef up the bulkfree buffering to allow a lot more memory
  to be used for the in-memory freemap copy.

* Add a -m mem[k,m,g] override option for hammer2 bulkfree.

* Reduce console spam.

sbin/hammer2/cmd_bulkfree.c
sbin/hammer2/cmd_service.c
sbin/hammer2/hammer2.8
sbin/hammer2/hammer2.h
sbin/hammer2/main.c
sys/vfs/hammer2/hammer2_bulkfree.c

index 7029627..0c25203 100644 (file)
@@ -53,6 +53,9 @@ cmd_bulkfree(const char *sel_path)
        if (bfi.size < 8192 * 1024)
                bfi.size = 8192 * 1024;
 
+       if (MemOpt)
+               bfi.size = (MemOpt + 8192 * 1024 - 1) & ~(8192 * 1024 - 1L);
+
        if ((fd = hammer2_ioctl_handle(sel_path)) < 0)
                return 1;
        res = ioctl(fd, HAMMER2IOC_BULKFREE_SCAN, &bfi);
index bdaf3c1..dbb613a 100644 (file)
@@ -386,6 +386,8 @@ hammer2_volconf_thread(void *info)
 {
        hammer2_media_config_t *conf = info;
 
+       setproctitle("hammer2 volconf");
+
        pthread_mutex_lock(&confmtx);
        while ((conf->ctl & H2CONFCTL_STOP) == 0) {
                if (conf->ctl & H2CONFCTL_UPDATE) {
@@ -500,6 +502,7 @@ udev_thread(void *data __unused)
        int     seq = 0;
 
        pthread_detach(pthread_self());
+       setproctitle("hammer2 udev_thread");
 
        if ((fd = open(UDEV_DEVICE_PATH, O_RDWR)) < 0) {
                fprintf(stderr, "udev_thread: unable to open \"%s\"\n",
@@ -537,6 +540,7 @@ autoconn_thread(void *data __unused)
        lmod = 0;
 
        pthread_detach(pthread_self());
+       setproctitle("hammer2 autoconn_thread");
        for (;;) {
                /*
                 * Polling interval
@@ -699,6 +703,7 @@ autoconn_connect_thread(void *data)
 
        ac = data;
        pthread_detach(pthread_self());
+       setproctitle("hammer2 dmsg");
 
        while (ac->stopme == 0) {
                fd = dmsg_connect(ac->host);
index 8ed8cae..513f8bf 100644 (file)
@@ -43,6 +43,7 @@
 .Op Fl s Ar path
 .Op Fl t Ar type
 .Op Fl u Ar uuid
+.Op Fl m Ar mem
 .Ar command
 .Op Ar argument ...
 .Sh DESCRIPTION
@@ -69,6 +70,13 @@ random uuid will be generated.
 Note that every PFS also has a unique pfs_id which is always generated
 and cannot be overridden with an option.
 The { pfs_clid, pfs_fsid } tuple uniquely identifies a component of a cluster.
+.It Fl m Ar mem
+Specify how much tracking memory to use for certain directives.
+At the moment, this option is only applicable to the
+.Cm bulkfree
+directive, allowing it to operate in fewer passes when given more memory.
+A nominal value for a 4TB drive with a ton of stuff on it would be around
+a gigabyte '-m 1g'.
 .El
 .Pp
 .Nm
@@ -343,6 +351,10 @@ Run a bulkfree pass on a HAMMER2 mount.
 You can specify any PFS for the mount, the bulkfree pass is run on the
 entire partition.
 Note that it takes two passes to actually free space.
+By default this directive will use up to 1/16 physical memory to track
+the freemap.  The amount of memory used may be overridden with the
+.Op Fl m Ar mem
+option.
 .El
 .Sh SYSCTLS
 .Bl -tag -width indent
index 3ef7c1a..09beed4 100644 (file)
@@ -116,6 +116,7 @@ extern int RecurseOpt;
 extern int VerboseOpt;
 extern int QuietOpt;
 extern int NormalExit;
+extern size_t MemOpt;
 
 /*
  * Hammer2 command APIs
index d434401..bcbce7e 100644 (file)
@@ -41,6 +41,7 @@ int QuietOpt;
 int NormalExit = 1;    /* if set to 0 main() has to pthread_exit() */
 int RecurseOpt;
 int ForceOpt;
+size_t MemOpt;
 
 static void usage(int code);
 
@@ -50,6 +51,7 @@ main(int ac, char **av)
        const char *sel_path = NULL;
        const char *uuid_str = NULL;
        const char *arg;
+       char *opt;
        int pfs_type = HAMMER2_PFSTYPE_NONE;
        int all_opt = 0;
        int ecode = 0;
@@ -62,7 +64,7 @@ main(int ac, char **av)
        /*
         * Core options
         */
-       while ((ch = getopt(ac, av, "adfrqs:t:u:v")) != -1) {
+       while ((ch = getopt(ac, av, "adfm:rqs:t:u:v")) != -1) {
                switch(ch) {
                case 'a':
                        all_opt = 1;
@@ -75,6 +77,29 @@ main(int ac, char **av)
                case 'f':
                        ForceOpt = 1;
                        break;
+               case 'm':
+                       MemOpt = strtoul(optarg, &opt, 0);
+                       switch(*opt) {
+                       case 'g':
+                       case 'G':
+                               MemOpt *= 1024;
+                               /* FALLTHROUGH */
+                       case 'm':
+                       case 'M':
+                               MemOpt *= 1024;
+                               /* FALLTHROUGH */
+                       case 'k':
+                       case 'K':
+                               MemOpt *= 1024;
+                               break;
+                       case 0:
+                               break;
+                       default:
+                               fprintf(stderr, "-m: unrecognized suffix\n");
+                               usage(1);
+                               break;
+                       }
+                       break;
                case 'r':
                        RecurseOpt = 1;
                        break;
@@ -470,6 +495,7 @@ usage(int code)
                "    -s path            Select filesystem\n"
                "    -t type            PFS type for pfs-create\n"
                "    -u uuid            uuid for pfs-create\n"
+               "    -m mem[k,m,g]      buffer memory (bulkfree)\n"
                "\n"
                "    cleanup [<path>...]          "
                        "Run cleanup passes\n"
index e6bbb95..2b12604 100644 (file)
@@ -188,14 +188,18 @@ hammer2_bulk_scan(hammer2_chain_t *parent,
                        ++info->count_chains_scanned;
 
                        if (info->count_chains_scanned >=
-                           info->count_chains_reported + 50000) {
+                           info->count_chains_reported + 1000000 ||
+                           (info->count_chains_scanned < 1000000 &&
+                            info->count_chains_scanned >=
+                            info->count_chains_reported + 100000)) {
                                kprintf(" chains %-7ld inodes %-7ld "
                                        "dirents %-7ld bytes %5ldMB\n",
                                        info->count_chains_scanned,
                                        info->count_inodes_scanned,
                                        info->count_dirents_scanned,
                                        info->count_bytes_scanned / 1000000);
-                               info->count_chains_reported += 50000;
+                               info->count_chains_reported =
+                                       info->count_chains_scanned;
                        }
                }
 
@@ -383,15 +387,19 @@ hammer2_bulkfree_pass(hammer2_dev_t *hmp, hammer2_chain_t *vchain,
        hammer2_dedup_clear(hmp);
 
        /*
-        * Setup for free pass
+        * Setup for free pass.  Maximum buffer memory is 1/4 physical
+        * memory.
         */
        bzero(&cbinfo, sizeof(cbinfo));
        size = (bfi->size + HAMMER2_FREEMAP_LEVELN_PSIZE - 1) &
               ~(size_t)(HAMMER2_FREEMAP_LEVELN_PSIZE - 1);
        if (size < 1024 * 1024)
                size = 1024 * 1024;
-       if (size > kmem_lim_size() * 1024 * 1024 / 16)
-               size = kmem_lim_size() * 1024 * 1024 / 16;
+       if (size > kmem_lim_size() * 1024 * 1024 / 4) {
+               size = kmem_lim_size() * 1024 * 1024 / 4;
+               kprintf("hammer2: Warning: capping bulkfree buffer at %jdM\n",
+                       (intmax_t)size / (1024 * 1024));
+       }
 
        cbinfo.hmp = hmp;
        cbinfo.bmap = kmem_alloc_swapbacked(&cbinfo.kp, size, VM_SUBSYS_HAMMER);
@@ -444,11 +452,12 @@ hammer2_bulkfree_pass(hammer2_dev_t *hmp, hammer2_chain_t *vchain,
                        cbinfo.sstop = hmp->voldata.volu_size;
                else
                        cbinfo.sstop = cbinfo.sbase + incr;
-               if (hammer2_debug & 1) {
-                       kprintf("bulkfree pass %016jx/%jdGB\n",
-                               (intmax_t)cbinfo.sbase,
-                               (intmax_t)incr / HAMMER2_FREEMAP_LEVEL1_SIZE);
-               }
+               kprintf("hammer2: bulkfree buf=%5jdM "
+                       "pass %016jx-%016jx (%jdGB of media)\n",
+                       (intmax_t)size / (1024 * 1024),
+                       (intmax_t)cbinfo.sbase,
+                       (intmax_t)cbinfo.sstop,
+                       (intmax_t)incr / (1024L*1024*1024));
 
                /*
                 * Scan topology for stuff inside this range.