Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/famz/tags/block-and-testing-pul…
Browse files Browse the repository at this point in the history
…l-request' into staging

# gpg: Signature made Mon 17 Jul 2017 04:47:05 BST
# gpg:                using RSA key 0xCA35624C6A9171C6
# gpg: Good signature from "Fam Zheng <famz@redhat.com>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 5003 7CB7 9706 0F76 F021  AD56 CA35 624C 6A91 71C6

* remotes/famz/tags/block-and-testing-pull-request:
  travis: add no-TCG build
  docker.py: Improve subprocess exit code handling
  docker.py: Drop infile parameter
  docker: Don't enable networking as a side-effect of DEBUG=1
  ssh: support I/O from any AioContext
  sheepdog: add queue_lock
  qed: protect table cache with CoMutex
  qed: introduce bdrv_qed_init_state
  block: invoke .bdrv_drain callback in coroutine context and from AioContext
  qed: move tail of qed_aio_write_main to qed_aio_write_{cow, alloc}
  vvfat: make it thread-safe
  vpc: make it thread-safe
  vdi: make it thread-safe
  coroutine-lock: add qemu_co_rwlock_downgrade and qemu_co_rwlock_upgrade
  qcow2: call CoQueue APIs under CoMutex

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jul 17, 2017
2 parents acbaa0f + 9783731 commit 6632f6f
Show file tree
Hide file tree
Showing 18 changed files with 355 additions and 161 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Expand Up @@ -86,6 +86,9 @@ matrix:
- env: CONFIG="--enable-trace-backends=ust"
TEST_CMD=""
compiler: gcc
- env: CONFIG="--disable-tcg"
TEST_CMD=""
compiler: gcc
- env: CONFIG=""
os: osx
compiler: clang
Expand Down
42 changes: 33 additions & 9 deletions block/io.c
Expand Up @@ -149,16 +149,46 @@ bool bdrv_requests_pending(BlockDriverState *bs)
return false;
}

typedef struct {
Coroutine *co;
BlockDriverState *bs;
bool done;
} BdrvCoDrainData;

static void coroutine_fn bdrv_drain_invoke_entry(void *opaque)
{
BdrvCoDrainData *data = opaque;
BlockDriverState *bs = data->bs;

bs->drv->bdrv_co_drain(bs);

/* Set data->done before reading bs->wakeup. */
atomic_mb_set(&data->done, true);
bdrv_wakeup(bs);
}

static void bdrv_drain_invoke(BlockDriverState *bs)
{
BdrvCoDrainData data = { .bs = bs, .done = false };

if (!bs->drv || !bs->drv->bdrv_co_drain) {
return;
}

data.co = qemu_coroutine_create(bdrv_drain_invoke_entry, &data);
bdrv_coroutine_enter(bs, data.co);
BDRV_POLL_WHILE(bs, !data.done);
}

