aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2018-04-08 19:41:15 -0700
committerGitHub <[email protected]>2018-04-08 19:41:15 -0700
commit3b0d99289a8e473b059605a83d4ce0bd505ec3d3 (patch)
tree4c9ba831ed700028eba843af53dd84961b72f3e0
parent7b47628acb7ef073caa5bd23372b0c9c2741caf8 (diff)
Fix 'zfs send/recv' hang with 16M blocks
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 <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Closes #7365 Closes #7404
-rw-r--r--man/man5/zfs-module-parameters.525
-rw-r--r--module/zfs/dmu_send.c16
2 files changed, 37 insertions, 4 deletions
diff --git a/man/man5/zfs-module-parameters.5 b/man/man5/zfs-module-parameters.5
index f7db35b19..e3c6dd91a 100644
--- a/man/man5/zfs-module-parameters.5
+++ b/man/man5/zfs-module-parameters.5
@@ -1922,6 +1922,31 @@ Use \fB1\fR for yes and \fB0\fR for no (default).
.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
\fBzfs_sync_pass_deferred_free\fR (int)
.ad
.RS 12n
diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c
index e0e5fe22c..a007e96ba 100644
--- a/module/zfs/dmu_send.c
+++ b/module/zfs/dmu_send.c
@@ -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;
@@ -1142,7 +1142,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;
@@ -3831,7 +3832,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);
@@ -4242,4 +4244,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