|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v8 for-xen-4.5 2/2] dpci: Replace tasklet with an softirq (v8)
On Tue, Oct 28, 2014 at 10:43:32AM +0000, Jan Beulich wrote:
> >>> On 27.10.14 at 22:13, <konrad.wilk@xxxxxxxxxx> wrote:
> > + /*
> > + * A crude 'while' loop with us dropping the spinlock and giving
> > + * the softirq_dpci a chance to run.
> > + * We MUST check for this condition as the softirq could be scheduled
> > + * and hasn't run yet. Note that this code replaced tasklet_kill which
> > + * would have spun forever and would do the same thing (wait to flush
> > out
> > + * outstanding hvm_dirq_assist calls.
> > + */
> > + if ( pt_pirq_softirq_active(pirq_dpci) )
> > + {
> > + spin_unlock(&d->event_lock);
> > + if ( pirq_dpci->cpu >= 0 && pirq_dpci->cpu != smp_processor_id() )
> > + {
> > + /*
> > + * The 'raise_softirq_for' sets the CPU and raises the softirq
> > bit
> > + * so we do not need to set the target CPU's HVM_DPCI_SOFTIRQ.
> > + */
> > + smp_send_event_check_cpu(pirq_dpci->cpu);
> > + pirq_dpci->cpu = -1;
> > + }
> > + cpu_relax();
> > + goto restart;
> > + }
>
> As said in an earlier reply to Andrew, I think this open coding goes
> too far. And with the softirq known to have got sent, I also don't
> really see why it needs to be resent _at all_ (and the comments
> don't explain this either).
In the other emails you and Andrew said:
">> > Can it ever be the case that we are waiting for a remote pcpu to
run its
>> > softirq handler? If so, the time spent looping here could be up
to 1
>> > scheduling timeslice in the worst case, and 30ms is a very long
time to
>> > wait.
>>
>> Good point - I think this can be the case. But there seems to be a
>> simple counter measure: The first time we get to this point, send an
>> event check IPI to the CPU in question (or in the worst case
>> broadcast one if the CPU can't be determined in a race free way).
>
"
Which is true. That is what this is trying to address.
But if we use 'cpu_raise_softirq' which you advocate it would inhibit the IPI
if the HVM_DPCI_SOFTIRQ is set on the remote CPU:
void cpu_raise_softirq(unsigned int cpu, unsigned int nr)
{
unsigned int this_cpu = smp_processor_id();
if ( test_and_set_bit(nr, &softirq_pending(cpu)) <=== that will
be true
|| (cpu == this_cpu)
|| arch_skip_send_event_check(cpu) )
return;
if ( !per_cpu(batching, this_cpu) || in_irq() )
smp_send_event_check_cpu(cpu);
else
set_bit(nr, &per_cpu(batch_mask, this_cpu));
}
In which case we still won't be sending the IPI. The open-usage of
'smp_send_event_check_cpu' would bypass that check (which would in this
scenario cause to inhibit the IPI).
Perhaps you are suggesting something like this (on top of this patch) - also
attached is the new patch with this change folded in.
diff --git a/xen/common/softirq.c b/xen/common/softirq.c
index 22e417a..2b90316 100644
--- a/xen/common/softirq.c
+++ b/xen/common/softirq.c
@@ -94,6 +94,14 @@ void cpumask_raise_softirq(const cpumask_t *mask, unsigned
int nr)
smp_send_event_check_mask(raise_mask);
}
+void cpu_raise_softirq_ipi(unsigned int this_cpu, unsigned int cpu,
+ unsigned int nr)
+{
+ if ( !per_cpu(batching, this_cpu) || in_irq() )
+ smp_send_event_check_cpu(cpu);
+ else
+ set_bit(nr, &per_cpu(batch_mask, this_cpu));
+}
void cpu_raise_softirq(unsigned int cpu, unsigned int nr)
{
unsigned int this_cpu = smp_processor_id();
@@ -103,10 +111,7 @@ void cpu_raise_softirq(unsigned int cpu, unsigned int nr)
|| arch_skip_send_event_check(cpu) )
return;
- if ( !per_cpu(batching, this_cpu) || in_irq() )
- smp_send_event_check_cpu(cpu);
- else
- set_bit(nr, &per_cpu(batch_mask, this_cpu));
+ cpu_raise_softirq_ipi(this_cpu, cpu, nr);
}
void cpu_raise_softirq_batch_begin(void)
diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c
index 66869e9..ddbb890 100644
--- a/xen/drivers/passthrough/io.c
+++ b/xen/drivers/passthrough/io.c
@@ -249,14 +249,18 @@ int pt_irq_create_bind(
*/
if ( pt_pirq_softirq_active(pirq_dpci) )
{
+ unsigned int cpu;
+
spin_unlock(&d->event_lock);
- if ( pirq_dpci->cpu >= 0 && pirq_dpci->cpu != smp_processor_id() )
+
+ cpu = smp_processor_id();
+ if ( pirq_dpci->cpu >= 0 && pirq_dpci->cpu != cpu )
{
/*
- * The 'raise_softirq_for' sets the CPU and raises the softirq bit
- * so we do not need to set the target CPU's HVM_DPCI_SOFTIRQ.
+ * We do NOT want to wait for the remote CPU to run its course
which
+ * could be a full guest time-slice. As such, send one IPI there.
*/
- smp_send_event_check_cpu(pirq_dpci->cpu);
+ cpu_raise_softirq_ipi(cpu, pirq_dpci->cpu, HVM_DPCI_SOFTIRQ);
pirq_dpci->cpu = -1;
}
cpu_relax();
diff --git a/xen/include/xen/softirq.h b/xen/include/xen/softirq.h
index 0895a16..16f7063 100644
--- a/xen/include/xen/softirq.h
+++ b/xen/include/xen/softirq.h
@@ -27,6 +27,8 @@ void open_softirq(int nr, softirq_handler handler);
void softirq_init(void);
void cpumask_raise_softirq(const cpumask_t *, unsigned int nr);
+void cpu_raise_softirq_ipi(unsigned int this_cpu, unsigned int cpu,
+ unsigned int nr);
void cpu_raise_softirq(unsigned int cpu, unsigned int nr);
void raise_softirq(unsigned int nr);
Attachment:
0001-dpci-Replace-tasklet-with-an-softirq-v11.patch _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |