Block layer patches:
- Fix double processing of nodes in bdrv_set_aio_context() - Fix potential hang in block export shutdown - block/nvme: Minor tracing improvements - iotests: Some more fixups for the 'check' rewrite - MAINTAINERS: Add Vladimir as co-maintainer for Block Jobs -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE3D3rFZqa+V09dFb+fwmycsiPL9YFAmAZfRoRHGt3b2xmQHJl ZGhhdC5jb20ACgkQfwmycsiPL9Y1ig//cClwP/uSJkIHRCmCsRL8XHtR9f3g8Jju CqB+b00VZGJx6b+d3CKty//LR/O8d8D8ZybnnyK0ruBKa3ayc+U5QBNByExJ6WRk Kf77MA5dUIx84t0O+XjO2NXjGiU3D3QGfjSF0Ex0nIEv+iUoVMYcUfep7cVz3/NN Vrt3xKPvRrptrrOwPDokkWpFCXhOha+I5gCX/JrKoeg/t4mBQxrYkkzgMHmqQY5o 3s4eI/5rFUpcMRqUj7Z9RNy4daR8BzCJKMLuzaoTbLy8UtaVhhhzY6a1qoJDYBRF YqbXTFwp8lS1QaQZCCYcl5LFEkmhqaj1GZXMLC2REsw53phVtWyv1xek42b/lmTx wB9VJcZhVfe5aswlI3WzPQS+D0rhzR1jxURaZvs7is1v7JOFkgT6Q6+Pbsx2GCpx uL/h6qCItPcfRj68zwJIaixeGa1JsECzTomFllI4jcL99fumxjDpU+E+4TuF2cEg Quk4VvFg7yKHJ5ci88lHNEWjOxLcxNDARk3PL+pyeP2Xe5imMfyHfYWzjjE5dK5g 94xqSoSrHgOc7kkshWk/ZRgpL8qa/tJuuzxX6mGxg9iUXmOr4HJNLWJp7BLKwqhm KUqpUUvlnjMRStGQ27GsQpeoO3t+x7/JKOZXWQ+7yB8dCrUHFVjFuljQu6PP2jCt qsUOIU1wGlo= =n0hS -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging Block layer patches: - Fix double processing of nodes in bdrv_set_aio_context() - Fix potential hang in block export shutdown - block/nvme: Minor tracing improvements - iotests: Some more fixups for the 'check' rewrite - MAINTAINERS: Add Vladimir as co-maintainer for Block Jobs # gpg: Signature made Tue 02 Feb 2021 16:26:02 GMT # gpg: using RSA key DC3DEB159A9AF95D3D7456FE7F09B272C88F2FD6 # gpg: issuer "kwolf@redhat.com" # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full] # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: block: Fix VM size column width in bdrv_snapshot_dump() block/nvme: Trace NVMe spec version supported by the controller block/nvme: Properly display doorbell stride length in trace event iotests: Fix -makecheck output iotests: check: return 1 on failure iotests: Revert emulator selection to old behaviour iotests/297: pylint: ignore too many statements block: move blk_exp_close_all() to qemu_cleanup() block: Avoid processing BDS twice in bdrv_set_aio_context_ignore() MAINTAINERS: Add Vladimir as co-maintainer for Block Jobs Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
77f3804ab7
10
MAINTAINERS
10
MAINTAINERS
@ -2210,6 +2210,7 @@ F: scsi/*
|
|||||||
|
|
||||||
Block Jobs
|
Block Jobs
|
||||||
M: John Snow <jsnow@redhat.com>
|
M: John Snow <jsnow@redhat.com>
|
||||||
|
M: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
|
||||||
L: qemu-block@nongnu.org
|
L: qemu-block@nongnu.org
|
||||||
S: Supported
|
S: Supported
|
||||||
F: blockjob.c
|
F: blockjob.c
|
||||||
@ -2222,7 +2223,16 @@ F: block/commit.c
|
|||||||
F: block/stream.c
|
F: block/stream.c
|
||||||
F: block/mirror.c
|
F: block/mirror.c
|
||||||
F: qapi/job.json
|
F: qapi/job.json
|
||||||
|
F: block/block-copy.c
|
||||||
|
F: include/block/block-copy.c
|
||||||
|
F: block/backup-top.h
|
||||||
|
F: block/backup-top.c
|
||||||
|
F: include/block/aio_task.h
|
||||||
|
F: block/aio_task.c
|
||||||
|
F: util/qemu-co-shared-resource.c
|
||||||
|
F: include/qemu/co-shared-resource.h
|
||||||
T: git https://gitlab.com/jsnow/qemu.git jobs
|
T: git https://gitlab.com/jsnow/qemu.git jobs
|
||||||
|
T: git https://src.openvz.org/scm/~vsementsov/qemu.git jobs
|
||||||
|
|
||||||
Block QAPI, monitor, command line
|
Block QAPI, monitor, command line
|
||||||
M: Markus Armbruster <armbru@redhat.com>
|
M: Markus Armbruster <armbru@redhat.com>
|
||||||
|
35
block.c
35
block.c
@ -4435,7 +4435,6 @@ static void bdrv_close(BlockDriverState *bs)
|
|||||||
void bdrv_close_all(void)
|
void bdrv_close_all(void)
|
||||||
{
|
{
|
||||||
assert(job_next(NULL) == NULL);
|
assert(job_next(NULL) == NULL);
|
||||||
blk_exp_close_all();
|
|
||||||
|
|
||||||
/* Drop references from requests still in flight, such as canceled block
|
/* Drop references from requests still in flight, such as canceled block
|
||||||
* jobs whose AIO context has not been polled yet */
|
* jobs whose AIO context has not been polled yet */
|
||||||
@ -6439,7 +6438,10 @@ void bdrv_set_aio_context_ignore(BlockDriverState *bs,
|
|||||||
AioContext *new_context, GSList **ignore)
|
AioContext *new_context, GSList **ignore)
|
||||||
{
|
{
|
||||||
AioContext *old_context = bdrv_get_aio_context(bs);
|
AioContext *old_context = bdrv_get_aio_context(bs);
|
||||||
BdrvChild *child;
|
GSList *children_to_process = NULL;
|
||||||
|
GSList *parents_to_process = NULL;
|
||||||
|
GSList *entry;
|
||||||
|
BdrvChild *child, *parent;
|
||||||
|
|
||||||
g_assert(qemu_get_current_aio_context() == qemu_get_aio_context());
|
g_assert(qemu_get_current_aio_context() == qemu_get_aio_context());
|
||||||
|
|
||||||
@ -6454,17 +6456,34 @@ void bdrv_set_aio_context_ignore(BlockDriverState *bs,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*ignore = g_slist_prepend(*ignore, child);
|
*ignore = g_slist_prepend(*ignore, child);
|
||||||
bdrv_set_aio_context_ignore(child->bs, new_context, ignore);
|
children_to_process = g_slist_prepend(children_to_process, child);
|
||||||
}
|
}
|
||||||
QLIST_FOREACH(child, &bs->parents, next_parent) {
|
|
||||||
if (g_slist_find(*ignore, child)) {
|
QLIST_FOREACH(parent, &bs->parents, next_parent) {
|
||||||
|
if (g_slist_find(*ignore, parent)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assert(child->klass->set_aio_ctx);
|
*ignore = g_slist_prepend(*ignore, parent);
|
||||||
*ignore = g_slist_prepend(*ignore, child);
|
parents_to_process = g_slist_prepend(parents_to_process, parent);
|
||||||
child->klass->set_aio_ctx(child, new_context, ignore);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (entry = children_to_process;
|
||||||
|
entry != NULL;
|
||||||
|
entry = g_slist_next(entry)) {
|
||||||
|
child = entry->data;
|
||||||
|
bdrv_set_aio_context_ignore(child->bs, new_context, ignore);
|
||||||
|
}
|
||||||
|
g_slist_free(children_to_process);
|
||||||
|
|
||||||
|
for (entry = parents_to_process;
|
||||||
|
entry != NULL;
|
||||||
|
entry = g_slist_next(entry)) {
|
||||||
|
parent = entry->data;
|
||||||
|
assert(parent->klass->set_aio_ctx);
|
||||||
|
parent->klass->set_aio_ctx(parent, new_context, ignore);
|
||||||
|
}
|
||||||
|
g_slist_free(parents_to_process);
|
||||||
|
|
||||||
bdrv_detach_aio_context(bs);
|
bdrv_detach_aio_context(bs);
|
||||||
|
|
||||||
/* Acquire the new context, if necessary */
|
/* Acquire the new context, if necessary */
|
||||||
|
@ -708,6 +708,7 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
|||||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||||
int ret;
|
int ret;
|
||||||
uint64_t cap;
|
uint64_t cap;
|
||||||
|
uint32_t ver;
|
||||||
uint64_t timeout_ms;
|
uint64_t timeout_ms;
|
||||||
uint64_t deadline, now;
|
uint64_t deadline, now;
|
||||||
volatile NvmeBar *regs = NULL;
|
volatile NvmeBar *regs = NULL;
|
||||||
@ -745,7 +746,7 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
|||||||
trace_nvme_controller_capability("Contiguous Queues Required",
|
trace_nvme_controller_capability("Contiguous Queues Required",
|
||||||
NVME_CAP_CQR(cap));
|
NVME_CAP_CQR(cap));
|
||||||
trace_nvme_controller_capability("Doorbell Stride",
|
trace_nvme_controller_capability("Doorbell Stride",
|
||||||
2 << (2 + NVME_CAP_DSTRD(cap)));
|
1 << (2 + NVME_CAP_DSTRD(cap)));
|
||||||
trace_nvme_controller_capability("Subsystem Reset Supported",
|
trace_nvme_controller_capability("Subsystem Reset Supported",
|
||||||
NVME_CAP_NSSRS(cap));
|
NVME_CAP_NSSRS(cap));
|
||||||
trace_nvme_controller_capability("Memory Page Size Minimum",
|
trace_nvme_controller_capability("Memory Page Size Minimum",
|
||||||
@ -764,6 +765,11 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
|||||||
bs->bl.request_alignment = s->page_size;
|
bs->bl.request_alignment = s->page_size;
|
||||||
timeout_ms = MIN(500 * NVME_CAP_TO(cap), 30000);
|
timeout_ms = MIN(500 * NVME_CAP_TO(cap), 30000);
|
||||||
|
|
||||||
|
ver = le32_to_cpu(regs->vs);
|
||||||
|
trace_nvme_controller_spec_version(extract32(ver, 16, 16),
|
||||||
|
extract32(ver, 8, 8),
|
||||||
|
extract32(ver, 0, 8));
|
||||||
|
|
||||||
/* Reset device to get a clean state. */
|
/* Reset device to get a clean state. */
|
||||||
regs->cc = cpu_to_le32(le32_to_cpu(regs->cc) & 0xFE);
|
regs->cc = cpu_to_le32(le32_to_cpu(regs->cc) & 0xFE);
|
||||||
/* Wait for CSTS.RDY = 0. */
|
/* Wait for CSTS.RDY = 0. */
|
||||||
|
@ -677,7 +677,7 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
|
|||||||
char *sizing = NULL;
|
char *sizing = NULL;
|
||||||
|
|
||||||
if (!sn) {
|
if (!sn) {
|
||||||
qemu_printf("%-10s%-18s%7s%20s%13s%11s",
|
qemu_printf("%-10s%-17s%8s%20s%13s%11s",
|
||||||
"ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT");
|
"ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT");
|
||||||
} else {
|
} else {
|
||||||
ti = sn->date_sec;
|
ti = sn->date_sec;
|
||||||
@ -696,7 +696,7 @@ void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
|
|||||||
snprintf(icount_buf, sizeof(icount_buf),
|
snprintf(icount_buf, sizeof(icount_buf),
|
||||||
"%"PRId64, sn->icount);
|
"%"PRId64, sn->icount);
|
||||||
}
|
}
|
||||||
qemu_printf("%-9s %-17s %7s%20s%13s%11s",
|
qemu_printf("%-9s %-16s %8s%20s%13s%11s",
|
||||||
sn->id_str, sn->name,
|
sn->id_str, sn->name,
|
||||||
sizing,
|
sizing,
|
||||||
date_buf,
|
date_buf,
|
||||||
|
@ -136,6 +136,7 @@ qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s
|
|||||||
# nvme.c
|
# nvme.c
|
||||||
nvme_controller_capability_raw(uint64_t value) "0x%08"PRIx64
|
nvme_controller_capability_raw(uint64_t value) "0x%08"PRIx64
|
||||||
nvme_controller_capability(const char *desc, uint64_t value) "%s: %"PRIu64
|
nvme_controller_capability(const char *desc, uint64_t value) "%s: %"PRIu64
|
||||||
|
nvme_controller_spec_version(uint32_t mjr, uint32_t mnr, uint32_t ter) "Specification supported: %u.%u.%u"
|
||||||
nvme_kick(void *s, unsigned q_index) "s %p q #%u"
|
nvme_kick(void *s, unsigned q_index) "s %p q #%u"
|
||||||
nvme_dma_flush_queue_wait(void *s) "s %p"
|
nvme_dma_flush_queue_wait(void *s) "s %p"
|
||||||
nvme_error(int cmd_specific, int sq_head, int sqid, int cid, int status) "cmd_specific %d sq_head %d sqid %d cid %d status 0x%x"
|
nvme_error(int cmd_specific, int sq_head, int sqid, int cid, int status) "cmd_specific %d sq_head %d sqid %d cid %d status 0x%x"
|
||||||
|
@ -503,6 +503,7 @@ static const char *socket_activation_validate_opts(const char *device,
|
|||||||
static void qemu_nbd_shutdown(void)
|
static void qemu_nbd_shutdown(void)
|
||||||
{
|
{
|
||||||
job_cancel_sync_all();
|
job_cancel_sync_all();
|
||||||
|
blk_exp_close_all();
|
||||||
bdrv_close_all();
|
bdrv_close_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "audio/audio.h"
|
#include "audio/audio.h"
|
||||||
#include "block/block.h"
|
#include "block/block.h"
|
||||||
|
#include "block/export.h"
|
||||||
#include "chardev/char.h"
|
#include "chardev/char.h"
|
||||||
#include "crypto/cipher.h"
|
#include "crypto/cipher.h"
|
||||||
#include "crypto/init.h"
|
#include "crypto/init.h"
|
||||||
@ -784,6 +785,14 @@ void qemu_cleanup(void)
|
|||||||
*/
|
*/
|
||||||
migration_shutdown();
|
migration_shutdown();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Close the exports before draining the block layer. The export
|
||||||
|
* drivers may have coroutines yielding on it, so we need to clean
|
||||||
|
* them up before the drain, as otherwise they may be get stuck in
|
||||||
|
* blk_wait_while_drained().
|
||||||
|
*/
|
||||||
|
blk_exp_close_all();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must cancel all block jobs while the block layer is drained,
|
* We must cancel all block jobs while the block layer is drained,
|
||||||
* or cancelling will be affected by throttling and thus may block
|
* or cancelling will be affected by throttling and thus may block
|
||||||
|
@ -314,6 +314,7 @@ int main(int argc, char *argv[])
|
|||||||
main_loop_wait(false);
|
main_loop_wait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
blk_exp_close_all();
|
||||||
bdrv_drain_all_begin();
|
bdrv_drain_all_begin();
|
||||||
bdrv_close_all();
|
bdrv_close_all();
|
||||||
|
|
||||||
|
@ -140,4 +140,7 @@ if __name__ == '__main__':
|
|||||||
else:
|
else:
|
||||||
with TestRunner(env, makecheck=args.makecheck,
|
with TestRunner(env, makecheck=args.makecheck,
|
||||||
color=args.color) as tr:
|
color=args.color) as tr:
|
||||||
tr.run_tests([os.path.join(env.source_iotests, t) for t in tests])
|
paths = [os.path.join(env.source_iotests, t) for t in tests]
|
||||||
|
ok = tr.run_tests(paths)
|
||||||
|
if not ok:
|
||||||
|
sys.exit(1)
|
||||||
|
@ -21,6 +21,8 @@ disable=invalid-name,
|
|||||||
unsubscriptable-object,
|
unsubscriptable-object,
|
||||||
# These are temporary, and should be removed:
|
# These are temporary, and should be removed:
|
||||||
missing-docstring,
|
missing-docstring,
|
||||||
|
too-many-return-statements,
|
||||||
|
too-many-statements
|
||||||
|
|
||||||
[FORMAT]
|
[FORMAT]
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ class TestEnv(ContextManager['TestEnv']):
|
|||||||
if not os.path.exists(self.qemu_prog):
|
if not os.path.exists(self.qemu_prog):
|
||||||
pattern = root('qemu-system-*')
|
pattern = root('qemu-system-*')
|
||||||
try:
|
try:
|
||||||
progs = glob.iglob(pattern)
|
progs = sorted(glob.iglob(pattern))
|
||||||
self.qemu_prog = next(p for p in progs if isxfile(p))
|
self.qemu_prog = next(p for p in progs if isxfile(p))
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
sys.exit("Not found any Qemu executable binary by pattern "
|
sys.exit("Not found any Qemu executable binary by pattern "
|
||||||
|
@ -301,8 +301,10 @@ class TestRunner(ContextManager['TestRunner']):
|
|||||||
last_el = self.last_elapsed.get(test)
|
last_el = self.last_elapsed.get(test)
|
||||||
start = datetime.datetime.now().strftime('%H:%M:%S')
|
start = datetime.datetime.now().strftime('%H:%M:%S')
|
||||||
|
|
||||||
self.test_print_one_line(test=test, starttime=start, lasttime=last_el,
|
if not self.makecheck:
|
||||||
end='\r', test_field_width=test_field_width)
|
self.test_print_one_line(test=test, starttime=start,
|
||||||
|
lasttime=last_el, end='\r',
|
||||||
|
test_field_width=test_field_width)
|
||||||
|
|
||||||
res = self.do_run_test(test)
|
res = self.do_run_test(test)
|
||||||
|
|
||||||
@ -318,7 +320,7 @@ class TestRunner(ContextManager['TestRunner']):
|
|||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def run_tests(self, tests: List[str]) -> None:
|
def run_tests(self, tests: List[str]) -> bool:
|
||||||
n_run = 0
|
n_run = 0
|
||||||
failed = []
|
failed = []
|
||||||
notrun = []
|
notrun = []
|
||||||
@ -363,5 +365,7 @@ class TestRunner(ContextManager['TestRunner']):
|
|||||||
if failed:
|
if failed:
|
||||||
print('Failures:', ' '.join(failed))
|
print('Failures:', ' '.join(failed))
|
||||||
print(f'Failed {len(failed)} of {n_run} iotests')
|
print(f'Failed {len(failed)} of {n_run} iotests')
|
||||||
|
return False
|
||||||
else:
|
else:
|
||||||
print(f'Passed all {n_run} iotests')
|
print(f'Passed all {n_run} iotests')
|
||||||
|
return True
|
||||||
|
Loading…
x
Reference in New Issue
Block a user