linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Bjorn Helgaas <bhelgaas@google.com>
To: Yinghai Lu <yinghai@kernel.org>
Cc: Jesse Barnes <jbarnes@virtuousgeek.org>,
	Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Tony Luck <tony.luck@intel.com>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arch@vger.kernel.org
Subject: Re: [PATCH 09/13] PCI: Probe safe range that we can use for unassigned bridge.
Date: Mon, 30 Jan 2012 07:59:57 -0800	[thread overview]
Message-ID: <CAErSpo5QYvx6dtL4NqW4Pu29HXbS-kcTq-GKvpJO8AJ6vRYeBw@mail.gmail.com> (raw)
In-Reply-To: <1327718971-9598-10-git-send-email-yinghai@kernel.org>

On Fri, Jan 27, 2012 at 6:49 PM, Yinghai Lu <yinghai@kernel.org> wrote:
> Try to allocate from parent bus busn_res. if can not find any big enough, will try
> to extend parent bus top. even the extending is through allocating, after allocating
> will pad the range to parent buses top.
>
> When extending happens, We will record the parent_res, so could use it as stopper
> for really extend/shrink top later.
>
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  drivers/pci/probe.c |  117 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 117 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 3e62f45..83df3fb 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -674,6 +674,123 @@ static void __devinit pci_bus_shrink_top(struct pci_bus *parent,
>        }
>  }
>
> +static resource_size_t __devinit find_res_top_free_size(struct resource *res)

I think what this does is "find the largest available area in 'res'."
That *sounds* sort of useful (and like something that could go
somewhere more generic than drivers/pci/probe.c), but there's no
locking, so we don't have any assurance that the area we find will
*remain* available.

Since the caller should deal with failure anyway (if the largest
available area is no longer available by the time it gets around to
allocating it), it seems like it'd be better to fold this into the
caller somehow.

> +{
> +       int ret = -ENOMEM;
> +       resource_size_t n_size;
> +       struct resource tmp_res;
> +
> +       /*
> +        *   find out number below res->end, that we can use at first
> +        *      res->start can not be used.
> +        */
> +       n_size = resource_size(res) - 1;
> +       memset(&tmp_res, 0, sizeof(struct resource));
> +       while (n_size > 0) {
> +               ret = allocate_resource(res, &tmp_res, n_size,
> +                       res->end - n_size + 1, res->end,
> +                       1, NULL, NULL);
> +               if (ret == 0) {
> +                       /* release busn_res */

Comments like this that repeat exactly what the next line of code does
without adding any useful information are unnecessary and distracting.

> +                       release_resource(&tmp_res);
> +                       break;
> +               }
> +               n_size--;
> +       }
> +
> +       return n_size;
> +}
> +
> +static int __devinit pci_bridge_probe_busn_res(struct pci_bus *bus,
> +                        struct pci_dev *dev, struct resource *busn_res,
> +                        resource_size_t needed_size, struct resource **p)
> +{
> +       int ret = -ENOMEM;
> +       resource_size_t n_size;
> +       struct pci_bus *parent;
> +       struct resource *parent_res;
> +       resource_size_t tmp = bus->busn_res.end + 1;
> +       int free_sz = -1;
> +
> +       parent_res = NULL;
> +
> +again:
> +       /*
> +        * find bigest range in bus->busn_res that we can use in the middle
> +        *  and we can not use bus->busn_res.start.
> +        */
> +       n_size = resource_size(&bus->busn_res) - 1;
> +       memset(busn_res, 0, sizeof(struct resource));
> +       dev_printk(KERN_DEBUG, &dev->dev,
> +                       "find free busn in busn_res: %06llx-%06llx\n",
> +                       (unsigned long long)bus->busn_res.start,
> +                       (unsigned long long)bus->busn_res.end);
> +       while (n_size >= needed_size) {
> +               ret = allocate_resource(&bus->busn_res, busn_res, n_size,
> +                               bus->busn_res.start + 1, bus->busn_res.end,
> +                               1, NULL, NULL);
> +               if (ret == 0) {
> +                       /* release res */
> +                       release_resource(busn_res);
> +
> +                       return ret;
> +               }
> +               n_size--;
> +       }
> +
> +       /* try extend the top of parent buss */
> +       if (free_sz < 0) {
> +               free_sz = find_res_top_free_size(&bus->busn_res);
> +               dev_printk(KERN_DEBUG, &dev->dev,
> +                       "found free busn %d in busn_res: %06llx-%06llx top\n",
> +                               free_sz,
> +                               (unsigned long long)bus->busn_res.start,
> +                               (unsigned long long)bus->busn_res.end);
> +       }
> +       n_size = free_sz;
> +
> +       /* check if extend could cross domain boundary */
> +       if ((bus->busn_res.end & 0xff) == 0xff)
> +               goto reduce_needed_size;
> +       if ((0x100 - (tmp & 0xff)) < (needed_size - n_size))
> +               goto reduce_needed_size;
> +
> +       /* find exteded range */
> +       memset(busn_res, 0, sizeof(struct resource));
> +       parent = bus->parent;
> +       while (parent) {
> +               ret = allocate_resource(&parent->busn_res, busn_res,
> +                        needed_size - n_size,
> +                        tmp, tmp + needed_size - n_size - 1,
> +                        1, NULL, NULL);
> +               if (ret == 0)
> +                       break;
> +               parent = parent->parent;
> +       }
> +
> +reduce_needed_size:
> +       if (ret != 0) {
> +               needed_size--;
> +               if (!needed_size)
> +                       return ret;
> +
> +               goto again;
> +       }
> +
> +       /* save parent_res, we need it as stopper later */
> +       parent_res = busn_res->parent;
> +       /* release busn_res */
> +       release_resource(busn_res);
> +       busn_res->start -= n_size;
> +
> +       /* extend parent bus top*/
> +       pci_bus_extend_top(bus, needed_size - n_size, parent_res);
> +
> +       *p = parent_res;
> +
> +       return ret;
> +}
> +
>  /*
>  * If it's a bridge, configure it and scan the bus behind it.
>  * For CardBus bridges, we don't scan behind as the devices will
> --
> 1.7.7
>

  reply	other threads:[~2012-01-30 16:00 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-28  2:49 [PATCH -v2 0/13] PCI: allocate pci bus num range for unassigned bridge busn Yinghai Lu
2012-01-28  2:49 ` [PATCH 01/13] PCI: Add iobusn_resource Yinghai Lu
2012-01-28  2:49 ` [PATCH 02/13] PCI: Add busn_res operation functions Yinghai Lu
2012-01-30 15:28   ` Bjorn Helgaas
2012-01-30 18:32     ` Yinghai Lu
2012-01-28  2:49 ` [PATCH 03/13] PCI: Add busn_res tracking in core Yinghai Lu
2012-01-30 15:35   ` Bjorn Helgaas
2012-01-30 18:39     ` Yinghai Lu
2012-01-28  2:49 ` [PATCH 04/13] PCI, x86: Register busn_res for root buses Yinghai Lu
2012-01-28  2:49 ` [PATCH 05/13] PCI, ia64: " Yinghai Lu
2012-01-28  2:49 ` [PATCH 06/13] PCI, powerpc: " Yinghai Lu
2012-01-30 15:44   ` Bjorn Helgaas
2012-01-28  2:49 ` [PATCH 07/13] PCI, parisc: " Yinghai Lu
2012-01-28  2:49 ` [PATCH 08/13] PCI: Add pci_bus_extend/shrink_top() Yinghai Lu
2012-01-30 15:50   ` Bjorn Helgaas
2012-01-30 18:42     ` Yinghai Lu
2012-01-28  2:49 ` [PATCH 09/13] PCI: Probe safe range that we can use for unassigned bridge Yinghai Lu
2012-01-30 15:59   ` Bjorn Helgaas [this message]
2012-01-30 18:51     ` Yinghai Lu
2012-01-28  2:49 ` [PATCH 10/13] PCI: Strict checking of valid range for bridge Yinghai Lu
2012-01-30 16:04   ` Bjorn Helgaas
2012-01-30 18:52     ` Yinghai Lu
2012-01-28  2:49 ` [PATCH 11/13] PCI: Allocate bus range instead of use max blindly Yinghai Lu
2012-01-28  2:49 ` [PATCH 12/13] PCI: kill pci_fixup_parent_subordinate_busnr() Yinghai Lu
2012-01-30 16:09   ` Bjorn Helgaas
2012-01-28  2:49 ` [PATCH 13/13] PCI: Seperate child bus scanning to two passes overall Yinghai Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAErSpo5QYvx6dtL4NqW4Pu29HXbS-kcTq-GKvpJO8AJ6vRYeBw@mail.gmail.com \
    --to=bhelgaas@google.com \
    --cc=benh@kernel.crashing.org \
    --cc=jbarnes@virtuousgeek.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=tony.luck@intel.com \
    --cc=torvalds@linux-foundation.org \
    --cc=yinghai@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).