timestamp_lock(util::unique_lock_name("librbd::ImageCtx::timestamp_lock", this)),
async_ops_lock(util::unique_lock_name("librbd::ImageCtx::async_ops_lock", this)),
copyup_list_lock(util::unique_lock_name("librbd::ImageCtx::copyup_list_lock", this)),
- completed_reqs_lock(util::unique_lock_name("librbd::ImageCtx::completed_reqs_lock", this)),
extra_read_flags(0),
old_format(false),
order(0), size(0), features(0),
operations(new Operations<>(*this)),
exclusive_lock(nullptr), object_map(nullptr),
io_work_queue(nullptr), op_work_queue(nullptr),
+ completed_reqs(32),
asok_hook(nullptr),
trace_endpoint("librbd")
{
on_finish->complete(0);
}
- void ImageCtx::clear_pending_completions() {
- Mutex::Locker l(completed_reqs_lock);
- ldout(cct, 10) << "clear pending AioCompletion: count="
- << completed_reqs.size() << dendl;
- completed_reqs.clear();
- }
-
void ImageCtx::apply_metadata(const std::map<std::string, bufferlist> &meta,
bool thread_safe) {
ldout(cct, 20) << __func__ << dendl;
#include "librbd/AsyncRequest.h"
#include "librbd/Types.h"
+#include <boost/lockfree/queue.hpp>
+
class CephContext;
class ContextWQ;
class Finisher;
RWLock timestamp_lock; // protects (create/access/modify)_timestamp
Mutex async_ops_lock; // protects async_ops and async_requests
Mutex copyup_list_lock; // protects copyup_waiting_list
- Mutex completed_reqs_lock; // protects completed_reqs
unsigned extra_read_flags;
io::ImageRequestWQ<ImageCtx> *io_work_queue;
io::ObjectDispatcher<ImageCtx> *io_object_dispatcher = nullptr;
- xlist<io::AioCompletion*> completed_reqs;
- EventSocket event_socket;
-
ContextWQ *op_work_queue;
+ boost::lockfree::queue<io::AioCompletion*> completed_reqs;
+ EventSocket event_socket;
+
bool ignore_migrating = false;
/// Cached latency-sensitive configuration settings
ObjectMap<ImageCtx> *create_object_map(uint64_t snap_id);
Journal<ImageCtx> *create_journal();
- void clear_pending_completions();
-
void set_image_name(const std::string &name);
void notify_update();
ldout(cct, 20) << __func__ << " " << ictx << " numcomp = " << numcomp
<< dendl;
int i = 0;
- Mutex::Locker l(ictx->completed_reqs_lock);
- numcomp = std::min(numcomp, (int)ictx->completed_reqs.size());
- while (i < numcomp) {
- comps[i++] = ictx->completed_reqs.front();
- ictx->completed_reqs.pop_front();
+ while (i < numcomp && ictx->completed_reqs.pop(comps[i])) {
+ ++i;
}
+
return i;
}
}
if (ictx != nullptr && event_notify && ictx->event_socket.is_valid()) {
- ictx->completed_reqs_lock.Lock();
- ictx->completed_reqs.push_back(&m_xlist_item);
- ictx->completed_reqs_lock.Unlock();
+ ictx->completed_reqs.push(this);
ictx->event_socket.notify();
}
state = AIO_STATE_COMPLETE;
AsyncOperation async_op;
- xlist<AioCompletion*>::item m_xlist_item;
bool event_notify = false;
template <typename T, void (T::*MF)(int)>
return comp;
}
- AioCompletion() : m_xlist_item(this) {
+ AioCompletion() {
}
~AioCompletion() {
ceph_assert(previous_ref > 0);
if (previous_ref == 1) {
- if (ictx != nullptr && event_notify) {
- ictx->completed_reqs_lock.Lock();
- m_xlist_item.remove_myself();
- ictx->completed_reqs_lock.Unlock();
- }
delete this;
}
}