Skip to content

Commit

Permalink
librbd: avoid blocking AIO API methods
Browse files Browse the repository at this point in the history
Enqueue all AIO API methods within the new librbd thread pool to
reduce the possibility of any blocking operations. To maintain
backwards compatibility with the legacy return codes of the API's
AIO methods, it's still possible to block attempting to acquire
the snap_lock.

Fixes: #11056
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
(cherry picked from commit 3a7b5e3)
  • Loading branch information
Jason Dillaman committed Jun 10, 2015
1 parent e61974a commit cf6e1f5
Showing 1 changed file with 132 additions and 42 deletions.
174 changes: 132 additions & 42 deletions src/librbd/librbd.cc
Expand Up @@ -20,6 +20,7 @@
#include "common/errno.h"
#include "common/snap_types.h"
#include "common/perf_counters.h"
#include "common/WorkQueue.h"
#include "include/Context.h"
#include "include/rbd/librbd.hpp"
#include "osdc/ObjectCacher.h"
Expand Down Expand Up @@ -51,6 +52,87 @@ using ceph::bufferlist;
using librados::snap_t;
using librados::IoCtx;

namespace {

class C_AioReadWQ : public Context {
public:
C_AioReadWQ(librbd::ImageCtx *ictx, uint64_t off, size_t len,
char *buf, bufferlist *pbl, librbd::AioCompletion *c,
int op_flags)
: m_ictx(ictx), m_off(off), m_len(len), m_buf(buf), m_pbl(pbl), m_comp(c),
m_op_flags(op_flags) {
}
protected:
virtual void finish(int r) {
librbd::aio_read(m_ictx, m_off, m_len, m_buf, m_pbl, m_comp, m_op_flags);
}
private:
librbd::ImageCtx *m_ictx;
uint64_t m_off;
uint64_t m_len;
char *m_buf;
bufferlist *m_pbl;
librbd::AioCompletion *m_comp;
int m_op_flags;
};

class C_AioWriteWQ : public Context {
public:
C_AioWriteWQ(librbd::ImageCtx *ictx, uint64_t off, size_t len,
const char *buf, librbd::AioCompletion *c, int op_flags)
: m_ictx(ictx), m_off(off), m_len(len), m_buf(buf), m_comp(c),
m_op_flags(op_flags) {
}
protected:
virtual void finish(int r) {
aio_write(m_ictx, m_off, m_len, m_buf, m_comp, m_op_flags);
}
private:
librbd::ImageCtx *m_ictx;
uint64_t m_off;
uint64_t m_len;
const char *m_buf;
librbd::AioCompletion *m_comp;
int m_op_flags;
};

class C_AioDiscardWQ : public Context {
public:
C_AioDiscardWQ(librbd::ImageCtx *ictx, uint64_t off, uint64_t len,
librbd::AioCompletion *c)
: m_ictx(ictx), m_off(off), m_len(len), m_comp(c) {
}
protected:
virtual void finish(int r) {
aio_discard(m_ictx, m_off, m_len, m_comp);
}
private:
librbd::ImageCtx *m_ictx;
uint64_t m_off;
uint64_t m_len;
librbd::AioCompletion *m_comp;
};

class C_AioFlushWQ : public Context {
public:
C_AioFlushWQ(librbd::ImageCtx *ictx, librbd::AioCompletion *c)
: m_ictx(ictx), m_comp(c) {
}
protected:
virtual void finish(int r) {
aio_flush(m_ictx, m_comp);
}
private:
librbd::ImageCtx *m_ictx;
librbd::AioCompletion *m_comp;
};

librbd::AioCompletion* get_aio_completion(librbd::RBD::AioCompletion *comp) {
return reinterpret_cast<librbd::AioCompletion *>(comp->pc);
}

} // anonymous namespace

