|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v6 for-xen-4.5 1/3] dpci: Move from domain centric model to hvm_dirq_dpci model.
>>> On 07.10.14 at 17:40, <konrad.wilk@xxxxxxxxxx> wrote:
> @@ -65,10 +69,13 @@ static void schedule_softirq_for(struct hvm_pirq_dpci
> *pirq_dpci)
> */
> int pt_pirq_softirq_active(struct hvm_pirq_dpci *pirq_dpci)
> {
> - if ( pirq_dpci->masked )
> - return -EAGAIN;
> + if ( test_bit(STATE_RUN, &pirq_dpci->masked) )
> + return -ERESTART;
> +
> + if ( test_bit(STATE_SCHED, &pirq_dpci->masked) )
> + return -ERESTART;
Just check both in one go?
> @@ -230,7 +234,35 @@ int pt_irq_create_bind(
> {
> pirq_dpci->gmsi.gflags = 0;
> pirq_dpci->gmsi.gvec = 0;
> - pirq_dpci->dom = NULL;
> +
> + /* The softirq has saved it so we are safe to reset it. */
> + if ( test_bit(STATE_RUN, &pirq_dpci->masked) )
> + {
> + pirq_dpci->dom = NULL;
> + }
> + else if ( test_and_clear_bit(STATE_SCHED,
> &pirq_dpci->masked) )
> + {
> + /* pirq_guest_unbind has made sure we won't be getting
> + * any more interrupts (no raise_softirq_for), so the
> only
> + * ones that can be are the ones that got scheduled
> _right_
> + * before the pirq_guest_unbind. If we can de-schedule
> them
> + * that is good. The problem #1 is that the softirq
> might be
> + * running and it has just set STATE_RUN while we cleared
> + * STATE_SCHED. That is OK, as right after the STATE_RUN
> it
> + * will check the STATE_SCHED and if cleared it will
> unclear
> + * STATE_RUN and ignore this pirq. We MUST put the
> refcount
> + * down. */
> + put_domain(pirq_dpci->dom);
> + pirq_dpci->dom = NULL;
> + }
> + else
> + {
> + /* !STATE_RUN (stale) and !STATE_SCHED.
> + * softirq will ignore this pirq, but we MUST put the
> refcount
> + * down. */
> + put_domain(pirq_dpci->dom);
> + pirq_dpci->dom = NULL;
> + }
First of all you don't seem to convert the setting of ->dom back to
what it was before (you said this is an incremental patch).
And then the else path is suspicious: Only when STATE_SCHED
is set there is a ref to be put. I.e. it always has to be the site
clearing that flag which also drops the ref. This is supported by
both else-if and else doing exactly the same (which can't really
be right).
> @@ -332,7 +364,7 @@ int pt_irq_create_bind(
> {
> if ( pt_irq_need_timer(pirq_dpci->flags) )
> kill_timer(&pirq_dpci->timer);
> - pirq_dpci->dom = NULL;
> + /* TODO - function. pirq_dpci->dom = NULL; */
I wonder whether _here_ you really need this: Is it possible
for the softirq to get invoked when pirq_guest_bind() fails? If not,
only the other error path above would seem to need extra care.
> @@ -725,11 +754,24 @@ static void dpci_softirq(void)
>
> while ( !list_empty(&our_list) )
> {
> + struct domain *d;
> +
> pirq_dpci = list_entry(our_list.next, struct hvm_pirq_dpci,
> softirq_list);
> list_del(&pirq_dpci->softirq_list);
>
> - hvm_dirq_assist(pirq_dpci);
> - pirq_dpci->masked = 0;
> + d = pirq_dpci->dom;
> + barrier(); /* 'd' MUST be saved before we set/clear the bits. */
smp_mb() I think.
> + if ( test_and_set_bit(STATE_RUN, &pirq_dpci->masked) )
> + BUG();
> + /* Asked to be descheduled. */
> + if ( !test_and_clear_bit(STATE_SCHED, &pirq_dpci->masked) )
Invert the condition and ...
> + {
> + clear_bit(STATE_RUN, &pirq_dpci->masked);
> + continue;
> + }
> + hvm_dirq_assist(d, pirq_dpci);
> + put_domain(d);
> + clear_bit(STATE_RUN, &pirq_dpci->masked);
... do the clear_bit() just once?
> --- a/xen/include/xen/hvm/irq.h
> +++ b/xen/include/xen/hvm/irq.h
> @@ -93,7 +93,7 @@ struct hvm_irq_dpci {
> /* Machine IRQ to guest device/intx mapping. */
> struct hvm_pirq_dpci {
> uint32_t flags;
> - bool_t masked;
> + unsigned long masked;
Perhaps better "state" or some such?
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |