|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v6 3/5] IOMMU: Make the pcidevs_lock a recursive one
On March 04, 2016 9:59pm, <dario.faggioli@xxxxxxxxxx> wrote:
> On Fri, 2016-03-04 at 11:54 +0000, Xu, Quan wrote:
> > On March 04, 2016 5:29pm, <JBeulich@xxxxxxxx> wrote:
> > > On March 04, 2016 7:59am, <dario.faggioli@xxxxxxxxxx> wrote:
> > >
> > > > Also I'd highlight the below modification:
> > > > - if ( !spin_trylock(&pcidevs_lock) )
> > > > - return -ERESTART;
> > > > -
> > > > + pcidevs_lock();
> > > >
> > > > IMO, it is right too.
> > > Well, I'll have to see where exactly this is (pulling such out of
> > > context is pretty unhelpful), but I suspect it can't be replaced
> > > like this.
> > >
> > Jan, I am looking forward to your review.
> > btw, It is in the assign_device(), in the
> > xen/drivers/passthrough/pci.c file.
> >
> Mmm... If multiple cpus calls assign_device(), and the calls race, the
> behavior
> between before and after the patch looks indeed different to me.
>
> In fact, in current code, the cpus that find the lock busy already, would
> quit the
> function immediately and a continuation is created. On the other hand, with
> the
> patch, they would spin and actually get the lock, one after the other (if
> there's
> more of them) at some point.
>
> Please, double check my reasoning, but I looks to me that it is indeed
> different
> what happens when the hypercall is restarted (i.e., in current code) and what
> happens if we just let others take the lock and execute the function (i.e.,
> with
> the patch applied).
>
> I suggest you try to figure out whether that is actually the case. Once you've
> done, feel free to report here and ask for help for finding a solution, if
> you don't
> see one.
>
Good idea.
For multiple cpus calls assign_device(), Iet's assume that there are 3 calls in
parallel:
(p1). xl pci-attach TestDom 0000:81:00.0
(p2). xl pci-attach TestDom 0000:81:00.0
(p3). xl pci-attach TestDom 0000:81:00.0
Furthermore, p1 and p2 run on pCPU1, and p3 runs on pCPU2.
After my patch,
__IIUC__ , the invoker flow might be as follow:
pCPU1 pCPU2
. .
. .
assign_device_1()
{ .
spin_lock_r(lock) .
. assign_device_3()
spin_lock_r(lock) <-- blocks
assign_device_2()
{ x <-- spins
spin_lock_r(lock) <-- can continue x <-- spins
spin_unlock_r(lock) <-- *doesn't* release lock x <-- spins
} x <-- spins
. x <-- spins
} x <-- spins
. x <-- spins
spin_unlock_r(lock) <-- release lock ----------->. .......
...............<--assign_device_3() continue, with lock held
. .
. .
. spin_unlock_r(lock)
<--lock is now free
Befer my patch,
The invoker flower might return at the point of assign_device_2() /
assign_device_3().
So, yes, If multiple cpus calls assign_device(), and the calls race, the
behavior between before and after the patch looks indeed different.
I try to fix it with follow:
--------patch >> --------
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -118,6 +118,11 @@ int pcidevs_is_locked(void)
return spin_is_locked(&_pcidevs_lock);
}
+int pcidevs_trylock(void)
+{
+ return spin_trylock_recursive(&_pcidevs_lock);
+}
+
void __init pt_pci_init(void)
{
radix_tree_init(&pci_segments);
@@ -1365,7 +1370,7 @@ static int assign_device(struct domain *d, u16 seg, u8
bus, u8 devfn, u32 flag)
p2m_get_hostp2m(d)->global_logdirty)) )
return -EXDEV;
- if ( !spin_trylock(&pcidevs_lock) )
+ if ( !pcidevs_trylock() )
return -ERESTART;
rc = iommu_construct(d);
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 017aa0b..b87571d 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -97,6 +97,7 @@ struct pci_dev {
void pcidevs_lock(void);
void pcidevs_unlock(void);
int pcidevs_is_locked(void);
+int pcidevs_trylock(void);
bool_t pci_known_segment(u16 seg);
bool_t pci_device_detect(u16 seg, u8 bus, u8 dev, u8 func);
--------patch << --------
A quick question, is it '-ERESTART', instead of '-EBUSY' ?
There is also a similar case, cpu_hotplug:
$cpu_up()--> cpu_hotplug_begin()-->get_cpu_maps()-->
spin_trylock_recursive(&cpu_add_remove_lock)
Feel free to share your idea, and correct me if I'm wrong.
Quan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |