All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@gmail.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: qemu-block@nongnu.org, qemu-devel@nongnu.org
Subject: Re: [PULL 00/28] Block layer patches
Date: Tue, 19 Sep 2023 15:34:44 -0400	[thread overview]
Message-ID: <CAJSP0QW4wBzBaf2dJpFVw8A_5EtOZh12eLjLfHkPPn4C0V1s=w@mail.gmail.com> (raw)
In-Reply-To: <ZQl3Tp7uWPyn/gYa@redhat.com>

On Tue, 19 Sept 2023 at 06:26, Kevin Wolf <kwolf@redhat.com> wrote:
>
> Am 18.09.2023 um 20:56 hat Stefan Hajnoczi geschrieben:
> > Hi Kevin,
> > I believe that my own commit "block-coroutine-wrapper: use
> > qemu_get_current_aio_context()" breaks this test. The failure is
> > non-deterministic (happens about 1 out of 4 runs).
> >
> > It seems the job hangs and the test times out in vm.run_job('job1', wait=5.0).
> >
> > I haven't debugged it yet but wanted to share this information to save
> > some time. Tomorrow I'll investigate further.
>
> Yes, it's relatively easily reproducible if I run the test in a loop,
> and I can't seem to reproduce it without the last patch. Should I
> unstage the full series again, or do you think that the last patch is
> really optional this time?
>
> However, I'm unsure how the stack traces I'm seeing are related to your
> patch. Maybe it just made an existing bug more likely to be triggered?
>
> What I'm seeing is that the reader lock is held by an iothread that is
> waiting for its AioContext lock to make progress:
>
> Thread 3 (Thread 0x7f811e9346c0 (LWP 26390) "qemu-system-x86"):
> #0  0x00007f81250aaf80 in __lll_lock_wait () at /lib64/libc.so.6
> #1  0x00007f81250b149a in pthread_mutex_lock@@GLIBC_2.2.5 () at /lib64/libc.so.6
> #2  0x000055b7b170967e in qemu_mutex_lock_impl (mutex=0x55b7b34e3080, file=0x55b7b199e1f7 "../util/async.c", line=728) at ../util/qemu-thread-posix.c:94
> #3  0x000055b7b1709953 in qemu_rec_mutex_lock_impl (mutex=0x55b7b34e3080, file=0x55b7b199e1f7 "../util/async.c", line=728) at ../util/qemu-thread-posix.c:149
> #4  0x000055b7b1728318 in aio_context_acquire (ctx=0x55b7b34e3020) at ../util/async.c:728
> #5  0x000055b7b1727c49 in co_schedule_bh_cb (opaque=0x55b7b34e3020) at ../util/async.c:565
> #6  0x000055b7b1726f1c in aio_bh_call (bh=0x55b7b34e2e70) at ../util/async.c:169
> #7  0x000055b7b17270ee in aio_bh_poll (ctx=0x55b7b34e3020) at ../util/async.c:216
> #8  0x000055b7b170351d in aio_poll (ctx=0x55b7b34e3020, blocking=true) at ../util/aio-posix.c:722
> #9  0x000055b7b1518604 in iothread_run (opaque=0x55b7b2904460) at ../iothread.c:63
> #10 0x000055b7b170a955 in qemu_thread_start (args=0x55b7b34e36b0) at ../util/qemu-thread-posix.c:541
> #11 0x00007f81250ae15d in start_thread () at /lib64/libc.so.6
> #12 0x00007f812512fc00 in clone3 () at /lib64/libc.so.6
>
> On the other hand, the main thread wants to acquire the writer lock,
> but it holds the AioContext lock of the iothread (it takes it in
> job_prepare_locked()):
>
> Thread 1 (Thread 0x7f811f4b7b00 (LWP 26388) "qemu-system-x86"):
> #0  0x00007f8125122356 in ppoll () at /lib64/libc.so.6
> #1  0x000055b7b172eae0 in qemu_poll_ns (fds=0x55b7b34ec910, nfds=1, timeout=-1) at ../util/qemu-timer.c:339
> #2  0x000055b7b1704ebd in fdmon_poll_wait (ctx=0x55b7b3269210, ready_list=0x7ffc90b05680, timeout=-1) at ../util/fdmon-poll.c:79
> #3  0x000055b7b1703284 in aio_poll (ctx=0x55b7b3269210, blocking=true) at ../util/aio-posix.c:670
> #4  0x000055b7b1567c3b in bdrv_graph_wrlock (bs=0x0) at ../block/graph-lock.c:145
> #5  0x000055b7b1554c1c in blk_remove_bs (blk=0x55b7b4425800) at ../block/block-backend.c:916
> #6  0x000055b7b1554779 in blk_delete (blk=0x55b7b4425800) at ../block/block-backend.c:497
> #7  0x000055b7b1554133 in blk_unref (blk=0x55b7b4425800) at ../block/block-backend.c:557
> #8  0x000055b7b157a149 in mirror_exit_common (job=0x55b7b4419000) at ../block/mirror.c:696
> #9  0x000055b7b1577015 in mirror_prepare (job=0x55b7b4419000) at ../block/mirror.c:807
> #10 0x000055b7b153a1a7 in job_prepare_locked (job=0x55b7b4419000) at ../job.c:988
> #11 0x000055b7b153a0d9 in job_txn_apply_locked (job=0x55b7b4419000, fn=0x55b7b153a110 <job_prepare_locked>) at ../job.c:191
> #12 0x000055b7b1538b6d in job_do_finalize_locked (job=0x55b7b4419000) at ../job.c:1011
> #13 0x000055b7b153a886 in job_completed_txn_success_locked (job=0x55b7b4419000) at ../job.c:1068
> #14 0x000055b7b1539372 in job_completed_locked (job=0x55b7b4419000) at ../job.c:1082
> #15 0x000055b7b153a71b in job_exit (opaque=0x55b7b4419000) at ../job.c:1103
> #16 0x000055b7b1726f1c in aio_bh_call (bh=0x7f8110005470) at ../util/async.c:169
> #17 0x000055b7b17270ee in aio_bh_poll (ctx=0x55b7b3269210) at ../util/async.c:216
> #18 0x000055b7b1702c05 in aio_dispatch (ctx=0x55b7b3269210) at ../util/aio-posix.c:423
> #19 0x000055b7b1728a14 in aio_ctx_dispatch (source=0x55b7b3269210, callback=0x0, user_data=0x0) at ../util/async.c:358
> #20 0x00007f8126c31c7f in g_main_dispatch (context=0x55b7b3269720) at ../glib/gmain.c:3454
> #21 g_main_context_dispatch (context=0x55b7b3269720) at ../glib/gmain.c:4172
> #22 0x000055b7b1729c98 in glib_pollfds_poll () at ../util/main-loop.c:290
> #23 0x000055b7b1729572 in os_host_main_loop_wait (timeout=27462700) at ../util/main-loop.c:313
> #24 0x000055b7b1729452 in main_loop_wait (nonblocking=0) at ../util/main-loop.c:592
> #25 0x000055b7b119a1eb in qemu_main_loop () at ../softmmu/runstate.c:772
> #26 0x000055b7b14c102d in qemu_default_main () at ../softmmu/main.c:37
> #27 0x000055b7b14c1068 in main (argc=44, argv=0x7ffc90b05d58) at ../softmmu/main.c:48
>
> At first I thought we just need to look into the AioContext locking in
> job completion and drop it in the right places.
>
> But in fact, first of all, blk_remove_bs() needs to make up its mind if
> it wants the caller to hold the AioContext or not and document that.
> Because it calls both bdrv_drained_begin() (which requires holding the
> AioContext lock) and bdrv_graph_wrlock(NULL) (which forbids it).