namespace librbd {
ProgressContext::~ProgressContext()
{
Expand Down Expand Up @@ -709,10 +791,10 @@ namespace librbd {
tracepoint(librbd, aio_write_exit, -EINVAL);
return -EINVAL;
}
int r = librbd::aio_write(ictx, off, len, bl.c_str(),
(librbd::AioCompletion *)c->pc, 0);
tracepoint(librbd, aio_write_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioWriteWQ(ictx, off, len, bl.c_str(),
get_aio_completion(c), 0));
tracepoint(librbd, aio_write_exit, 0);
return 0;
}

int Image::aio_write2(uint64_t off, size_t len, bufferlist& bl,
Expand All @@ -725,19 +807,21 @@ namespace librbd {
tracepoint(librbd, aio_write_exit, -EINVAL);
return -EINVAL;
}
int r = librbd::aio_write(ictx, off, len, bl.c_str(),
(librbd::AioCompletion *)c->pc, op_flags);
tracepoint(librbd, aio_write_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioWriteWQ(ictx, off, len, bl.c_str(),
get_aio_completion(c),
op_flags));
tracepoint(librbd, aio_write_exit, 0);
return 0;
}

int Image::aio_discard(uint64_t off, uint64_t len, RBD::AioCompletion *c)
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, aio_discard_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, off, len, c->pc);
int r = librbd::aio_discard(ictx, off, len, (librbd::AioCompletion *)c->pc);
tracepoint(librbd, aio_discard_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioDiscardWQ(ictx, off, len,
get_aio_completion(c)));
tracepoint(librbd, aio_discard_exit, 0);
return 0;
}