static bool bdrv_drain_recurse(BlockDriverState *bs)
{
BdrvChild *child, *tmp;
bool waited;

waited = BDRV_POLL_WHILE(bs, atomic_read(&bs->in_flight) > 0);

if (bs->drv && bs->drv->bdrv_drain) {
bs->drv->bdrv_drain(bs);
}
/* Ensure any pending metadata writes are submitted to bs->file. */
bdrv_drain_invoke(bs);

QLIST_FOREACH_SAFE(child, &bs->children, next, tmp) {
BlockDriverState *bs = child->bs;
Expand All @@ -184,12 +214,6 @@ static bool bdrv_drain_recurse(BlockDriverState *bs)
return waited;
}

typedef struct {
Coroutine *co;
BlockDriverState *bs;
bool done;
} BdrvCoDrainData;

static void bdrv_co_drain_bh_cb(void *opaque)
{
BdrvCoDrainData *data = opaque;
Expand Down
4 changes: 2 additions & 2 deletions block/qcow2.c
Expand Up @@ -2025,8 +2025,6 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
ret = 0;

fail:
qemu_co_mutex_unlock(&s->lock);

while (l2meta != NULL) {
QCowL2Meta *next;

Expand All @@ -2040,6 +2038,8 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
l2meta = next;
}

qemu_co_mutex_unlock(&s->lock);

qemu_iovec_destroy(&hd_qiov);
qemu_vfree(cluster_data);
trace_qcow2_writev_done_req(qemu_coroutine_self(), ret);
Expand Down
4 changes: 2 additions & 2 deletions block/qed-cluster.c
Expand Up @@ -85,6 +85,8 @@ static unsigned int qed_count_contiguous_clusters(BDRVQEDState *s,
*
* On failure QED_CLUSTER_L2 or QED_CLUSTER_L1 is returned for missing L2 or L1
* table offset, respectively. len is number of contiguous unallocated bytes.
*
* Called with table_lock held.
*/
int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
uint64_t pos, size_t *len,
Expand Down Expand Up @@ -112,7 +114,6 @@ int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,
}

ret = qed_read_l2_table(s, request, l2_offset);
qed_acquire(s);
if (ret) {
goto out;
}
Expand All @@ -137,6 +138,5 @@ int coroutine_fn qed_find_cluster(BDRVQEDState *s, QEDRequest *request,

out:
*img_offset = offset;
qed_release(s);
return ret;
}
6 changes: 6 additions & 0 deletions block/qed-l2-cache.c
Expand Up @@ -101,6 +101,8 @@ CachedL2Table *qed_alloc_l2_cache_entry(L2TableCache *l2_cache)
/**
* Decrease an entry's reference count and free if necessary when the reference
* count drops to zero.
*
* Called with table_lock held.
*/
void qed_unref_l2_cache_entry(CachedL2Table *entry)
{
Expand All @@ -122,6 +124,8 @@ void qed_unref_l2_cache_entry(CachedL2Table *entry)
*
* For a cached entry, this function increases the reference count and returns
* the entry.
*
* Called with table_lock held.
*/
CachedL2Table *qed_find_l2_cache_entry(L2TableCache *l2_cache, uint64_t offset)
{
Expand Down Expand Up @@ -150,6 +154,8 @@ CachedL2Table *qed_find_l2_cache_entry(L2TableCache *l2_cache, uint64_t offset)
* N.B. This function steals a reference to the l2_table from the caller so the
* caller must obtain a new reference by issuing a call to
* qed_find_l2_cache_entry().
*
* Called with table_lock held.
*/
void qed_commit_l2_cache_entry(L2TableCache *l2_cache, CachedL2Table *l2_table)
{
Expand Down
24 changes: 18 additions & 6 deletions block/qed-table.c
Expand Up @@ -18,6 +18,7 @@
#include "qed.h"
#include "qemu/bswap.h"

/* Called either from qed_check or with table_lock held. */
static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
{
QEMUIOVector qiov;
Expand All @@ -32,18 +33,22 @@ static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)

trace_qed_read_table(s, offset, table);

if (qemu_in_coroutine()) {
qemu_co_mutex_unlock(&s->table_lock);
}
ret = bdrv_preadv(s->bs->file, offset, &qiov);
if (qemu_in_coroutine()) {
qemu_co_mutex_lock(&s->table_lock);
}
if (ret < 0) {
goto out;
}

/* Byteswap offsets */
qed_acquire(s);
noffsets = qiov.size / sizeof(uint64_t);
for (i = 0; i < noffsets; i++) {
table->offsets[i] = le64_to_cpu(table->offsets[i]);
}
qed_release(s);

ret = 0;
out:
Expand All @@ -61,6 +66,8 @@ static int qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table)
* @index: Index of first element
* @n: Number of elements
* @flush: Whether or not to sync to disk
*
* Called either from qed_check or with table_lock held.
*/
static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
unsigned int index, unsigned int n, bool flush)
Expand Down Expand Up @@ -97,16 +104,20 @@ static int qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table,
/* Adjust for offset into table */
offset += start * sizeof(uint64_t);

if (qemu_in_coroutine()) {
qemu_co_mutex_unlock(&s->table_lock);
}
ret = bdrv_pwritev(s->bs->file, offset, &qiov);
if (qemu_in_coroutine()) {
qemu_co_mutex_lock(&s->table_lock);
}
trace_qed_write_table_cb(s, table, flush, ret);
if (ret < 0) {
goto out;
}

if (flush) {
qed_acquire(s);
ret = bdrv_flush(s->bs);
qed_release(s);
if (ret < 0) {
goto out;
}
Expand All @@ -123,6 +134,7 @@ int qed_read_l1_table_sync(BDRVQEDState *s)
return qed_read_table(s, s->header.l1_table_offset, s->l1_table);
}

/* Called either from qed_check or with table_lock held. */
int qed_write_l1_table(BDRVQEDState *s, unsigned int index, unsigned int n)
{
BLKDBG_EVENT(s->bs->file, BLKDBG_L1_UPDATE);
Expand All @@ -136,6 +148,7 @@ int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
return qed_write_l1_table(s, index, n);
}

/* Called either from qed_check or with table_lock held. */
int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
{
int ret;
Expand All @@ -154,7 +167,6 @@ int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
BLKDBG_EVENT(s->bs->file, BLKDBG_L2_LOAD);
ret = qed_read_table(s, offset, request->l2_table->table);

qed_acquire(s);
if (ret) {
/* can't trust loaded L2 table anymore */
qed_unref_l2_cache_entry(request->l2_table);
Expand All @@ -170,7 +182,6 @@ int qed_read_l2_table(BDRVQEDState *s, QEDRequest *request, uint64_t offset)
request->l2_table = qed_find_l2_cache_entry(&s->l2_cache, offset);
assert(request->l2_table != NULL);
}
qed_release(s);

return ret;
}
Expand All @@ -180,6 +191,7 @@ int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset
return qed_read_l2_table(s, request, offset);
}

/* Called either from qed_check or with table_lock held. */
int qed_write_l2_table(BDRVQEDState *s, QEDRequest *request,
unsigned int index, unsigned int n, bool flush)
{
Expand Down

0 comments on commit 6632f6f

Please sign in to comment.