mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 03:19:35 +03:00
Limit the number of blocks to discard at once.
The number of blocks that can be discarded in one BLKDISCARD ioctl on a zvol is currently unlimited. Some applications, such as mkfs, discard the whole volume at once and they use the maximum possible discard size to do that. As a result, several gigabytes discard requests are not uncommon. Unfortunately, if a large amount of data is allocated in the zvol, ZFS can be quite slow to process discard requests. This is especially true if the volblocksize is low (e.g. the 8K default). As a result, very large discard requests can take a very long time (seconds to minutes under heavy load) to complete. This can cause a number of problems, most notably if the zvol is accessed remotely (e.g. via iSCSI), in which case the client has a high probability of timing out on the request. This patch solves the issue by adding a new tunable module parameter: zvol_max_discard_blocks. This indicates the maximum possible range, in zvol blocks, of one discard operation. It is set by default to 16384 blocks, which appears to be a good tradeoff. Using the default volblocksize of 8K this is equivalent to 128 MB. When using the maximum volblocksize of 128K this is equivalent to 2 GB. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #858
This commit is contained in:
parent
330d06f90d
commit
7c0e570888
@ -49,6 +49,7 @@
|
|||||||
unsigned int zvol_inhibit_dev = 0;
|
unsigned int zvol_inhibit_dev = 0;
|
||||||
unsigned int zvol_major = ZVOL_MAJOR;
|
unsigned int zvol_major = ZVOL_MAJOR;
|
||||||
unsigned int zvol_threads = 32;
|
unsigned int zvol_threads = 32;
|
||||||
|
unsigned long zvol_max_discard_blocks = 16384;
|
||||||
|
|
||||||
static taskq_t *zvol_taskq;
|
static taskq_t *zvol_taskq;
|
||||||
static kmutex_t zvol_state_lock;
|
static kmutex_t zvol_state_lock;
|
||||||
@ -1242,7 +1243,8 @@ __zvol_create_minor(const char *name)
|
|||||||
blk_queue_physical_block_size(zv->zv_queue, zv->zv_volblocksize);
|
blk_queue_physical_block_size(zv->zv_queue, zv->zv_volblocksize);
|
||||||
blk_queue_io_opt(zv->zv_queue, zv->zv_volblocksize);
|
blk_queue_io_opt(zv->zv_queue, zv->zv_volblocksize);
|
||||||
#ifdef HAVE_BLK_QUEUE_DISCARD
|
#ifdef HAVE_BLK_QUEUE_DISCARD
|
||||||
blk_queue_max_discard_sectors(zv->zv_queue, UINT_MAX);
|
blk_queue_max_discard_sectors(zv->zv_queue,
|
||||||
|
(zvol_max_discard_blocks * zv->zv_volblocksize) >> 9);
|
||||||
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, zv->zv_queue);
|
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, zv->zv_queue);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_BLK_QUEUE_NONROT
|
#ifdef HAVE_BLK_QUEUE_NONROT
|
||||||
@ -1446,3 +1448,6 @@ MODULE_PARM_DESC(zvol_major, "Major number for zvol device");
|
|||||||
|
|
||||||
module_param(zvol_threads, uint, 0444);
|
module_param(zvol_threads, uint, 0444);
|
||||||
MODULE_PARM_DESC(zvol_threads, "Number of threads for zvol device");
|
MODULE_PARM_DESC(zvol_threads, "Number of threads for zvol device");
|
||||||
|
|
||||||
|
module_param(zvol_max_discard_blocks, ulong, 0444);
|
||||||
|
MODULE_PARM_DESC(zvol_max_discard_blocks, "Max number of blocks to discard at once");
|
||||||
|
Loading…
Reference in New Issue
Block a user