I was surprised to see bdrv_graph_wrlock(NULL) called. The AioContext
lock is held across aio_poll() and that's why the hang occurs.

I'll make blk_remove_bs() consistent with respect to the AioContext
lock so this test failure can be fixed.

> If we could fully get rid of the AioContext lock (as we originally
> stated as a goal), that would automatically solve this kind of
> deadlocks.

Although it's not an indication that it's already safe to remove the
AioContext lock, I commented out the lock/unlock in
aio_context_acquire/release() and found that "make check" passes. Only
graph-changes-while-io fails when I run "qemu-iotests -qcow2".

I think the main thing keeping the AioContext lock around is
AIO_WAIT_WHILE(). The caller must hold the lock and that forces many
APIs to extend this requirement to their caller.

Perhaps more AIO_WAIT_WHILE() instances can now be converted to
AIO_WAIT_WHILE_UNLOCKED().

Stefan


  parent reply	other threads:[~2023-09-19 19:36 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-15 14:43 [PULL 00/28] Block layer patches Kevin Wolf
2023-09-15 14:43 ` [PULL 01/28] block: Remove unused BlockReopenQueueEntry.perms_checked Kevin Wolf
2023-09-15 14:43 ` [PULL 02/28] preallocate: Factor out preallocate_truncate_to_real_size() Kevin Wolf
2023-09-15 14:43 ` [PULL 03/28] preallocate: Don't poll during permission updates Kevin Wolf
2023-09-15 14:43 ` [PULL 04/28] block: Take AioContext lock for bdrv_append() more consistently Kevin Wolf
2023-09-15 14:43 ` [PULL 05/28] block: Introduce bdrv_schedule_unref() Kevin Wolf
2023-09-15 14:43 ` [PULL 06/28] block-coroutine-wrapper: Add no_co_wrapper_bdrv_wrlock functions Kevin Wolf
2023-09-15 14:43 ` [PULL 07/28] block-coroutine-wrapper: Allow arbitrary parameter names Kevin Wolf
2023-09-15 14:43 ` [PULL 08/28] block: Mark bdrv_replace_child_noperm() GRAPH_WRLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 09/28] block: Mark bdrv_replace_child_tran() GRAPH_WRLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 10/28] block: Mark bdrv_attach_child_common() GRAPH_WRLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 11/28] block: Call transaction callbacks with lock held Kevin Wolf
2023-09-15 14:43 ` [PULL 12/28] block: Mark bdrv_attach_child() GRAPH_WRLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 13/28] block: Mark bdrv_parent_perms_conflict() and callers GRAPH_RDLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 14/28] block: Mark bdrv_get_cumulative_perm() " Kevin Wolf
2023-09-15 14:43 ` [PULL 15/28] block: Mark bdrv_child_perm() GRAPH_RDLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 16/28] block: Mark bdrv_parent_cb_change_media() GRAPH_RDLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 17/28] block: Take graph rdlock in bdrv_drop_intermediate() Kevin Wolf
2023-09-15 14:43 ` [PULL 18/28] block: Take graph rdlock in bdrv_change_aio_context() Kevin Wolf
2023-09-15 14:43 ` [PULL 19/28] block: Mark bdrv_root_unref_child() GRAPH_WRLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 20/28] block: Mark bdrv_unref_child() GRAPH_WRLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 21/28] block: Mark bdrv_add/del_child() and caller GRAPH_WRLOCK Kevin Wolf
2023-09-15 14:43 ` [PULL 22/28] block: add BDRV_BLOCK_COMPRESSED flag for bdrv_block_status() Kevin Wolf
2023-09-15 14:43 ` [PULL 23/28] qemu-img: map: report compressed data blocks Kevin Wolf
2023-09-15 14:43 ` [PULL 24/28] block: remove AIOCBInfo->get_aio_context() Kevin Wolf
2023-09-15 14:43 ` [PULL 25/28] test-bdrv-drain: avoid race with BH in IOThread drain test Kevin Wolf
2023-09-15 14:43 ` [PULL 26/28] block-backend: process I/O in the current AioContext Kevin Wolf
2023-09-15 14:43 ` [PULL 27/28] block-backend: process zoned requests " Kevin Wolf
2023-09-15 14:43 ` [PULL 28/28] block-coroutine-wrapper: use qemu_get_current_aio_context() Kevin Wolf
2023-09-18 15:03 ` [PULL 00/28] Block layer patches Stefan Hajnoczi
2023-09-18 18:56   ` Stefan Hajnoczi
2023-09-19 10:26     ` Kevin Wolf
2023-09-19 17:35       ` Stefan Hajnoczi
2023-09-19 19:34       ` Stefan Hajnoczi [this message]
2023-09-19 20:08       ` Stefan Hajnoczi
  -- strict thread matches above, loose matches on Subject: below --
2023-05-10 12:20 Kevin Wolf
2023-05-10 15:42 ` Richard Henderson
2021-07-09 12:50 Kevin Wolf
2021-07-10 20:27 ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAJSP0QW4wBzBaf2dJpFVw8A_5EtOZh12eLjLfHkPPn4C0V1s=w@mail.gmail.com' \
    --to=stefanha@gmail.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.