From d6f97edf4adbf15b628a0efc2c1965996374fb84 Mon Sep 17 00:00:00 2001 From: Zygo Blaxell Date: Tue, 7 Feb 2017 21:56:54 -0500 Subject: [PATCH] crucible: fs: keep ioctl buffer between runs perf blames the SEARCH_V2 ioctl wrapper for a lot of time spent in malloc. Use a thread_local buffer for ioctl results, and reuse it between runs. Signed-off-by: Zygo Blaxell (cherry picked from commit e509210428951e645d33916694a17aed1950991d) --- lib/fs.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/fs.cc b/lib/fs.cc index 511ceae..366934f 100644 --- a/lib/fs.cc +++ b/lib/fs.cc @@ -716,10 +716,20 @@ namespace crucible { bool BtrfsIoctlSearchKey::do_ioctl_nothrow(int fd) { - vector ioctl_arg = vector_copy_struct(this); // Normally we like to be paranoid and fill empty bytes with zero, // but these buffers can be huge. 80% of a 4GHz CPU huge. - ioctl_arg.resize(sizeof(btrfs_ioctl_search_args_v2) + m_buf_size); + + // Keep the ioctl buffer from one run to the next to save on malloc costs + size_t target_buf_size = sizeof(btrfs_ioctl_search_args_v2) + m_buf_size; + + thread_local vector ioctl_arg; + if (ioctl_arg.size() < m_buf_size) { + ioctl_arg = vector_copy_struct(this); + ioctl_arg.resize(target_buf_size); + } else { + memcpy(ioctl_arg.data(), static_cast(this), sizeof(btrfs_ioctl_search_key)); + } + btrfs_ioctl_search_args_v2 *ioctl_ptr = reinterpret_cast(ioctl_arg.data()); ioctl_ptr->buf_size = m_buf_size;