All of lore.kernel.org
 help / color / mirror / Atom feed
From: Cornelia Huck <cohuck@redhat.com>
To: David Hildenbrand <david@redhat.com>
Cc: qemu-s390x@nongnu.org, qemu-devel@nongnu.org,
	Richard Henderson <rth@twiddle.net>,
	Alexander Graf <agraf@suse.de>,
	Christian Borntraeger <borntraeger@de.ibm.com>,
	Thomas Huth <thuth@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: Re: [Qemu-devel] [PATCH RFC] s390x: refactor reset/reipl handling
Date: Mon, 23 Apr 2018 12:42:22 +0200	[thread overview]
Message-ID: <20180423124222.3c79c3fe.cohuck@redhat.com> (raw)
In-Reply-To: <20180412192602.13430-1-david@redhat.com>

On Thu, 12 Apr 2018 21:26:02 +0200
David Hildenbrand <david@redhat.com> wrote:

> Calling pause_all_vcpus()/resume_all_vcpus() from a VCPU thread might
> not be the best idea. As pause_all_vcpus() temporarily drops the qemu
> mutex, two parallel calls to pause_all_vcpus() can be active at a time,
> resulting in a deadlock. (either by two VCPUs or by the main thread and a
> VCPU)
> 
> Let's handle it via the main loop instead, as suggested by Paolo. If we
> would have two parallel reset requests by two different VCPUs at the
> same time, the last one would win.
> 
> We use the existing ipl device to handle it. The nice side effect is
> that we can get rid of reipl_requested.
> 
> This change implies that all reset handling now goes via the common
> path, so "no-reboot" handling is now active for all kinds of reboots.
> 
> Let's execute any CPU initialization code on the target CPU using
> run_on_cpu.
> 
> Signed-off-by: David Hildenbrand <david@redhat.com>
> ---
> 
> Did only a quick check with TCG. I think this way it is way easier to
> control what is getting reset.

Yes, I like this patch.

> 
>  hw/s390x/ipl.c                     | 44 ++++++++++++++++++++++++---
>  hw/s390x/ipl.h                     | 16 ++++++++--
>  hw/s390x/s390-virtio-ccw.c         | 49 +++++++++++++++++++++++++-----
>  include/hw/s390x/s390-virtio-ccw.h |  2 --
>  target/s390x/cpu.h                 | 26 ++++++++++++++++
>  target/s390x/diag.c                | 61 +++-----------------------------------
>  target/s390x/internal.h            |  6 ----
>  target/s390x/kvm.c                 |  2 +-
>  8 files changed, 127 insertions(+), 79 deletions(-)
> 
> diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
> index fb554ab156..f7589d20f1 100644
> --- a/hw/s390x/ipl.c
> +++ b/hw/s390x/ipl.c
> @@ -26,6 +26,7 @@
>  #include "qemu/config-file.h"
>  #include "qemu/cutils.h"
>  #include "qemu/option.h"
> +#include "exec/exec-all.h"
>  
>  #define KERN_IMAGE_START                0x010000UL
>  #define KERN_PARM_AREA                  0x010480UL
> @@ -484,11 +485,22 @@ IplParameterBlock *s390_ipl_get_iplb(void)
>      return &ipl->iplb;
>  }
>  
> -void s390_reipl_request(void)
> +void s390_ipl_reset_request(CPUState *cs, enum s390_reset reset_type)
>  {
>      S390IPLState *ipl = get_ipl_device();
>  
> -    ipl->reipl_requested = true;
> +    if (reset_type == S390_RESET_EXTERNAL || reset_type == S390_RESET_REIPL) {
> +        /* let's always use CPU 0 */
> +        ipl->reset_cpu = NULL;
> +    } else {
> +        ipl->reset_cpu = cs;
> +    }
> +    ipl->reset_type = reset_type;
> +
> +    if (reset_type != S390_RESET_REIPL) {

Pull the check for S390_RESET_REIPL into the if condition below? Gets
rid of the goto :)

> +        goto no_reipl;
> +    }
> +
>      if (ipl->iplb_valid &&
>          !ipl->netboot &&
>          ipl->iplb.pbt == S390_IPL_TYPE_CCW &&
> @@ -505,7 +517,32 @@ void s390_reipl_request(void)
>              ipl->iplb_valid = s390_gen_initial_iplb(ipl);
>          }
>      }
> +no_reipl:
>      qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
> +    /* as this is triggered by a CPU, make sure to exit the loop */
> +    if (tcg_enabled()) {
> +        cpu_loop_exit(cs);
> +    }
> +}
> +
> +void s390_ipl_get_reset_request(CPUState **cs, enum s390_reset *reset_type)
> +{
> +    S390IPLState *ipl = get_ipl_device();
> +
> +    *cs = ipl->reset_cpu;
> +    if (!ipl->reset_cpu) {
> +        /* use CPU 0 as default */
> +        *cs = qemu_get_cpu(0);

That looks somewhat ugly. Maybe just stuff cpu 0 in there at init time?

As an aside: Are we guaranteed to always have cpu 0? IIRC there was
some code relying on that; but just grabbing an 'any' cpu looks more
like what we want.

> +    }
> +    *reset_type = ipl->reset_type;
> +}

