]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Fix 'zfs send/recv' hang with 16M blocks
authorBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 9 Apr 2018 02:41:15 +0000 (19:41 -0700)
committerTony Hutter <hutter2@llnl.gov>
Tue, 8 May 2018 00:19:57 +0000 (17:19 -0700)
When using 16MB blocks the send/recv queue's aren't quite big
enough.  This change leaves the default 16M queue size which a
good value for most pools.  But it additionally ensures that the
queue sizes are at least twice the allowed zfs_max_recordsize.

Reviewed-by: loli10K <ezomori.nozomu@gmail.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #7365
Closes #7404

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

index bfcac1493cc4755d820bc00c58449796dd3c9f9e..0c5a6462e380e8c9ec6f0b42c75164db6088a9d3 100644 (file)
@@ -1763,6 +1763,31 @@ Allow sending of corrupt data (ignore read/checksum errors when sending data)
 Use \fB1\fR for yes and \fB0\fR for no (default).
 .RE
 
+.sp
+.ne 2
+.na
+\fBzfs_send_queue_length\fR (int)
+.ad
+.RS 12n
+The maximum number of bytes allowed in the \fBzfs send\fR queue. This value
+must be at least twice the maximum block size in use.
+.sp
+Default value: \fB16,777,216\fR.
+.RE
+
+.sp
+.ne 2
+.na
+\fBzfs_recv_queue_length\fR (int)
+.ad
+.RS 12n
+.sp
+The maximum number of bytes allowed in the \fBzfs receive\fR queue. This value
+must be at least twice the maximum block size in use.
+.sp
+Default value: \fB16,777,216\fR.
+.RE
+
 .sp
 .ne 2
 .na
index 344e42018df1f236c828497e2b74d00980c39ad3..cdbc1cd1bc6d7c990e8477516046105b22bf92fd 100644 (file)
@@ -61,8 +61,8 @@
 
 /* Set this tunable to TRUE to replace corrupt data with 0x2f5baddb10c */
 int zfs_send_corrupt_data = B_FALSE;
-int zfs_send_queue_length = 16 * 1024 * 1024;
-int zfs_recv_queue_length = 16 * 1024 * 1024;
+int zfs_send_queue_length = SPA_MAXBLOCKSIZE;
+int zfs_recv_queue_length = SPA_MAXBLOCKSIZE;
 /* Set this tunable to FALSE to disable setting of DRR_FLAG_FREERECORDS */
 int zfs_send_set_freerecords_bit = B_TRUE;
 
@@ -944,7 +944,8 @@ dmu_send_impl(void *tag, dsl_pool_t *dp, dsl_dataset_t *to_ds,
                goto out;
        }
 
-       err = bqueue_init(&to_arg.q, zfs_send_queue_length,
+       err = bqueue_init(&to_arg.q,
+           MAX(zfs_send_queue_length, 2 * zfs_max_recordsize),
            offsetof(struct send_block_record, ln));
        to_arg.error_code = 0;
        to_arg.cancel = B_FALSE;
@@ -3173,7 +3174,8 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, vnode_t *vp, offset_t *voffp,
                        goto out;
        }
 
-       (void) bqueue_init(&rwa->q, zfs_recv_queue_length,
+       (void) bqueue_init(&rwa->q,
+           MAX(zfs_recv_queue_length, 2 * zfs_max_recordsize),
            offsetof(struct receive_record_arg, node));
        cv_init(&rwa->cv, NULL, CV_DEFAULT, NULL);
        mutex_init(&rwa->mutex, NULL, MUTEX_DEFAULT, NULL);
@@ -3550,4 +3552,10 @@ dmu_objset_is_receiving(objset_t *os)
 #if defined(_KERNEL)
 module_param(zfs_send_corrupt_data, int, 0644);
 MODULE_PARM_DESC(zfs_send_corrupt_data, "Allow sending corrupt data");
+
+module_param(zfs_send_queue_length, int, 0644);
+MODULE_PARM_DESC(zfs_send_queue_length, "Maximum send queue length");
+
+module_param(zfs_recv_queue_length, int, 0644);
+MODULE_PARM_DESC(zfs_recv_queue_length, "Maximum receive queue length");
 #endif