|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 3/5] hvmemul_do_io: If the send to the ioreq server failed do not retry.
On 01/30/15 13:17, Don Slutz wrote:
> On 01/30/15 05:23, Jan Beulich wrote:
>>>>> On 30.01.15 at 01:52, <dslutz@xxxxxxxxxxx> wrote:
>>> I.E. do just what no backing DM does.
>>
>> _If_ this is correct, the if() modified here should be folded with the
>> one a few lines up.
>
> Ok, will fold with the one a few lines up. As expected without this
> change the guest will hang (more details below).
>
>
>> But looking at the description of the commit that
>> introduced this (bac0999325 "x86 hvm: Do not incorrectly retire an
>> instruction emulation...", almost immediately modified by f20f3c8ece
>> "x86 hvm: On failed hvm_send_assist_req(), io emulation...") I doubt
>> this is really what we want, or at the very least your change
>> description should explain what was wrong with the original commit.
>>
>
> Looking at these 2 commits, it looks to me like I need to handle these
> cases also. So it looks like having hvm_send_assist_req() return an int
> 0, 1, & 2 is the simpler way. V2 on the way soon.
>
Soon after sending this, I came up with a 2nd way for fix.
Change hvm_has_dm() to use hvm_select_ioreq_server(). Then
the correct answer will be found, and so will not retry.
To avoid 2 calls to hvm_select_ioreq_server(), it makes
snes to me to return s. Also adding a call to hvm_complete_assist_req()
would help. So based on all this is is a possible v2:
commit 24eb5a839427ba80c1adf16ab656c19729f906be
Author: Don Slutz <dslutz@xxxxxxxxxxx>
Date: Fri Jan 30 13:54:43 2015 -0500
fixup use of hvm_send_assist_req
Signed-off-by: Don Slutz <dslutz@xxxxxxxxxxx>
diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
index 2ed4344..7c3c654 100644
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -218,8 +218,11 @@ static int hvmemul_do_io(
vio->io_state = HVMIO_handle_mmio_awaiting_completion;
break;
case X86EMUL_UNHANDLEABLE:
+ {
+ void *s = hvm_has_dm(curr->domain, &p);
+
/* If there is no backing DM, just ignore accesses */
- if ( !hvm_has_dm(curr->domain) )
+ if ( !s )
{
rc = X86EMUL_OKAY;
vio->io_state = HVMIO_none;
@@ -227,11 +230,12 @@ static int hvmemul_do_io(
else
{
rc = X86EMUL_RETRY;
- if ( !hvm_send_assist_req(&p) )
+ if ( !hvm_send_assist_req(s, &p) )
vio->io_state = HVMIO_none;
else if ( p_data == NULL )
rc = X86EMUL_OKAY;
}
+ }
break;
default:
BUG();
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 984af81..21d4a73 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -2507,9 +2507,45 @@ int hvm_buffered_io_send(ioreq_t *p)
return 1;
}
-bool_t hvm_has_dm(struct domain *d)
+static bool_t hvm_complete_assist_req(ioreq_t *p)
{
- return !list_empty(&d->arch.hvm_domain.ioreq_server.list);
+ HVMTRACE_1D(COMPLETE_ASSIST, p->type);
+ ASSERT(p->type != IOREQ_TYPE_PCI_CONFIG);
+ switch ( p->type )
+ {
+ case IOREQ_TYPE_COPY:
+ case IOREQ_TYPE_PIO:
+ if ( p->dir == IOREQ_READ )
+ {
+ if ( !p->data_is_ptr )
+ p->data = ~0ul;
+ else
+ {
+ int i, step = p->df ? -p->size : p->size;
+ uint32_t data = ~0;
+
+ for ( i = 0; i < p->count; i++ )
+ hvm_copy_to_guest_phys(p->data + step * i, &data,
+ p->size);
+ }
+ }
+ /* FALLTHRU */
+ default:
+ p->state = STATE_IORESP_READY;
+ hvm_io_assist(p);
+ break;
+ }
+
+ return 1;
+}
+
+void *hvm_has_dm(struct domain *d, ioreq_t *p)
+{
+ struct hvm_ioreq_server *s = hvm_select_ioreq_server(d, p);
+
+ if ( !s )
+ hvm_complete_assist_req(p);
+ return (void *)s;
}
bool_t hvm_send_assist_req_to_ioreq_server(struct hvm_ioreq_server *s,
@@ -2571,44 +2607,15 @@ bool_t
hvm_send_assist_req_to_ioreq_server(struct hvm_ioreq_server *s,
return 0;
}
-static bool_t hvm_complete_assist_req(ioreq_t *p)
-{
- HVMTRACE_1D(COMPLETE_ASSIST, p->type);
- ASSERT(p->type != IOREQ_TYPE_PCI_CONFIG);
- switch ( p->type )
- {
- case IOREQ_TYPE_COPY:
- case IOREQ_TYPE_PIO:
- if ( p->dir == IOREQ_READ )
- {
- if ( !p->data_is_ptr )
- p->data = ~0ul;
- else
- {
- int i, step = p->df ? -p->size : p->size;
- uint32_t data = ~0;
-
- for ( i = 0; i < p->count; i++ )
- hvm_copy_to_guest_phys(p->data + step * i, &data,
- p->size);
- }
- }
- /* FALLTHRU */
- default:
- p->state = STATE_IORESP_READY;
- hvm_io_assist(p);
- break;
- }
-
- return 0; /* implicitly bins the i/o operation */
-}
-
-bool_t hvm_send_assist_req(ioreq_t *p)
+bool_t hvm_send_assist_req(void *vs, ioreq_t *p)
{
- struct hvm_ioreq_server *s =
hvm_select_ioreq_server(current->domain, p);
+ struct hvm_ioreq_server *s = vs;
if ( !s )
- return hvm_complete_assist_req(p);
+ {
+ hvm_complete_assist_req(p);
+ return 1;
+ }
return hvm_send_assist_req_to_ioreq_server(s, p);
}
diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h
index e3d2d9a..1923842 100644
--- a/xen/include/asm-x86/hvm/hvm.h
+++ b/xen/include/asm-x86/hvm/hvm.h
@@ -228,7 +228,7 @@ int hvm_vcpu_cacheattr_init(struct vcpu *v);
void hvm_vcpu_cacheattr_destroy(struct vcpu *v);
void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip);
-bool_t hvm_send_assist_req(ioreq_t *p);
+bool_t hvm_send_assist_req(void *s, ioreq_t *p);
void hvm_broadcast_assist_req(ioreq_t *p);
void hvm_get_guest_pat(struct vcpu *v, u64 *guest_pat);
@@ -359,7 +359,7 @@ void hvm_hypervisor_cpuid_leaf(uint32_t sub_idx,
void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx);
void hvm_migrate_timers(struct vcpu *v);
-bool_t hvm_has_dm(struct domain *d);
+void *hvm_has_dm(struct domain *d, ioreq_t *p);
bool_t hvm_io_pending(struct vcpu *v);
void hvm_do_resume(struct vcpu *v);
void hvm_migrate_pirqs(struct vcpu *v);
-Don Slutz
> Which is the better codding style:
>
> 1) Add #defines for the return values?
> 2) Just use numbers?
> 3) Invert the sense 0 means worked, 1 is shutdown_deferral or
> domain_crash, 2 is hvm_complete_assist_req()?
>
>
> I.E. (for just adding 2):
>
>
> diff --git a/xen/arch/x86/hvm/emulate.c b/xen/arch/x86/hvm/emulate.c
> index 2ed4344..c565151 100644
> --- a/xen/arch/x86/hvm/emulate.c
> +++ b/xen/arch/x86/hvm/emulate.c
> @@ -227,10 +227,19 @@ static int hvmemul_do_io(
> else
> {
> rc = X86EMUL_RETRY;
> - if ( !hvm_send_assist_req(&p) )
> - vio->io_state = HVMIO_none;
> - else if ( p_data == NULL )
> + switch ( hvm_send_assist_req(&p) )
> + {
> + case 2:
> rc = X86EMUL_OKAY;
> + /* fall through */
> + case 0:
> + vio->io_state = HVMIO_none;
> + break;
> + case 1:
> + if ( p_data == NULL )
> + rc = X86EMUL_OKAY;
> + break;
> + }
> }
>
>
> ???
>
>
>
> I would think it would be good for the code using hvm_has_dm()
> to also call on hvm_complete_assist_req(). hvm_has_dm() is a subset of
> the cases that hvm_select_ioreq_server() checks for.
>
> Based on this, I think it would be better to remove the call on
> hvm_has_dm() instead of adding a call to hvm_complete_assist_req().
>
>
> -Don Slutz
> P.S. Details for hang:
>
> Using:
>
> static bool_t hvm_complete_assist_req(ioreq_t *p)
> {
> + HVMTRACE_1D(COMPLETE_ASSIST, p->type);
> ...
> ):
>
> I get the trace:
>
> CPU1 745455716325 (+ 1362) VMEXIT [ exitcode = 0x0000001e, rIP
> = 0x00101581 ]
> CPU1 0 (+ 0) COMPLETE_ASSIST [ type = 0 ]
> CPU1 0 (+ 0) HANDLE_PIO [ port = 0x0cfe size = 2 dir = 1
> io_state = 0 ret = 0 ]
> CPU1 745455717846 (+ 1521) vlapic_accept_pic_intr [ i8259_target =
> 1, accept_pic_int = 1 ]
> CPU1 745455718209 (+ 363) VMENTRY
> CPU1 745455719568 (+ 1359) VMEXIT [ exitcode = 0x0000001e, rIP
> = 0x00101581 ]
> CPU1 0 (+ 0) COMPLETE_ASSIST [ type = 0 ]
> CPU1 0 (+ 0) HANDLE_PIO [ port = 0x0cfe size = 2 dir = 1
> io_state = 0 ret = 0 ]
> CPU1 745455721083 (+ 1515) vlapic_accept_pic_intr [ i8259_target =
> 1, accept_pic_int = 1 ]
> CPU1 745455721422 (+ 339) VMENTRY
> CPU1 745455722781 (+ 1359) VMEXIT [ exitcode = 0x0000001e, rIP
> = 0x00101581 ]
> CPU1 0 (+ 0) COMPLETE_ASSIST [ type = 0 ]
> CPU1 0 (+ 0) HANDLE_PIO [ port = 0x0cfe size = 2 dir = 1
> io_state = 0 ret = 0 ]
> CPU1 745455724299 (+ 1518) vlapic_accept_pic_intr [ i8259_target =
> 1, accept_pic_int = 1 ]
> CPU1 745455724656 (+ 357) VMENTRY
> CPU1 745455726009 (+ 1353) VMEXIT [ exitcode = 0x0000001e, rIP
> = 0x00101581 ]
> CPU1 0 (+ 0) COMPLETE_ASSIST [ type = 0 ]
> CPU1 0 (+ 0) HANDLE_PIO [ port = 0x0cfe size = 2 dir = 1
> io_state = 0 ret = 0 ]
> CPU1 745455727539 (+ 1530) vlapic_accept_pic_intr [ i8259_target =
> 1, accept_pic_int = 1 ]
> CPU1 745455727899 (+ 360) VMENTRY
> CPU1 745455729276 (+ 1377) VMEXIT [ exitcode = 0x0000001e, rIP
> = 0x00101581 ]
> CPU1 0 (+ 0) COMPLETE_ASSIST [ type = 0 ]
> CPU1 0 (+ 0) HANDLE_PIO [ port = 0x0cfe size = 2 dir = 1
> io_state = 0 ret = 0 ]
> CPU1 745455730803 (+ 1527) vlapic_accept_pic_intr [ i8259_target =
> 1, accept_pic_int = 1 ]
> CPU1 745455731163 (+ 360) VMENTRY
> CPU1 745455732525 (+ 1362) VMEXIT [ exitcode = 0x0000001e, rIP
> = 0x00101581 ]
> CPU1 0 (+ 0) COMPLETE_ASSIST [ type = 0 ]
> CPU1 0 (+ 0) HANDLE_PIO [ port = 0x0cfe size = 2 dir = 1
> io_state = 0 ret = 0 ]
> CPU1 745455734049 (+ 1524) vlapic_accept_pic_intr [ i8259_target =
> 1, accept_pic_int = 1 ]
> CPU1 745455734385 (+ 336) VMENTRY
> ...
>
>
>> Jan
>>
>>> --- a/xen/arch/x86/hvm/emulate.c
>>> +++ b/xen/arch/x86/hvm/emulate.c
>>> @@ -228,7 +228,11 @@ static int hvmemul_do_io(
>>> {
>>> rc = X86EMUL_RETRY;
>>> if ( !hvm_send_assist_req(&p) )
>>> + {
>>> + /* Since the send failed, do not retry */
>>> + rc = X86EMUL_OKAY;
>>> vio->io_state = HVMIO_none;
>>> + }
>>> else if ( p_data == NULL )
>>> rc = X86EMUL_OKAY;
>>> }
>>> --
>>> 1.8.4
>>
>>
>>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |