]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Illumos 5138 - add tunable for maximum number of blocks freed in one txg
authorMax Grossman <max.grossman@delphix.com>
Sun, 7 Sep 2014 15:06:08 +0000 (17:06 +0200)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Tue, 23 Sep 2014 21:26:34 +0000 (14:26 -0700)
Reviewed by: Adam Leventhal <adam.leventhal@delphix.com>
Reviewed by: Mattew Ahrens <mahrens@delphix.com>
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Reviewed by: Richard Elling <richard.elling@gmail.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Approved by: Dan McDonald <danmcd@omniti.com>

References:
  https://www.illumos.org/issues/5138
  https://github.com/illumos/illumos-gate/commit/af3465d

Porting notes:

Because support for exposing a uint64_t parameter wasn't added
until v3.17-rc1 the zfs_free_max_blocks variable has been declared
as a unsigned long.  This is already far larger than required and
it allows us to avoid additional autoconf compatibility code.

The default value has been set to 100,000 on Linux instead of
ULONG_MAX which is used on Illumos.  This was done to limit the
number of outstanding IOs in the system when snapshots are destroyed.
This helps ensure individual TXG sync times are kept reasonable and
memory isn't wasted managing a huge backlog of outstanding IOs.

Ported by: Turbo Fredriksson <turbo@bayour.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #2675
Closes #2581

man/man5/zfs-module-parameters.5
module/zfs/dsl_scan.c

index 9c5d70de8be858652b763951478ff187892d8306..28c6e11d2fd5c82dc318628efa71002ff8c4e287 100644 (file)
@@ -620,6 +620,17 @@ Start syncing out a transaction group if there is at least this much dirty data.
 Default value: \fB67,108,864\fR.
 .RE
 
+.sp
+.ne 2
+.na
+\fBzfs_free_max_blocks\fR (ulong)
+.ad
+.RS 12n
+Maximum number of blocks freed in a single txg.
+.sp
+Default value: \fB100,000\fR.
+.RE
+
 .sp
 .ne 2
 .na
index 5546dad5f656aabc24d5ab4c744c56c627d8baa0..eeec76f78733b5dde5246e5061df092f0088d2bb 100644 (file)
@@ -69,6 +69,8 @@ int zfs_no_scrub_io = B_FALSE; /* set to disable scrub i/o */
 int zfs_no_scrub_prefetch = B_FALSE; /* set to disable scrub prefetch */
 enum ddt_class zfs_scrub_ddt_class_max = DDT_CLASS_DUPLICATE;
 int dsl_scan_delay_completion = B_FALSE; /* set to delay scan completion */
+/* max number of blocks to free in a single TXG */
+ulong zfs_free_max_blocks = 100000;
 
 #define        DSL_SCAN_IS_SCRUB_RESILVER(scn) \
        ((scn)->scn_phys.scn_func == POOL_SCAN_SCRUB || \
@@ -1370,6 +1372,9 @@ dsl_scan_free_should_pause(dsl_scan_t *scn)
        if (zfs_recover)
                return (B_FALSE);
 
+       if (scn->scn_visited_this_txg >= zfs_free_max_blocks)
+               return (B_TRUE);
+
        elapsed_nanosecs = gethrtime() - scn->scn_sync_start_time;
        return (elapsed_nanosecs / NANOSEC > zfs_txg_timeout ||
            (NSEC2MSEC(elapsed_nanosecs) > zfs_free_min_time_ms &&
@@ -1868,4 +1873,7 @@ MODULE_PARM_DESC(zfs_no_scrub_io, "Set to disable scrub I/O");
 
 module_param(zfs_no_scrub_prefetch, int, 0644);
 MODULE_PARM_DESC(zfs_no_scrub_prefetch, "Set to disable scrub prefetching");
+
+module_param(zfs_free_max_blocks, ulong, 0644);
+MODULE_PARM_DESC(zfs_free_max_blocks, "Max number of blocks freed in one txg");
 #endif