if (submit_deferred) {
// we're pinning memory; flush! we could be more fine-grained here but
// i'm not sure it's worth the bother.
- deferred_try_submit();
+ deferred_submit_all();
}
if (empty && osr->zombie) {
++deferred_aggressive;
{
// submit anything pending
- deferred_try_submit();
+ deferred_submit_all();
}
{
// wake up any previously finished deferred events
if (!deferred_aggressive) {
if (deferred_queue_size >= deferred_batch_ops.load() ||
throttle_deferred_bytes.past_midpoint()) {
- deferred_try_submit();
+ deferred_submit_all();
}
}
dout(20) << __func__ << " txc " << txc << " osr " << txc->osr << dendl;
deferred_lock.lock();
if (!txc->osr->deferred_pending &&
- !txc->osr->deferred_running) {
+ txc->osr->deferred_running.empty()) {
deferred_queue.push_back(*txc->osr);
}
if (!txc->osr->deferred_pending) {
cct, wt.seq, e.offset, e.length, p);
}
}
- if (deferred_aggressive &&
- !txc->osr->deferred_running) {
+ if (deferred_aggressive) {
_deferred_submit_unlock(txc->osr.get());
} else {
deferred_lock.unlock();
}
}
-void BlueStore::deferred_try_submit()
+void BlueStore::deferred_submit_all()
{
dout(20) << __func__ << " " << deferred_queue.size() << " osrs, "
<< deferred_queue_size << " txcs" << dendl;
osrs.push_back(&osr);
}
for (auto& osr : osrs) {
- if (osr->deferred_pending && !osr->deferred_running) {
+ if (osr->deferred_pending) {
_deferred_submit_unlock(osr.get());
deferred_lock.lock();
}
void BlueStore::_deferred_submit_unlock(OpSequencer *osr)
{
- dout(10) << __func__ << " osr " << osr
+ auto b = osr->deferred_pending;
+ dout(10) << __func__ << " osr " << osr << " b " << b
<< " " << osr->deferred_pending->iomap.size() << " ios pending "
<< dendl;
- assert(osr->deferred_pending);
- assert(!osr->deferred_running);
-
- auto b = osr->deferred_pending;
+ assert(b);
deferred_queue_size -= b->seq_bytes.size();
assert(deferred_queue_size >= 0);
- osr->deferred_running = osr->deferred_pending;
+ osr->deferred_running.push_back(osr->deferred_pending);
osr->deferred_pending = nullptr;
uint64_t start = 0, pos = 0;
bdev->aio_submit(&b->ioc);
}
-void BlueStore::_deferred_aio_finish(OpSequencer *osr)
+void BlueStore::_deferred_aio_finish(DeferredBatch *b)
{
- dout(10) << __func__ << " osr " << osr << dendl;
- assert(osr->deferred_running);
- DeferredBatch *b = osr->deferred_running;
+ OpSequencer *osr = b->osr;
+ dout(10) << __func__ << " osr " << osr << " b " << b << dendl;
{
std::lock_guard<std::mutex> l(deferred_lock);
- assert(osr->deferred_running == b);
- osr->deferred_running = nullptr;
- if (!osr->deferred_pending) {
+ auto p = std::find(osr->deferred_running.begin(),
+ osr->deferred_running.end(),
+ b);
+ assert(p != osr->deferred_running.end());
+ osr->deferred_running.erase(p);
+ if (osr->deferred_running.empty() && !osr->deferred_pending) {
auto q = deferred_queue.iterator_to(*osr);
deferred_queue.erase(q);
- } else if (deferred_aggressive) {
- dout(20) << __func__ << " queuing async deferred_try_submit" << dendl;
- finishers[0]->queue(new FunctionContext([&](int) {
- deferred_try_submit();
- }));
}
}
if (txc->deferred_txn) {
// ensure we do not block here because of deferred writes
if (!throttle_deferred_bytes.get_or_fail(txc->cost)) {
- deferred_try_submit();
+ deferred_submit_all();
throttle_deferred_bytes.get(txc->cost);
}
}
bufferlist::const_iterator& p);
void aio_finish(BlueStore *store) override {
- store->_deferred_aio_finish(osr);
+ store->_deferred_aio_finish(this);
}
};
boost::intrusive::list_member_hook<> deferred_osr_queue_item;
- DeferredBatch *deferred_running = nullptr;
+ deque<DeferredBatch*> deferred_running;
DeferredBatch *deferred_pending = nullptr;
Sequencer *parent;
bluestore_deferred_op_t *_get_deferred_op(TransContext *txc, OnodeRef o);
void _deferred_queue(TransContext *txc);
- void deferred_try_submit();
+ void deferred_submit_all();
void _deferred_submit_unlock(OpSequencer *osr);
- void _deferred_aio_finish(OpSequencer *osr);
+ void _deferred_aio_finish(DeferredBatch *b);
int _deferred_replay();
public: