Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1621417 > unrolled thread
| Started by | Christian König <deathsimple@vodafone.de> |
|---|---|
| First post | 2017-04-11 17:40 +0200 |
| Last post | 2017-04-12 18:40 +0200 |
| Articles | 2 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH 2/4] PCI: add functionality for resizing resources v2 Christian König <deathsimple@vodafone.de> - 2017-04-11 17:40 +0200
Re: [PATCH 2/4] PCI: add functionality for resizing resources v2 Bjorn Helgaas <helgaas@kernel.org> - 2017-04-12 18:40 +0200
| From | Christian König <deathsimple@vodafone.de> |
|---|---|
| Date | 2017-04-11 17:40 +0200 |
| Subject | Re: [PATCH 2/4] PCI: add functionality for resizing resources v2 |
| Message-ID | <tv63D-nH-13@gated-at.bofh.it> |
Hi Bjorn,
first of all sorry for the delay, had been busy with other stuff in the
last few weeks.
Am 24.03.2017 um 22:34 schrieb Bjorn Helgaas:
>> + release_child_resources(res);
> Doesn't this recursively release *all* child resources? There could
> be BARs from several devices, or even windows of downstream bridges,
> inside this window. The drivers of those other devices aren't
> expecting things to change here.
Yes, the original idea was that the driver calling this knows that the
BARs will be changed for the bridge it belongs to.
But you're right. I've changed it in the way that our device driver will
release all resource first and then call the function to resize its BAR.
The function will return an error in the next version of the patch if
the bridge BAR which needs to be moved for this is still used by child
resources.
>> +int pci_resize_resource(struct pci_dev *dev, int resno, int size)
>> +{
>> + struct resource *res = dev->resource + resno;
>> + u32 sizes = pci_rbar_get_possible_sizes(dev, resno);
>> + int old = pci_rbar_get_current_size(dev, resno);
>> + u64 bytes = 1ULL << (size + 20);
>> + int ret = 0;
> I think we should fail the request if the device is enabled, i.e., if
> the PCI_COMMAND_MEMORY bit is set. We can't safely change the BAR
> while memory decoding is enabled.
>
> I know there's code in pci_std_update_resource() that turns off
> PCI_COMMAND_MEMORY, but I think that's a mistake: I think it should
> fail when asked to update an enabled BAR the same way
> pci_iov_update_resource() does.
>
> I'm not sure why you call pci_reenable_device() below, but I think I
> would rather have the driver do something like this:
>
> pci_disable_device(dev);
> pci_resize_resource(dev, 0, size);
> pci_enable_device(dev);
>
> That way it's very clear to the driver that it must re-read all BARs
> after resizing this one.
I've tried it, but this actually doesn't seem to work.
At least on the board I've tried pci_disable_device() doesn't clear the
PCI_COMMAND_MEMORY bit, it just clears the master bit.
Additional to that the power management reference counting
pci_disable_device() and pci_enable_device() doesn't look like what I
want for this functionality.
How about the driver needs to disabled memory decoding itself before
trying to resize anything?
>> + if (!sizes)
>> + return -ENOTSUPP;
>> +
>> + if (!(sizes & (1 << size)))
>> + return -EINVAL;
>> +
>> + if (old < 0)
>> + return old;
>> +
>> + /* Make sure the resource isn't assigned before making it larger. */
>> + if (resource_size(res) < bytes && res->parent) {
>> + release_resource(res);
>> + res->end = resource_size(res) - 1;
>> + res->start = 0;
>> + if (resno < PCI_BRIDGE_RESOURCES)
>> + pci_update_resource(dev, resno);
> Why do we need to write this zero to the BAR? If PCI_COMMAND_MEMORY
> is set, I think this is dangerous, and if it's not set, I think it's
> unnecessary.
>
> I think we should set the IORESOURCE_UNSET bit to indicate that the
> resource does not have an address assigned to it. It should get
> cleared later anyway, but having IORESOURCE_UNSET will make any debug
> messages emitted while reassigning resources make more sense.
Makes sense, changed.
>> + return 0;
>> +
>> +error_resize:
>> + pci_rbar_set_size(dev, resno, old);
>> + res->end = res->start + (1ULL << (old + 20)) - 1;
>> +
>> +error_reassign:
>> + pci_assign_unassigned_bus_resources(dev->bus);
>> + pci_setup_bridge(dev->bus);
> Could this bridge-related recovery code go inside
> pci_reassign_bridge_resources()?
No, we need to restore the original size of the resource before trying
the recovery code when something goes wrong.
I will address all other comments in the next version of the patch as well.
Regards,
Christian.
[toc] | [next] | [standalone]
| From | Bjorn Helgaas <helgaas@kernel.org> |
|---|---|
| Date | 2017-04-12 18:40 +0200 |
| Message-ID | <tvttf-6Mv-1@gated-at.bofh.it> |
| In reply to | #1621417 |
On Tue, Apr 11, 2017 at 05:37:04PM +0200, Christian König wrote:
> >>+int pci_resize_resource(struct pci_dev *dev, int resno, int size)
> >>+{
> >>+ struct resource *res = dev->resource + resno;
> >>+ u32 sizes = pci_rbar_get_possible_sizes(dev, resno);
> >>+ int old = pci_rbar_get_current_size(dev, resno);
> >>+ u64 bytes = 1ULL << (size + 20);
> >>+ int ret = 0;
> >I think we should fail the request if the device is enabled, i.e., if
> >the PCI_COMMAND_MEMORY bit is set. We can't safely change the BAR
> >while memory decoding is enabled.
> >
> >I know there's code in pci_std_update_resource() that turns off
> >PCI_COMMAND_MEMORY, but I think that's a mistake: I think it should
> >fail when asked to update an enabled BAR the same way
> >pci_iov_update_resource() does.
> >
> >I'm not sure why you call pci_reenable_device() below, but I think I
> >would rather have the driver do something like this:
> >
> > pci_disable_device(dev);
> > pci_resize_resource(dev, 0, size);
> > pci_enable_device(dev);
> >
> >That way it's very clear to the driver that it must re-read all BARs
> >after resizing this one.
>
> I've tried it, but this actually doesn't seem to work.
>
> At least on the board I've tried pci_disable_device() doesn't clear
> the PCI_COMMAND_MEMORY bit, it just clears the master bit.
Yeah, you're right. We generally turn *on* PCI_COMMAND_MEMORY in the
pci_enable_device() path, but the pci_disable_device() path doesn't
turn it off.
> Additional to that the power management reference counting
> pci_disable_device() and pci_enable_device() doesn't look like what
> I want for this functionality.
>
> How about the driver needs to disabled memory decoding itself before
> trying to resize anything?
There are a few places that do that, so maybe that's the best option.
Bjorn
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web