int Image::aio_read(uint64_t off, size_t len, bufferlist& bl,
Expand All @@ -747,9 +831,10 @@ namespace librbd {
tracepoint(librbd, aio_read_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, off, len, bl.c_str(), c->pc);
ldout(ictx->cct, 10) << "Image::aio_read() buf=" << (void *)bl.c_str() << "~"
<< (void *)(bl.c_str() + len - 1) << dendl;
int r = librbd::aio_read(ictx, off, len, NULL, &bl, (librbd::AioCompletion *)c->pc, 0);
tracepoint(librbd, aio_read_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioReadWQ(ictx, off, len, NULL, &bl,
get_aio_completion(c), 0));
tracepoint(librbd, aio_read_exit, 0);
return 0;
}

int Image::aio_read2(uint64_t off, size_t len, bufferlist& bl,
Expand All @@ -760,9 +845,11 @@ namespace librbd {
ictx->read_only, off, len, bl.c_str(), c->pc, op_flags);
ldout(ictx->cct, 10) << "Image::aio_read() buf=" << (void *)bl.c_str() << "~"
<< (void *)(bl.c_str() + len - 1) << dendl;
int r = librbd::aio_read(ictx, off, len, NULL, &bl, (librbd::AioCompletion *)c->pc, op_flags);
tracepoint(librbd, aio_read_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioReadWQ(ictx, off, len, NULL, &bl,
get_aio_completion(c),
op_flags));
tracepoint(librbd, aio_read_exit, 0);
return 0;
}

int Image::flush()
Expand All @@ -778,9 +865,9 @@ namespace librbd {
{
ImageCtx *ictx = (ImageCtx *)ctx;
tracepoint(librbd, aio_flush_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, c->pc);
int r = librbd::aio_flush(ictx, (librbd::AioCompletion *)c->pc);
tracepoint(librbd, aio_flush_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioFlushWQ(ictx, get_aio_completion(c)));
tracepoint(librbd, aio_flush_exit, 0);
return 0;
}

int Image::invalidate_cache()
Expand Down Expand Up @@ -1612,10 +1699,10 @@ extern "C" int rbd_aio_write(rbd_image_t image, uint64_t off, size_t len,
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
tracepoint(librbd, aio_write_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, off, len, buf, comp->pc);
int r = librbd::aio_write(ictx, off, len, buf,
(librbd::AioCompletion *)comp->pc, 0);
tracepoint(librbd, aio_write_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioWriteWQ(ictx, off, len, buf,
get_aio_completion(comp), 0));
tracepoint(librbd, aio_write_exit, 0);
return 0;
}

extern "C" int rbd_aio_write2(rbd_image_t image, uint64_t off, size_t len,
Expand All @@ -1625,10 +1712,11 @@ extern "C" int rbd_aio_write2(rbd_image_t image, uint64_t off, size_t len,
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
tracepoint(librbd, aio_write2_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(),
ictx->read_only, off, len, buf, comp->pc, op_flags);
int r = librbd::aio_write(ictx, off, len, buf,
(librbd::AioCompletion *)comp->pc, op_flags);
tracepoint(librbd, aio_write_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioWriteWQ(ictx, off, len, buf,
get_aio_completion(comp),
op_flags));
tracepoint(librbd, aio_write_exit, 0);
return 0;
}


Expand All @@ -1638,9 +1726,10 @@ extern "C" int rbd_aio_discard(rbd_image_t image, uint64_t off, uint64_t len,
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
tracepoint(librbd, aio_discard_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, off, len, comp->pc);
int r = librbd::aio_discard(ictx, off, len, (librbd::AioCompletion *)comp->pc);
tracepoint(librbd, aio_discard_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioDiscardWQ(ictx, off, len,
get_aio_completion(comp)));
tracepoint(librbd, aio_discard_exit, 0);
return 0;
}

extern "C" int rbd_aio_read(rbd_image_t image, uint64_t off, size_t len,
Expand All @@ -1649,10 +1738,10 @@ extern "C" int rbd_aio_read(rbd_image_t image, uint64_t off, size_t len,
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
tracepoint(librbd, aio_read_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, off, len, buf, comp->pc);
int r = librbd::aio_read(ictx, off, len, buf, NULL,
(librbd::AioCompletion *)comp->pc, 0);
tracepoint(librbd, aio_read_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioReadWQ(ictx, off, len, buf, NULL,
get_aio_completion(comp), 0));
tracepoint(librbd, aio_read_exit, 0);
return 0;
}

extern "C" int rbd_aio_read2(rbd_image_t image, uint64_t off, size_t len,
Expand All @@ -1662,10 +1751,11 @@ extern "C" int rbd_aio_read2(rbd_image_t image, uint64_t off, size_t len,
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
tracepoint(librbd, aio_read2_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(),
ictx->read_only, off, len, buf, comp->pc, op_flags);
int r = librbd::aio_read(ictx, off, len, buf, NULL,
(librbd::AioCompletion *)comp->pc, op_flags);
tracepoint(librbd, aio_read_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioReadWQ(ictx, off, len, buf, NULL,
get_aio_completion(comp),
op_flags));
tracepoint(librbd, aio_read_exit, 0);
return 0;
}

extern "C" int rbd_flush(rbd_image_t image)
Expand All @@ -1682,9 +1772,9 @@ extern "C" int rbd_aio_flush(rbd_image_t image, rbd_completion_t c)
librbd::ImageCtx *ictx = (librbd::ImageCtx *)image;
librbd::RBD::AioCompletion *comp = (librbd::RBD::AioCompletion *)c;
tracepoint(librbd, aio_flush_enter, ictx, ictx->name.c_str(), ictx->snap_name.c_str(), ictx->read_only, comp->pc);
int r = librbd::aio_flush(ictx, (librbd::AioCompletion *)comp->pc);
tracepoint(librbd, aio_flush_exit, r);
return r;
ictx->aio_work_queue->queue(new C_AioFlushWQ(ictx, get_aio_completion(comp)));
tracepoint(librbd, aio_flush_exit, 0);
return 0;
}

extern "C" int rbd_invalidate_cache(rbd_image_t image)
Expand Down

0 comments on commit cf6e1f5

Please sign in to comment.