forked from torvalds/linux
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PCI: hotplug: Initial support of the movable BARs feature
When hot-adding a device, the involved bridge may have windows not big enough (or fragmented too much) for newly requested BARs to fit in. But expanding these bridge windows may be impossible if they are wedged between existing neighboring BARs. Still, it may be possible to allocate a memory region for new BARs, if at least some working BARs can be moved, using the following procedure: 1) Notify all the drivers which support movable BARs to pause and release the BARs; the rest of the drivers are guaranteed that their devices will not get BARs moved; 2) Release all the bridge windows and movable BARs; 3) Try to recalculate new bridge windows that will fit all the BAR types: - fixed (those marked with PCI_FIXED or bound by not-updated drivers); - movable; - newly requested by hot-added devices; 4) If that failed, disable BARs for one of the hot-added devices and repeat the step 3; 5) Notify the drivers, so they remap BARs and resume. If bridge calculation and BAR assignment fail with hot-added devices, this patchset disables their BARs, falling back to the same amount and size of BARs as they were before the hotplug event. The kernel succeeded then, so the same BAR layout will be reproduced again. This makes the prior reservation of memory by BIOS/bootloader/firmware not required anymore for the PCI hotplug. Drivers indicate support of movable BARs by implementing a new .bar_fixed() hook and two optional ones: .rescan_prepare() and .rescan_done() in the struct pci_driver. All device's activity must be paused during a rescan, and iounmap()+ioremap() must be applied to every used BAR. If a device is not bound to a driver, its BARs are considered movable, except VGA devices, due to sometimes indirect usage of their framebuffers. For a higher probability of the successful BAR reassignment, all the BARs and bridge windows should be released during a rescan, not only those with higher addresses. One example when it is needed, BAR(I) is moved to free a gap for the new BAR(II): Before: ==================== parent bridge window =============== ---- hotplug bridge window ---- | BAR(I) | fixed BAR | fixed BAR | fixed BAR | ^^^^^^ ^ | new BAR(II) After: ==================== parent bridge window ========================= ----------- hotplug bridge window ----------- | new BAR(II) | fixed BAR | fixed BAR | fixed BAR | BAR(I) | ^^^^^^^^^^^ ^^^^^^ Another example is a fragmented bridge window jammed between fixed BARs: Before: ===================== parent bridge window ======================== ---------- hotplug bridge window ---------- | fixed BAR | | BAR(I) | | BAR(II) | | BAR(III) | fixed BAR | ^^^^^^ ^ ^^^^^^^ ^^^^^^^^ | new BAR(IV) After: ==================== parent bridge window ========================= ---------- hotplug bridge window ---------- | fixed BAR | BAR(I) | BAR(II) | BAR(III) | new BAR(IV) | fixed BAR | ^^^^^^ ^^^^^^^ ^^^^^^^^ ^^^^^^^^^^^ This patch is a preparation for future patches with actual implementation, and for now it just does the following: - declares the feature; - defines bool pci_can_move_bars and bool pci_dev_bar_fixed(dev, bar); - invokes the new .rescan_prepare() and .rescan_done() driver notifiers; - disables the feature for the powerpc (support will be added later, in another series). The feature is disabled in this first patch of the series, until the actual implementation if finalized by the following patches. It can be overridden per-arch using the pci_can_move_bars=false flag or by the following command line option: pci=no_movable_bars Current approach doesn't support calculating windows for subtractive decode bridges, so disable BAR movement if such bridge is present. Signed-off-by: Sergei Miroshnichenko <s.miroshnichenko@yadro.com>
- Loading branch information
Sergei Miroshnichenko
committed
Jan 13, 2021
1 parent
93e4d12
commit 5bc12ba
Showing
8 changed files
with
181 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters