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

Re: [PATCH v9 01/16] pci: introduce per-domain PCI rwlock


  • To: Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • From: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
  • Date: Mon, 25 Sep 2023 22:44:32 +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=AxHux67opKt9joI8KxHRG9cAZ5QtG+PKsF6yLYmOPZo=; b=blRCtq7eOZaSjhoaXX7m3hjVSbO+UD0dBB0YnY8UiLID0+/NGbDmAnKaix/E8AAP4nu3pbIijZ2K/KB27+7nlqU9F4zugilWZCu7PDB+m5h/v2u/ouM7Bdv1H7UDHCqDUxBgKoEXZvobI1aMS1bCEHUpF2IOib39zxVdIvcGZOluhl8LX1uy25+rufcojsCYBzglWNOm+ZcKLE8KtFWPnf74C1NslvVzYUKd2sbXaRero7StETDa6c1XQT5cwt973wXzHOyupKXMyE31Fus/FvBqFgM1M+P8OgrGofG2qxCFGMMFGomuucBsudizG4Ev6rqIz6EsoB/5We7fkVFAzQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=E7DLkEDmUCHuBu89IOuDPNwhevWe7NdkazX1murk+OMBCpjOkvHtKbqC9o6eyjr1TXM1EJXcqlSh+cyEBbn3jdi4z0JXO+ar2iKIIezX2FZ3fOnZIKaDBJYkhhTzX35lrDtbpfElnSkVfMkrypKh6I8FuIPQoPDVR+AtRTxGTyP5xzVcHlBU7QpBIsvjM04i/Vcv95Dlv1TwWwd7J7qVH0Cc8UofjiVnpWlYf8g6CczXPOiwsNuc00MQ9PO1abTUrZr/fTqKIVSgchod7gq6G8hZL2lECzrgyS0LU6CbtAMo6kR4iu+yvbsCR3eCESDnAwyDRTr4VYAAymg/QyUYbg==
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Stewart Hildebrand <stewart.hildebrand@xxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Paul Durrant <paul@xxxxxxx>, Kevin Tian <kevin.tian@xxxxxxxxx>
  • Delivery-date: Mon, 25 Sep 2023 22:45:00 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHZ2s9KWF3JKCAv4U2Fm0C+oJYn+LAiUDyAgAn8FQA=
  • Thread-topic: [PATCH v9 01/16] pci: introduce per-domain PCI rwlock

Hello Roger,

Roger Pau Monné <roger.pau@xxxxxxxxxx> writes:

> On Tue, Aug 29, 2023 at 11:19:42PM +0000, Volodymyr Babchuk wrote:
>> Add per-domain d->pci_lock that protects access to
>> d->pdev_list. Purpose of this lock is to give guarantees to VPCI code
>> that underlying pdev will not disappear under feet. This is a rw-lock,
>> but this patch adds only write_lock()s. There will be read_lock()
>> users in the next patches.
>> 
>> This lock should be taken in write mode every time d->pdev_list is
>> altered. This covers both accesses to d->pdev_list and accesses to
>> pdev->domain_list fields.
>
> Why do you mention pdev->domain_list here?  I don't think the lock
> covers accesses to pdev->domain_list, unless that domain_list field
> happens to be part of the linked list in d->pdev_list.  I find it kind
> of odd to mention here.

You are correct. I was referring very specific case in reassign_device()
IOMMU functions. It seemed important for me when I wrote this. But you
are correct, no need to mention pdev->domain_list explicitly.

>
>> All write accesses also should be protected
>> by pcidevs_lock() as well. Idea is that any user that wants read
>> access to the list or to the devices stored in the list should use
>> either this new d->pci_lock or old pcidevs_lock(). Usage of any of
>> this two locks will ensure only that pdev of interest will not
>> disappear from under feet and that the pdev still will be assigned to
>> the same domain. Of course, any new users should use pcidevs_lock()
>> when it is appropriate (e.g. when accessing any other state that is
>> protected by the said lock). In case both the newly introduced
>> per-domain rwlock and the pcidevs lock is taken, the later must be
>> acquired first.
>> 
>> Any write access to pdev->domain_list should be protected by both
>> pcidevs_lock() and d->pci_lock in the write mode.
>> 
>> Suggested-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
>> Suggested-by: Jan Beulich <jbeulich@xxxxxxxx>
>> Signed-off-by: Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx>
>> 
>> ---
>> 
>> Changes in v9:
>>  - returned back "pdev->domain = target;" in AMD IOMMU code
>>  - used "source" instead of pdev->domain in IOMMU functions
>>  - added comment about lock ordering in the commit message
>>  - reduced locked regions
>>  - minor changes non-functional changes in various places
>> 
>> Changes in v8:
>>  - New patch
>> 
>> Changes in v8 vs RFC:
>>  - Removed all read_locks after discussion with Roger in #xendevel
>>  - pci_release_devices() now returns the first error code
>>  - extended commit message
>>  - added missing lock in pci_remove_device()
>>  - extended locked region in pci_add_device() to protect list_del() calls
>> ---
>>  xen/common/domain.c                         |  1 +
>>  xen/drivers/passthrough/amd/pci_amd_iommu.c |  9 ++-
>>  xen/drivers/passthrough/pci.c               | 71 +++++++++++++++++----
>>  xen/drivers/passthrough/vtd/iommu.c         |  9 ++-
>>  xen/include/xen/sched.h                     |  1 +
>>  5 files changed, 78 insertions(+), 13 deletions(-)
>> 
>> diff --git a/xen/common/domain.c b/xen/common/domain.c
>> index 304aa04fa6..9b04a20160 100644
>> --- a/xen/common/domain.c
>> +++ b/xen/common/domain.c
>> @@ -651,6 +651,7 @@ struct domain *domain_create(domid_t domid,
>>  
>>  #ifdef CONFIG_HAS_PCI
>>      INIT_LIST_HEAD(&d->pdev_list);
>> +    rwlock_init(&d->pci_lock);
>>  #endif
>>  
>>      /* All error paths can depend on the above setup. */
>> diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c 
>> b/xen/drivers/passthrough/amd/pci_amd_iommu.c
>> index bea70db4b7..d219bd9453 100644
>> --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
>> +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
>> @@ -476,7 +476,14 @@ static int cf_check reassign_device(
>>  
>>      if ( devfn == pdev->devfn && pdev->domain != target )
>>      {
>> -        list_move(&pdev->domain_list, &target->pdev_list);
>> +        write_lock(&source->pci_lock);
>> +        list_del(&pdev->domain_list);
>> +        write_unlock(&source->pci_lock);
>> +
>> +        write_lock(&target->pci_lock);
>> +        list_add(&pdev->domain_list, &target->pdev_list);
>> +        write_unlock(&target->pci_lock);
>> +
>>          pdev->domain = target;
>
> While I don't think this is strictly an issue right now, it would be
> better to set pdev->domain before the device is added to domain_list.
> A pattern like:
>
> read_lock(d->pci_lock);
> for_each_pdev(d, pdev)
>     foo(pdev->domain);
> read_unlock(d->pci_lock);
>
> Wouldn't work currently if the pdev is added to domain_list before the
> pdev->domain field is updated to reflect the new owner.

Agree. I moved `pdev->domain = target` so it sits between list_del() and
list_add() calls


-- 
WBR, Volodymyr

 


Rackspace

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