From: Keir Fraser <keir.xen@gmail.com>
To: "Zhang, Yang Z" <yang.z.zhang@intel.com>,
"xen-devel@lists.xen.org" <xen-devel@lists.xen.org>
Cc: "Qiu, Shuang" <shuang.qiu@intel.com>,
"Zhang, Xiantao" <xiantao.zhang@intel.com>,
Jan Beulich <jbeulich@suse.com>
Subject: Re: use tasklet to handle init/sipi?
Date: Tue, 26 Mar 2013 07:55:55 +0000 [thread overview]
Message-ID: <CD77050D.1BBD3%keir.xen@gmail.com> (raw)
In-Reply-To: <A9667DDFB95DB7438FA9D7D576C3D87E099F21B1@SHSMSX101.ccr.corp.intel.com>
[-- Attachment #1: Type: text/plain, Size: 1419 bytes --]
On 26/03/2013 07:41, "Zhang, Yang Z" <yang.z.zhang@intel.com> wrote:
> Keir Fraser wrote on 2013-03-26:
>> On 26/03/2013 07:17, "Zhang, Yang Z" <yang.z.zhang@intel.com> wrote:
>>
>>>>> Oh, I see. Well I think it is fine to have
>>>>> vlapic_schedule_init_sipi_tasklet() return X86EMUL_OKAY rather than
>>>>> X86EMUL_RETRY. We used to need to return RETRY, but the code got
>>>>> simplified and now it is actually unnecessary.
>>>>>
>>>>> That should make your patch a lot simpler eh? ;)
>>>>
>>>> Given that you ignore the return code on the apicv call path, is there
>>>> currently a bug at all for you? Seems what is there already must work
>>>> for you?
>>> It do cause bug after we change to use seabios. For seabios, it will
>>> send INIT/SIPI to all vcpus via broadcasting. And there only one vcpu
>>> is waken up via tasklet with current logic. That's the reason why I
>>> want to wakeup all vcpus on one callback. Just change X86EMUL_RETRY to
>>> OK cannot solve the problem. still need the logic I mentioned above.
>>
>> Ok, wait a sec, I will sort out a patch for you to try...
> Thanks. Actually, I have patch on hand and testing it now. But it's ok if you
> can provide a more better solution.
See how you like it compared with the attached patch. Attached doesn't
really make the code any more complicated, which is nice. However it is not
tested, at all. ;)
-- Keir
> Best regards,
> Yang
>
>
[-- Attachment #2: 00-vlapic-init --]
[-- Type: application/octet-stream, Size: 6450 bytes --]
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index ea7adf6..38e87ce 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3461,8 +3461,6 @@ void hvm_vcpu_reset_state(struct vcpu *v, uint16_t cs, uint16_t ip)
struct domain *d = v->domain;
struct segment_register reg;
- BUG_ON(vcpu_runnable(v));
-
domain_lock(d);
if ( v->is_initialised )
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index 38ff216..bb897bb 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -243,18 +243,22 @@ bool_t vlapic_match_dest(
return 0;
}
-static void vlapic_init_sipi_action(unsigned long _vcpu)
+static void vlapic_init_sipi_one(struct vcpu *target, uint32_t icr)
{
- struct vcpu *origin = (struct vcpu *)_vcpu;
- struct vcpu *target = vcpu_vlapic(origin)->init_sipi.target;
- uint32_t icr = vcpu_vlapic(origin)->init_sipi.icr;
-
vcpu_pause(target);
switch ( icr & APIC_MODE_MASK )
{
case APIC_DM_INIT: {
bool_t fpu_initialised;
+ /* No work on INIT de-assert for P4-type APIC. */
+ if ( (icr & (APIC_INT_LEVELTRIG | APIC_INT_ASSERT)) ==
+ APIC_INT_LEVELTRIG )
+ break;
+ /* Nothing to do if the VCPU is already reset. */
+ if ( !target->is_initialised )
+ break;
+ hvm_vcpu_down(target);
domain_lock(target->domain);
/* Reset necessary VCPU state. This does not include FPU state. */
fpu_initialised = target->fpu_initialised;
@@ -276,28 +280,29 @@ static void vlapic_init_sipi_action(unsigned long _vcpu)
}
vcpu_unpause(target);
-
- vcpu_vlapic(origin)->init_sipi.target = NULL;
- vcpu_unpause(origin);
}
-static int vlapic_schedule_init_sipi_tasklet(struct vcpu *target, uint32_t icr)
+static void vlapic_init_sipi_action(unsigned long _vcpu)
{
- struct vcpu *origin = current;
+ struct vcpu *origin = (struct vcpu *)_vcpu;
+ uint32_t icr = vcpu_vlapic(origin)->init_sipi.icr;
+ uint32_t dest = vcpu_vlapic(origin)->init_sipi.dest;
+ uint32_t short_hand = icr & APIC_SHORT_MASK;
+ uint32_t dest_mode = !!(icr & APIC_DEST_MASK);
+ struct vcpu *v;
- if ( vcpu_vlapic(origin)->init_sipi.target != NULL )
+ if ( icr == 0 )
+ return;
+
+ for_each_vcpu ( origin->domain, v )
{
- WARN(); /* should be impossible but don't BUG, just in case */
- return X86EMUL_UNHANDLEABLE;
+ if ( vlapic_match_dest(vcpu_vlapic(v), vcpu_vlapic(origin),
+ short_hand, dest, dest_mode) )
+ vlapic_init_sipi_one(v, icr);
}
- vcpu_pause_nosync(origin);
-
- vcpu_vlapic(origin)->init_sipi.target = target;
- vcpu_vlapic(origin)->init_sipi.icr = icr;
- tasklet_schedule(&vcpu_vlapic(origin)->init_sipi.tasklet);
-
- return X86EMUL_RETRY;
+ vcpu_vlapic(origin)->init_sipi.icr = 0;
+ vcpu_unpause(origin);
}
/* Add a pending IRQ into lapic. */
@@ -339,23 +344,9 @@ static int vlapic_accept_irq(struct vcpu *v, uint32_t icr_low)
break;
case APIC_DM_INIT:
- /* No work on INIT de-assert for P4-type APIC. */
- if ( (icr_low & (APIC_INT_LEVELTRIG | APIC_INT_ASSERT)) ==
- APIC_INT_LEVELTRIG )
- break;
- /* Nothing to do if the VCPU is already reset. */
- if ( !v->is_initialised )
- break;
- hvm_vcpu_down(v);
- rc = vlapic_schedule_init_sipi_tasklet(v, icr_low);
- break;
-
case APIC_DM_STARTUP:
- /* Nothing to do if the VCPU is already initialised. */
- if ( v->is_initialised )
- break;
- rc = vlapic_schedule_init_sipi_tasklet(v, icr_low);
- break;
+ /* Handled in vlapic_ipi(). */
+ BUG();
default:
gdprintk(XENLOG_ERR, "TODO: unsupported delivery mode in ICR %x\n",
@@ -427,8 +418,6 @@ int vlapic_ipi(
unsigned int dest;
unsigned int short_hand = icr_low & APIC_SHORT_MASK;
unsigned int dest_mode = !!(icr_low & APIC_DEST_MASK);
- struct vlapic *target;
- struct vcpu *v;
int rc = X86EMUL_OKAY;
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "icr = 0x%08x:%08x", icr_high, icr_low);
@@ -437,22 +426,41 @@ int vlapic_ipi(
? icr_high
: GET_xAPIC_DEST_FIELD(icr_high));
- if ( (icr_low & APIC_MODE_MASK) == APIC_DM_LOWEST )
+ switch ( icr_low & APIC_MODE_MASK )
{
- target = vlapic_lowest_prio(vlapic_domain(vlapic), vlapic,
- short_hand, dest, dest_mode);
+ case APIC_DM_INIT:
+ case APIC_DM_STARTUP:
+ if ( vlapic->init_sipi.icr != 0 )
+ {
+ WARN(); /* should be impossible but don't BUG, just in case */
+ break;
+ }
+ vcpu_pause_nosync(vlapic_vcpu(vlapic));
+ vlapic->init_sipi.icr = icr_low;
+ vlapic->init_sipi.dest = dest;
+ tasklet_schedule(&vlapic->init_sipi.tasklet);
+ break;
+
+ case APIC_DM_LOWEST: {
+ struct vlapic *target = vlapic_lowest_prio(
+ vlapic_domain(vlapic), vlapic, short_hand, dest, dest_mode);
if ( target != NULL )
rc = vlapic_accept_irq(vlapic_vcpu(target), icr_low);
- return rc;
+ break;
}
- for_each_vcpu ( vlapic_domain(vlapic), v )
- {
- if ( vlapic_match_dest(vcpu_vlapic(v), vlapic,
- short_hand, dest, dest_mode) )
+ default: {
+ struct vcpu *v;
+ for_each_vcpu ( vlapic_domain(vlapic), v )
+ {
+ if ( vlapic_match_dest(vcpu_vlapic(v), vlapic,
+ short_hand, dest, dest_mode) )
rc = vlapic_accept_irq(v, icr_low);
- if ( rc != X86EMUL_OKAY )
- break;
+ if ( rc != X86EMUL_OKAY )
+ break;
+ }
+ break;
+ }
}
return rc;
diff --git a/xen/include/asm-x86/hvm/vlapic.h b/xen/include/asm-x86/hvm/vlapic.h
index 09cb63c..8537a35 100644
--- a/xen/include/asm-x86/hvm/vlapic.h
+++ b/xen/include/asm-x86/hvm/vlapic.h
@@ -62,8 +62,7 @@ struct vlapic {
struct page_info *regs_page;
/* INIT-SIPI-SIPI work gets deferred to a tasklet. */
struct {
- struct vcpu *target;
- uint32_t icr;
+ uint32_t icr, dest;
struct tasklet tasklet;
} init_sipi;
};
[-- Attachment #3: Type: text/plain, Size: 126 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel
next prev parent reply other threads:[~2013-03-26 7:55 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-25 5:31 use tasklet to handle init/sipi? Zhang, Yang Z
2013-03-25 6:29 ` Keir Fraser
2013-03-25 6:55 ` Zhang, Yang Z
2013-03-25 8:05 ` Keir Fraser
2013-03-25 12:16 ` Zhang, Yang Z
2013-03-25 12:38 ` Jan Beulich
2013-03-25 12:39 ` Keir Fraser
2013-03-26 3:15 ` Zhang, Yang Z
2013-03-26 6:07 ` Keir Fraser
2013-03-26 6:14 ` Zhang, Yang Z
2013-03-26 7:00 ` Keir Fraser
2013-03-26 7:11 ` Keir Fraser
2013-03-26 7:17 ` Zhang, Yang Z
2013-03-26 7:38 ` Keir Fraser
2013-03-26 7:41 ` Zhang, Yang Z
2013-03-26 7:55 ` Keir Fraser [this message]
2013-03-26 8:02 ` Keir Fraser
2013-03-28 1:18 ` Zhang, Yang Z
2013-03-28 6:39 ` Qiu, Shuang
2013-03-28 11:48 ` Keir Fraser
2013-03-28 15:29 ` Jan Beulich
2013-03-28 20:02 ` Keir Fraser
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=CD77050D.1BBD3%keir.xen@gmail.com \
--to=keir.xen@gmail.com \
--cc=jbeulich@suse.com \
--cc=shuang.qiu@intel.com \
--cc=xen-devel@lists.xen.org \
--cc=xiantao.zhang@intel.com \
--cc=yang.z.zhang@intel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).