[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-ppc] [PATCH 6/6] spapr: Clean up DRC set_isolation_state() pat
From: |
Michael Roth |
Subject: |
Re: [Qemu-ppc] [PATCH 6/6] spapr: Clean up DRC set_isolation_state() path |
Date: |
Mon, 19 Jun 2017 17:52:27 -0500 |
User-agent: |
alot/0.5.1 |
Quoting David Gibson (2017-06-08 00:09:30)
> There are substantial differences in the various paths through
> set_isolation_state(), both for setting to ISOLATED versus UNISOLATED
> state and for logical versus physical DRCs.
>
> So, split the set_isolation_state() method into isolate() and unisolate()
> methods, and give it different implementations for the two DRC types.
>
> Factor some minimal common checks, including for valid indicator values
> (which we weren't previously checking) into rtas_set_isolation_state().
>
> Signed-off-by: David Gibson <address@hidden>
> ---
> hw/ppc/spapr_drc.c | 145
> ++++++++++++++++++++++++++++++++-------------
> include/hw/ppc/spapr_drc.h | 6 +-
> 2 files changed, 105 insertions(+), 46 deletions(-)
>
> diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
> index 9e01d7b..90c0fde 100644
> --- a/hw/ppc/spapr_drc.c
> +++ b/hw/ppc/spapr_drc.c
> @@ -46,30 +46,64 @@ uint32_t spapr_drc_index(sPAPRDRConnector *drc)
> | (drc->id & DRC_INDEX_ID_MASK);
> }
>
> -static uint32_t set_isolation_state(sPAPRDRConnector *drc,
> - sPAPRDRIsolationState state)
> +static uint32_t drc_isolate_physical(sPAPRDRConnector *drc)
> {
> - trace_spapr_drc_set_isolation_state(spapr_drc_index(drc), state);
> -
> /* if the guest is configuring a device attached to this DRC, we
> * should reset the configuration state at this point since it may
> * no longer be reliable (guest released device and needs to start
> * over, or unplug occurred so the FDT is no longer valid)
> */
> - if (state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
> - g_free(drc->ccs);
> - drc->ccs = NULL;
> - }
> + g_free(drc->ccs);
> + drc->ccs = NULL;
>
> - if (state == SPAPR_DR_ISOLATION_STATE_UNISOLATED) {
> - /* cannot unisolate a non-existent resource, and, or resources
> - * which are in an 'UNUSABLE' allocation state. (PAPR 2.7, 13.5.3.5)
> - */
> - if (!drc->dev ||
> - drc->allocation_state == SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {
> - return RTAS_OUT_NO_SUCH_INDICATOR;
> + drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
> +
> + /* if we're awaiting release, but still in an unconfigured state,
> + * it's likely the guest is still in the process of configuring
> + * the device and is transitioning the devices to an ISOLATED
> + * state as a part of that process. so we only complete the
> + * removal when this transition happens for a device in a
> + * configured state, as suggested by the state diagram from PAPR+
> + * 2.7, 13.4
> + */
> + if (drc->awaiting_release) {
> + uint32_t drc_index = spapr_drc_index(drc);
> + if (drc->configured) {
> + trace_spapr_drc_set_isolation_state_finalizing(drc_index);
> + spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
> + } else {
> + trace_spapr_drc_set_isolation_state_deferring(drc_index);
> }
> }
> + drc->configured = false;
> +
> + return RTAS_OUT_SUCCESS;
> +}
> +
> +static uint32_t drc_unisolate_physical(sPAPRDRConnector *drc)
> +{
> + /* cannot unisolate a non-existent resource, and, or resources
> + * which are in an 'UNUSABLE' allocation state. (PAPR 2.7,
> + * 13.5.3.5)
> + */
> + if (!drc->dev) {
> + return RTAS_OUT_NO_SUCH_INDICATOR;
> + }
> +
> + drc->isolation_state = SPAPR_DR_ISOLATION_STATE_UNISOLATED;
> +
> + return RTAS_OUT_SUCCESS;
> +}
> +
> +static uint32_t drc_isolate_logical(sPAPRDRConnector *drc)
> +{
> + /* if the guest is configuring a device attached to this DRC, we
> + * should reset the configuration state at this point since it may
> + * no longer be reliable (guest released device and needs to start
> + * over, or unplug occurred so the FDT is no longer valid)
> + */
> + g_free(drc->ccs);
> + drc->ccs = NULL;
>
> /*
> * Fail any requests to ISOLATE the LMB DRC if this LMB doesn't
> @@ -81,35 +115,47 @@ static uint32_t set_isolation_state(sPAPRDRConnector
> *drc,
> * If the LMB being removed doesn't belong to a DIMM device that is
> * actually being unplugged, fail the isolation request here.
> */
> - if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB) {
> - if ((state == SPAPR_DR_ISOLATION_STATE_ISOLATED) &&
> - !drc->awaiting_release) {
> - return RTAS_OUT_HW_ERROR;
> - }
> + if (spapr_drc_type(drc) == SPAPR_DR_CONNECTOR_TYPE_LMB
> + && !drc->awaiting_release) {
> + return RTAS_OUT_HW_ERROR;
> }
>
> - drc->isolation_state = state;
> + drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;
>
> - if (drc->isolation_state == SPAPR_DR_ISOLATION_STATE_ISOLATED) {
> - /* if we're awaiting release, but still in an unconfigured state,
> - * it's likely the guest is still in the process of configuring
> - * the device and is transitioning the devices to an ISOLATED
> - * state as a part of that process. so we only complete the
> - * removal when this transition happens for a device in a
> - * configured state, as suggested by the state diagram from
> - * PAPR+ 2.7, 13.4
> - */
> - if (drc->awaiting_release) {
> - uint32_t drc_index = spapr_drc_index(drc);
> - if (drc->configured) {
> - trace_spapr_drc_set_isolation_state_finalizing(drc_index);
> - spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
> - } else {
> - trace_spapr_drc_set_isolation_state_deferring(drc_index);
> - }
> + /* if we're awaiting release, but still in an unconfigured state,
> + * it's likely the guest is still in the process of configuring
> + * the device and is transitioning the devices to an ISOLATED
> + * state as a part of that process. so we only complete the
> + * removal when this transition happens for a device in a
> + * configured state, as suggested by the state diagram from PAPR+
> + * 2.7, 13.4
> + */
> + if (drc->awaiting_release) {
> + uint32_t drc_index = spapr_drc_index(drc);
> + if (drc->configured) {
> + trace_spapr_drc_set_isolation_state_finalizing(drc_index);
> + spapr_drc_detach(drc, DEVICE(drc->dev), NULL);
> + } else {
> + trace_spapr_drc_set_isolation_state_deferring(drc_index);
Not sure this is the right patch to do it, but this refactoring does make
it more apparent that the if (drc->configured) checks should get pushed
down into spapr_drc_detach() like the other deferral checks at some point.
(There are 2 locations that do the detach without checking configured,
but you switched out the one in reset() to use spapr_drc_release()
already, and I don't think drc_set_unusable() without first going
through drc_isolate_*() is a transition that PAPR would allow anyway)
- [Qemu-ppc] [PATCH 4/6] spapr: Make DRC reset force DRC into known state, (continued)
- [Qemu-ppc] [PATCH 4/6] spapr: Make DRC reset force DRC into known state, David Gibson, 2017/06/08
- [Qemu-ppc] [PATCH 5/6] spapr: Clean up DRC set_allocation_state path, David Gibson, 2017/06/08
- [Qemu-ppc] [PATCH 1/6] spapr: Start hotplugged PCI devices in ISOLATED state, David Gibson, 2017/06/08
- [Qemu-ppc] [PATCH 6/6] spapr: Clean up DRC set_isolation_state() path, David Gibson, 2017/06/08
- Re: [Qemu-ppc] [Qemu-devel] [PATCH 0/6] spapr: DRC cleanups (part IV), Laurent Vivier, 2017/06/15
- Re: [Qemu-ppc] [PATCH 0/6] spapr: DRC cleanups (part IV), Michael Roth, 2017/06/19
- Re: [Qemu-ppc] [PATCH 0/6] spapr: DRC cleanups (part IV), David Gibson, 2017/06/19