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

Re: [PATCH v6 03/13] vpci: move lock outside of struct vpci


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Oleksandr Andrushchenko <Oleksandr_Andrushchenko@xxxxxxxx>
  • Date: Tue, 8 Feb 2022 09:00:21 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; 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=GOvedpwc4BrgJPXSjAHoARgCDT0cQXFsosolrHyQ5hE=; b=mm1/Cfbj1o+p6fCBsJE98lRDaKWYdh/zqLPY1yFUbqQvLlrtuHpOuN8joBSx1Izez7B2nx7SZT8bcbxT1O310ejWjvPAYHSlJN1cqzGN16JiiVl27hTUpmESo+jR4HjFfjXyhukL6j/YD1nbHYsBGxwhG1KiTfJyzzZx1aAG8NDAbBK/8nNuUqqjHfVGg4rcS+3CfVmgbhwgbp3VwBufUyANNbDcEHNUKveUsWZ7xcIURoKFD8/QOvlcGUh7H/4mXvLOKFhE4RyA4NlOe4ao+23hcWDQGRm0QSavkwrKboptvgL+oZEOqDNRRDmEEViDvdUHRclUepNFWVSQifHt2w==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=HW4resnCC0tyGVVaV+gquvyZwFQna+5jranohtXzOkdBepPnjd4BpV1ETBH82JofIKVZ+UZOxjwj5ukWPXsakwesEASCsPMyXF9QemfGoSOAKtspNiZxCPpHMjvbEJ0/VCuceiLpdLXCZiDS+HqVSjZ9mRnqr3ThPgYj4uiKtZ9OklGSgFiKH4dbDY47vxfXXGT9v3Icq61+g53l8BPf9eqwBlUPn2fwiVCf96o06LM36Li69Ivbelf+a7o8xVX77E0u/kKV/6gYxoPbhwU+8HT8KIfGw5Mcy8hBNHCmjVIBgtejhyri8GNdHf0egpYqiSCRCQp1EmKWUuTvGvMtXg==
  • Cc: "julien@xxxxxxx" <julien@xxxxxxx>, "sstabellini@xxxxxxxxxx" <sstabellini@xxxxxxxxxx>, Oleksandr Tyshchenko <Oleksandr_Tyshchenko@xxxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Artem Mygaiev <Artem_Mygaiev@xxxxxxxx>, "andrew.cooper3@xxxxxxxxxx" <andrew.cooper3@xxxxxxxxxx>, "george.dunlap@xxxxxxxxxx" <george.dunlap@xxxxxxxxxx>, "paul@xxxxxxx" <paul@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Rahul Singh <rahul.singh@xxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, Oleksandr Andrushchenko <Oleksandr_Andrushchenko@xxxxxxxx>
  • Delivery-date: Tue, 08 Feb 2022 09:00:35 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHYGZFc/MnzQOjwVEeBBUHLSW0md6yDBUkAgAASSACAAATYAIAAD/WAgAAKNgCAAAbfgIAABnuAgAAQvgCAAAMCAIAAAY4AgAADxICAABrnAIAABAgAgAR3CoCAABt5gIAAEpuAgAAE5ICAAASKAIAAAiiAgAAKNYCAAARNAIAAC1wAgAACRYCAAAGVgIAABJiAgAAB5wCAAQ7DgIAAAdkA
  • Thread-topic: [PATCH v6 03/13] vpci: move lock outside of struct vpci


On 08.02.22 10:53, Jan Beulich wrote:
> On 07.02.2022 17:44, Oleksandr Andrushchenko wrote:
>>
>> On 07.02.22 18:37, Jan Beulich wrote:
>>> On 07.02.2022 17:21, Oleksandr Andrushchenko wrote:
>>>> On 07.02.22 18:15, Jan Beulich wrote:
>>>>> On 07.02.2022 17:07, Oleksandr Andrushchenko wrote:
>>>>>> On 07.02.22 17:26, Jan Beulich wrote:
>>>>>>> 1b. Make vpci_write use write lock for writes to command register and 
>>>>>>> BARs
>>>>>>> only; keep using the read lock for all other writes.
>>>>>> I am not quite sure how to do that. Do you mean something like:
>>>>>> void vpci_write(pci_sbdf_t sbdf, unsigned int reg, unsigned int size,
>>>>>>                     uint32_t data)
>>>>>> [snip]
>>>>>>         list_for_each_entry ( r, &pdev->vpci->handlers, node )
>>>>>> {
>>>>>> [snip]
>>>>>>         if ( r->needs_write_lock)
>>>>>>             write_lock(d->vpci_lock)
>>>>>>         else
>>>>>>             read_lock(d->vpci_lock)
>>>>>> ....
>>>>>>
>>>>>> And provide rw as an argument to:
>>>>>>
>>>>>> int vpci_add_register(struct vpci *vpci, vpci_read_t *read_handler,
>>>>>>                           vpci_write_t *write_handler, unsigned int 
>>>>>> offset,
>>>>>>                           unsigned int size, void *data, --->>> bool 
>>>>>> write_path <<<-----)
>>>>>>
>>>>>> Is this what you mean?
>>>>> This sounds overly complicated. You can derive locally in vpci_write(),
>>>>> from just its "reg" and "size" parameters, whether the lock needs taking
>>>>> in write mode.
>>>> Yes, I started writing a reply with that. So, the summary (ROM
>>>> position depends on header type):
>>>> if ( (reg == PCI_COMMAND) || (reg == ROM) )
>>>> {
>>>>        read PCI_COMMAND and see if memory or IO decoding are enabled.
>>>>        if ( enabled )
>>>>            write_lock(d->vpci_lock)
>>>>        else
>>>>            read_lock(d->vpci_lock)
>>>> }
>>> Hmm, yes, you can actually get away without using "size", since both
>>> command register and ROM BAR are 32-bit aligned registers, and 64-bit
>>> accesses get split in vpci_ecam_write().
>> But, OS may want reading a single byte of ROM BAR, so I think
>> I'll need to check if reg+size fall into PCI_COMAND and ROM BAR
>> ranges
>>> For the command register the memory- / IO-decoding-enabled check may
>>> end up a little more complicated, as the value to be written also
>>> matters. Maybe read the command register only for the ROM BAR write,
>>> using the write lock uniformly for all command register writes?
>> Sounds good for the start.
>> Another concern is that if we go with a read_lock and then in the
>> underlying code we disable memory decoding and try doing
>> something and calling cmd_write handler for any reason then....
>>
>> I mean that the check in the vpci_write is somewhat we can tolerate,
>> but then it is must be considered that no code in the read path
>> is allowed to perform write path functions. Which brings a pretty
>> valid use-case: say in read mode we detect an unrecoverable error
>> and need to remove the device:
>> vpci_process_pending -> ERROR -> vpci_remove_device or similar.
>>
>> What do we do then? It is all going to be fragile...
> Real hardware won't cause a device to disappear upon a problem with
> a read access. There shouldn't be any need to remove a passed-through
> device either; such problems (if any) need handling differently imo.
Yes, at the moment there is a single place in the code which
removes the device (besides normal use-cases such as
pci_add_device on fail path and PHYSDEVOP_manage_pci_remove):

bool vpci_process_pending(struct vcpu *v)
{
[snip]
         if ( rc )
             /*
              * FIXME: in case of failure remove the device from the domain.
              * Note that there might still be leftover mappings. While this is
              * safe for Dom0, for DomUs the domain will likely need to be
              * killed in order to avoid leaking stale p2m mappings on
              * failure.
              */
             vpci_remove_device(v->vpci.pdev);

>
> Jan
>
>

 


Rackspace

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