[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC PATCH 01/10] xen: pci: add per-domain pci list lock


  • To: Stefano Stabellini <sstabellini@xxxxxxxxxx>
  • From: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Date: Tue, 14 Feb 2023 23:38:41 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=SGv4HB7UbsPLmaPOZhI9GR/eHKTekYVXWtSt/9CNtTA=; b=obcTDvsfuPYj13W3WTZSFUxX3w3kXJxANXTriE4tOS2VNzoLR5YyM8UP2cAaHvQIrg62zDdVMX8F0E1T4/IAc3fYAXGv/omjnYJ2970AkuYIOMf6+3iVC2gTJfoXxDUCr0ubwOjTBe+KqkCKo3guKPZMoSmThzG3ACsp6BFQA1rJ3wesrKU0cRdoGzH7x3QJ5Q2UIuHbTIDB9eRYcGLZGc3ycfxYs6HKXD6skdd4fosHqiiZfdwMq3suGp0P65lCPPBGqQ6oMp4f4Nk+IyyUijNan6Itk3oPaCkqA9ey0ObYUhwGUxzjurSBkOiwwDwLdIf/Ae4wX9xhOBqPajEmCA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FtBQ0aZuK49I4t4i5AX9AtoBppeZ9LgOXW21Txzfn0fjJCnHj3mLtDKQ7sHe/K2AXUK8kadfsfbUrdHVLUoVNNKoRwcsV5TJ1w7Xt9Enm8GIv140fBgB+H4JYNSf8dD76RKPOxysttkrBJSzp2Y8Z4xFZ7WcbzeXZ4jXUcIx32eAWzpPC/7Chp/BftyR2hJXp5MTxdDJyQzvHXFRO3WD3rPm9IoU2+WelsAfpr2shF4+oWRNa8coVQHtBM8/dhfuLH+a4G3LeCPdn5EyTpEAic9g9a+kdnnGMNIvvHnf0X9KamR3knPcpLHagLGVFjnpQWwLY1wZWw+9OOFOeg8vYQ==
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Oleksandr Andrushchenko <Oleksandr_Andrushchenko@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Wei Liu <wl@xxxxxxx>, Paul Durrant <paul@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Kevin Tian <kevin.tian@xxxxxxxxx>, "Stewart.Hildebrand@xxxxxxx" <Stewart.Hildebrand@xxxxxxx>
  • Delivery-date: Tue, 14 Feb 2023 23:39:31 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHYvUN+sHWq0w//vE+eH46Zd/aTJ66yPm0AgB3Z5oA=
  • Thread-topic: [RFC PATCH 01/10] xen: pci: add per-domain pci list lock

Hello Stefano,

Stefano Stabellini <sstabellini@xxxxxxxxxx> writes:

> On Wed, 31 Aug 2022, Volodymyr Babchuk wrote:
>> domain->pdevs_lock protects access to domain->pdev_list.
>> As this, it should be used when we are adding, removing on enumerating
>> PCI devices assigned to a domain.
>> 
>> This enables more granular locking instead of one huge pcidevs_lock that
>> locks entire PCI subsystem. Please note that pcidevs_lock() is still
>> used, we are going to remove it in subsequent patches.
>> 
>> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx>
>
> I reviewed the patch, and made sure to pay extra attention to:

Thank you for doing this.

> - error paths
> - missing locks
> - lock ordering
> - interruptions

> Here is what I found:
>
>
> 1) iommu.c:reassign_device_ownership and pci_amd_iommu.c:reassign_device
> Both functions without any pdevs_lock locking do:
> list_move(&pdev->domain_list, &target->pdev_list);
>
> It seems to be it would need pdevs_lock. Maybe we need to change
> list_move into list_del (protected by the pdevs_lock of the old domain)
> and list_add (protected by the pdev_lock of the new domain).

Yes, I did as you suggested. But this leads to another potential
issue. I'll describe it below, in deassign_device() part.

[...]

>> +    spin_lock(&d->pdevs_lock);
>>      list_for_each_entry_safe ( pdev, tmp, &d->pdev_list, domain_list )
>>      {
>>          bus = pdev->bus;
>>          devfn = pdev->devfn;
>>          ret = deassign_device(d, pdev->seg, bus, devfn) ?: ret;
>
> This causes pdevs_lock to be taken twice. deassign_device also takes a
> pdevs_lock.  Probably we need to change all the
> spin_lock(&d->pdevs_lock) into spin_lock_recursive.

You are right, I missed that deassign_device() causes
iommu*_reassign_device() call. But there lies the issue: with recursive
locks, reassign_device() will not be able to unlock source->pdevs_lock,
but will try to take target->pdevs_lock also. This potentially might
lead to deadlock, if another call to reassign_device() moves some other
pdev in the opposite way at the same time. This is why I want to avoid
recursive spinlocks if possible.

So, I am thinking: why does IOMMU code move a pdev across domains in the
first place? We are making IOMMU driver responsible of managing domain's
pdevs, which does not look right, as this is the responsibility of pci.c

I want to propose another approach: implement deassign_device() function
in IOMMU drivers. Then, instead of calling to reassign_device() we might
do the following:

1. deassign_device()
2. remove pdev from source->pdev_list
3. add pdef to target->pdev_list
4. assign_device()


[...]

>> diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
>> index 1cf629e7ec..0775228ba9 100644
>> --- a/xen/include/xen/sched.h
>> +++ b/xen/include/xen/sched.h
>> @@ -457,6 +457,7 @@ struct domain
>>  
>>  #ifdef CONFIG_HAS_PCI
>>      struct list_head pdev_list;
>> +    spinlock_t pdevs_lock;
>
> I think it would be better called "pdev_lock" but OK either way

As Jan pointed out, we are locking devices as in plural. On other hand, I can 
rename
pdev_list to pdevs_lists to make this consistent.

>
>
>>  #endif
>>  
>>  #ifdef CONFIG_HAS_PASSTHROUGH
>> -- 
>> 2.36.1
>> 



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.