From 5c4a2341bf724b0c69aea8a4d45358e7944acfac Mon Sep 17 00:00:00 2001 From: Matt Vandermeulen Date: Fri, 16 Feb 2024 13:06:14 -0400 Subject: [PATCH] blk: support bdev_async_discard_threads == 0 Signed-off-by: Matt Vandermeulen --- src/blk/kernel/KernelDevice.cc | 40 +++++++++++++++++++--------------- src/blk/kernel/KernelDevice.h | 2 +- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/blk/kernel/KernelDevice.cc b/src/blk/kernel/KernelDevice.cc index 6ce5b3a9293..6337292f5de 100644 --- a/src/blk/kernel/KernelDevice.cc +++ b/src/blk/kernel/KernelDevice.cc @@ -778,30 +778,28 @@ void KernelDevice::_discard_thread(uint64_t tid) dout(10) << __func__ << " thread " << tid << " finish" << dendl; } -int KernelDevice::_queue_discard(interval_set &to_release) +// this is private and is expected that the caller checks that discard +// threads are running via _discard_started() +void KernelDevice::_queue_discard(interval_set &to_release) { - // if bdev_async_discard enabled on the fly, discard_thread is not started here, fallback to sync discard - if (!_discard_started()) - return -1; - if (to_release.empty()) - return 0; + return; std::lock_guard l(discard_lock); discard_queued.insert(to_release); discard_cond.notify_one(); - return 0; } -// return true only if _queue_discard succeeded, so caller won't have to do alloc->release -// otherwise false +// return true only if discard was queued, so caller won't have to do +// alloc->release, otherwise return false bool KernelDevice::try_discard(interval_set &to_release, bool async) { if (!support_discard || !cct->_conf->bdev_enable_discard) return false; - if (async) { - return 0 == _queue_discard(to_release); + if (async && _discard_started()) { + _queue_discard(to_release); + return true; } else { for (auto p = to_release.begin(); p != to_release.end(); ++p) { _discard(p.get_start(), p.get_len()); @@ -1528,13 +1526,19 @@ void KernelDevice::handle_conf_change(const ConfigProxy& conf, // Decrease? Signal threads after telling them to stop dout(10) << __func__ << " stopping " << (oldval - newval) << " existing discard threads" << dendl; - // Signal the last threads to quit, and stop tracking them - for(uint64_t i = oldval - 1; i >= newval; i--) - { - // Also detach the thread so we no longer need to join - discard_threads[i]->stop = true; - discard_threads[i]->detach(); - discard_threads.erase(discard_threads.begin() + i); + // Decreasing to zero is exactly the same as disabling async discard. + // Signal all threads to stop + if(newval == 0) { + _discard_stop(); + } else { + // Signal the last threads to quit, and stop tracking them + for(uint64_t i = oldval - 1; i >= newval; i--) + { + // Also detach the thread so we no longer need to join + discard_threads[i]->stop = true; + discard_threads[i]->detach(); + discard_threads.erase(discard_threads.begin() + i); + } } discard_cond.notify_all(); diff --git a/src/blk/kernel/KernelDevice.h b/src/blk/kernel/KernelDevice.h index 326a9433991..914f05e64c4 100644 --- a/src/blk/kernel/KernelDevice.h +++ b/src/blk/kernel/KernelDevice.h @@ -87,7 +87,7 @@ private: void _aio_thread(); void _discard_thread(uint64_t tid); - int _queue_discard(interval_set &to_release); + void _queue_discard(interval_set &to_release); bool try_discard(interval_set &to_release, bool async = true) override; int _aio_start(); -- 2.39.5