>  static void s390_machine_reset(void)
>  {
> -    S390CPU *ipl_cpu = S390_CPU(qemu_get_cpu(0));
> +    enum s390_reset reset_type;
> +    CPUState *cs, *t;
>  
> +    /* get the reset parameters, reset them once done */
> +    s390_ipl_get_reset_request(&cs, &reset_type);
> +
> +    /* all CPUs are paused and synchronized at this point */
>      s390_cmma_reset();
> -    qemu_devices_reset();
> -    s390_crypto_reset();
>  
> -    /* all cpus are stopped - configure and start the ipl cpu only */
> -    s390_ipl_prepare_cpu(ipl_cpu);
> -    s390_cpu_set_state(S390_CPU_STATE_OPERATING, ipl_cpu);
> +    switch (reset_type) {
> +    case S390_RESET_EXTERNAL:
> +    case S390_RESET_REIPL:
> +        qemu_devices_reset();
> +        s390_crypto_reset();
> +
> +        /* configure and start the ipl CPU only */
> +        run_on_cpu(cs, s390_do_cpu_ipl, RUN_ON_CPU_NULL);
> +        break;
> +    case S390_RESET_MODIFIED_CLEAR:
> +        CPU_FOREACH(t) {
> +            run_on_cpu(t, s390_do_cpu_full_reset, RUN_ON_CPU_NULL);
> +        }
> +        subsystem_reset();
> +        s390_crypto_reset();
> +        run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
> +        break;
> +    case S390_RESET_LOAD_NORMAL:
> +        CPU_FOREACH(t) {
> +            run_on_cpu(t, s390_do_cpu_reset, RUN_ON_CPU_NULL);
> +        }
> +        subsystem_reset();
> +        run_on_cpu(cs, s390_do_cpu_initital_reset, RUN_ON_CPU_NULL);

'initital' looks like a typo; 'initial'?

(But you made the same typo twice, so it compiles :)

> +        run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
> +        break;

Moan on default case hit?

> +    }
> +    s390_ipl_clear_reset_request();
>  }
>  
>  static void s390_machine_device_plug(HotplugHandler *hotplug_dev,

  parent reply	other threads:[~2018-04-23 10:42 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-12 19:26 [Qemu-devel] [PATCH RFC] s390x: refactor reset/reipl handling David Hildenbrand
2018-04-12 20:49 ` Paolo Bonzini
2018-04-18 14:08 ` Thomas Huth
2018-04-18 14:09   ` David Hildenbrand
2018-04-18 14:33 ` David Hildenbrand
2018-04-23 10:45   ` Cornelia Huck
2018-04-23 19:36     ` David Hildenbrand
2018-04-23 10:42 ` Cornelia Huck [this message]
2018-04-23 19:42   ` David Hildenbrand
2018-04-24  8:56 ` Christian Borntraeger

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=20180423124222.3c79c3fe.cohuck@redhat.com \
    --to=cohuck@redhat.com \
    --cc=agraf@suse.de \
    --cc=borntraeger@de.ibm.com \
    --cc=david@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-s390x@nongnu.org \
    --cc=rth@twiddle.net \
    --cc=thuth@redhat.com \
    /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.