@@ -134,7 +134,6 @@ int KernelDevice::open(const string& p)
134134{
135135 path = p;
136136 int r = 0 , i = 0 ;
137- uint64_t num_discard_threads = 0 ;
138137 dout (1 ) << __func__ << " path " << path << dendl;
139138
140139 struct stat statbuf;
@@ -286,10 +285,7 @@ int KernelDevice::open(const string& p)
286285 goto out_fail;
287286 }
288287
289- num_discard_threads = cct->_conf .get_val <uint64_t >(" bdev_async_discard_threads" );
290- if (support_discard && cct->_conf ->bdev_enable_discard && num_discard_threads > 0 ) {
291- _discard_start ();
292- }
288+ _discard_update_threads ();
293289
294290 // round size down to an even block
295291 size &= ~(block_size - 1 );
@@ -536,47 +532,49 @@ void KernelDevice::_aio_stop()
536532 }
537533}
538534
539- void KernelDevice::_discard_start ()
535+ void KernelDevice::_discard_update_threads ()
540536{
541- uint64_t num = cct->_conf .get_val <uint64_t >(" bdev_async_discard_threads" );
542- dout (10 ) << __func__ << " starting " << num << " threads" << dendl;
543-
544537 std::unique_lock l (discard_lock);
545538
546- target_discard_threads = num;
547- discard_threads.reserve (num);
548- for (uint64_t i = 0 ; i < num; i++)
549- {
550- // All threads created with the same name
551- discard_threads.emplace_back (new DiscardThread (this , i));
552- discard_threads.back ()->create (" bstore_discard" );
553- }
539+ uint64_t oldcount = discard_threads.size ();
540+ uint64_t newcount = cct->_conf .get_val <uint64_t >(" bdev_async_discard_threads" );
541+ if (!cct->_conf .get_val <bool >(" bdev_enable_discard" ) || !support_discard || discard_stop) {
542+ newcount = 0 ;
543+ }
544+
545+ // Increase? Spawn now, it's quick
546+ if (newcount > oldcount) {
547+ dout (10 ) << __func__ << " starting " << (newcount - oldcount) << " additional discard threads" << dendl;
548+ discard_threads.reserve (newcount);
549+ for (uint64_t i = oldcount; i < newcount; i++)
550+ {
551+ // All threads created with the same name
552+ discard_threads.emplace_back (new DiscardThread (this , i));
553+ discard_threads.back ()->create (" bstore_discard" );
554+ }
555+ // Decrease? Signal threads after telling them to stop
556+ } else if (newcount < oldcount) {
557+ dout (10 ) << __func__ << " stopping " << (oldcount - newcount) << " existing discard threads" << dendl;
558+
559+ // Signal the last threads to quit, and stop tracking them
560+ for (uint64_t i = oldcount; i > newcount; i--)
561+ {
562+ discard_threads[i-1 ]->stop = true ;
563+ discard_threads[i-1 ]->detach ();
564+ }
565+ discard_threads.resize (newcount);
554566
555- dout (10 ) << __func__ << " started " << num << " threads" << dendl;
567+ discard_cond.notify_all ();
568+ }
556569}
557570
558571void KernelDevice::_discard_stop ()
559572{
560573 dout (10 ) << __func__ << dendl;
561574
562- // Signal threads to stop, then wait for them to join
563- {
564- std::unique_lock l (discard_lock);
565- while (discard_threads.empty ()) {
566- discard_cond.wait (l);
567- }
568-
569- for (auto &t : discard_threads) {
570- t->stop = true ;
571- }
572-
573- discard_cond.notify_all ();
574- }
575-
576- // Threads are shared pointers and are cleaned up for us
577- for (auto &t : discard_threads)
578- t->join ();
579- discard_threads.clear ();
575+ discard_stop = true ;
576+ _discard_update_threads ();
577+ discard_drain ();
580578
581579 dout (10 ) << __func__ << " stopped" << dendl;
582580}
@@ -761,6 +759,13 @@ void KernelDevice::_discard_thread(uint64_t tid)
761759 discard_cond.wait (l);
762760 dout (20 ) << __func__ << " wake" << dendl;
763761 } else {
762+ // If there are non-stopped discard threads and we have been requested
763+ // to stop, do so now. Otherwise, we need to proceed because
764+ // discard_queued is non-empty and at least one thread is needed to
765+ // drain it.
766+ if (thr->stop && !discard_threads.empty ())
767+ break ;
768+
764769 // Limit local processing to MAX_LOCAL_DISCARD items.
765770 // This will allow threads to work in parallel
766771 // instead of a single thread taking over the whole discard_queued.
@@ -1513,6 +1518,7 @@ const char** KernelDevice::get_tracked_conf_keys() const
15131518{
15141519 static const char * KEYS[] = {
15151520 " bdev_async_discard_threads" ,
1521+ " bdev_enable_discard" ,
15161522 NULL
15171523 };
15181524 return KEYS;
@@ -1521,44 +1527,7 @@ const char** KernelDevice::get_tracked_conf_keys() const
15211527void KernelDevice::handle_conf_change (const ConfigProxy& conf,
15221528 const std::set <std::string> &changed)
15231529{
1524- if (changed.count (" bdev_async_discard_threads" )) {
1525- std::unique_lock l (discard_lock);
1526-
1527- uint64_t oldval = target_discard_threads;
1528- uint64_t newval = cct->_conf .get_val <uint64_t >(" bdev_async_discard_threads" );
1529-
1530- target_discard_threads = newval;
1531-
1532- // Increase? Spawn now, it's quick
1533- if (newval > oldval) {
1534- dout (10 ) << __func__ << " starting " << (newval - oldval) << " additional discard threads" << dendl;
1535- discard_threads.reserve (target_discard_threads);
1536- for (uint64_t i = oldval; i < newval; i++)
1537- {
1538- // All threads created with the same name
1539- discard_threads.emplace_back (new DiscardThread (this , i));
1540- discard_threads.back ()->create (" bstore_discard" );
1541- }
1542- } else {
1543- // Decrease? Signal threads after telling them to stop
1544- dout (10 ) << __func__ << " stopping " << (oldval - newval) << " existing discard threads" << dendl;
1545-
1546- // Decreasing to zero is exactly the same as disabling async discard.
1547- // Signal all threads to stop
1548- if (newval == 0 ) {
1549- _discard_stop ();
1550- } else {
1551- // Signal the last threads to quit, and stop tracking them
1552- for (uint64_t i = oldval - 1 ; i >= newval; i--)
1553- {
1554- // Also detach the thread so we no longer need to join
1555- discard_threads[i]->stop = true ;
1556- discard_threads[i]->detach ();
1557- discard_threads.erase (discard_threads.begin () + i);
1558- }
1559- }
1560-
1561- discard_cond.notify_all ();
1562- }
1530+ if (changed.count (" bdev_async_discard_threads" ) || changed.count (" bdev_enable_discard" )) {
1531+ _discard_update_threads ();
15631532 }
15641533}
0 commit comments