* acpi-pci-hotplug:
ACPI / hotplug / PCI: Avoid parent bus rescans on spurious device checks
ACPI / hotplug / PCI: Use _OST to notify firmware about notify status
ACPI / hotplug / PCI: Avoid doing too much for spurious notifies
ACPI / hotplug / PCI: Don't trim devices before scanning the namespace
In the current ACPIPHP notify handler we always go directly for a
rescan of the parent bus if we get a device check notification for
a device that is not a bridge. However, this obviously is
overzealous if nothing really changes, because this way we may rescan
the whole PCI hierarchy pretty much in vain.
That happens on Alex Williamson's machine whose ACPI tables contain
device objects that are supposed to coresspond to PCIe root ports,
but those ports aren't physically present (or at least they aren't
visible in the PCI config space to us). The BIOS generates multiple
device check notifies for those objects during boot and for each of
them we go straight for the parent bus rescan, but the parent bus is
the root bus in this particular case. In consequence, we rescan the
whole PCI bus from the top several times in a row, which is
completely unnecessary, increases boot time by 50% (after previous
fixes) and generates excess dmesg output from the PCI subsystem.
Fix the problem by checking if we can find anything new in the
slot corresponding to the device we've got a device check notify
for and doing nothig if that's not the case.
The spec (ACPI 5.0, Section 5.6.6) appears to mandate this behavior,
as it says:
Device Check. Used to notify OSPM that the device either appeared
or disappeared. If the device has appeared, OSPM will re-enumerate
from the parent. If the device has disappeared, OSPM will
invalidate the state of the device. OSPM may optimize out
re-enumeration.
Therefore, according to the spec, we are free to do nothing if
nothing changes.
References: https://bugzilla.kernel.org/show_bug.cgi?id=60865
Reported-and-tested-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The spec suggests that we should use _OST to notify the platform
about the status of notifications it sends us, for example so that
it doesn't repeate a notification that has been handled already.
This turns out to help reduce the amount of diagnostic output from
the ACPIPHP subsystem and speed up boot on at least one system that
generates multiple device check notifies for PCIe devices on the root
bus during boot.
Reported-and-tested-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Sometimes we may get a spurious device check or bus check notify for
a hotplug device and in those cases we should avoid doing all of the
configuration work needed when something actually changes. To that
end, check the return value of pci_scan_slot() in enable_slot() and
bail out early if it is 0.
This turns out to help reduce the amount of diagnostic output from
the ACPIPHP subsystem and speed up boot on at least one system that
generates multiple device check notifies for PCIe devices on the root
bus during boot.
Reported-and-tested-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
In acpiphp_bus_add() we first remove device objects corresponding to
the given handle and the ACPI namespace branch below it, which are
then re-created by acpi_bus_scan(). This used to be done to clean
up after surprise removals, but now we do the cleanup through
trim_stale_devices() which checks if the devices in question are
actually gone before removing them, so the device hierarchy trimming
in acpiphp_bus_add() is not necessary any more and, moreover, it may
lead to problems if it removes device objects corresponding to
devices that are actually present.
For this reason, remove the leftover acpiphp_bus_trim() from
acpiphp_bus_add().
Reported-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
After commit bbd34fc (ACPI / hotplug / PCI: Register all devices
under the given bridge) register_slot() is called for all PCI
devices under a given bridge that have corresponding objects in
the ACPI namespace, but it calls acpiphp_register_hotplug_slot()
only for devices satisfying specific criteria. Still,
cleanup_bridge() calls acpiphp_unregister_hotplug_slot() for all
objects created by register_slot(), although it should only call it
for the ones that acpiphp_register_hotplug_slot() has been called
for (successfully). This causes a NULL pointer to be dereferenced
by the acpiphp_unregister_hotplug_slot() executed by cleanup_bridge()
if the object it is called for has not been passed to
acpiphp_register_hotplug_slot().
To fix this problem, check if the 'slot' field of the object passed
to acpiphp_unregister_hotplug_slot() in cleanup_bridge() is not NULL,
which only is the case if acpiphp_register_hotplug_slot() has been
executed for that object. In addition to that, make register_slot()
reset the 'slot' field to NULL if acpiphp_register_hotplug_slot() has
failed for the given object to prevent stale pointers from being
used by acpiphp_unregister_hotplug_slot().
Reported-and-tested-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
We currently enable PCI bridges after scanning a bus and assigning
resources. This is often done in arch code.
This patch changes this so we don't enable a bridge until necessary, i.e.,
until we enable a PCI device behind the bridge. We do this in the generic
pci_enable_device() path, so this also removes the arch-specific code to
enable bridges.
[bhelgaas: changelog]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Now that acpiphp_check_bridge() always enumerates devices behind the
bridge, there is no need to do that for each sub-bridge anymore like
it is done in the current ACPI-based PCI hotplug (ACPIPHP) code.
Given this we don't need check_sub_bridges() anymore, so drop that
function completely.
This also simplifies the ACPIPHP code a bit.
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Do not acquire bridge_mutex around the addition of a slot to its
bridge's list of slots and arount the addition of a function to
its slot's list of functions, because that doesn't help anything
right now (those lists are walked without any locking anyway).
However, acquire bridge_mutex around the list walk in
acpiphp_remove_slots() and use list_for_each_entry() there,
because we terminate the walk as soon as we find the first matching
entry. This prevents that list walk from colliding with bridge
addition and removal.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Notice that functions enable_device() and disable_device() cannot
fail and their return values are ignored in the majority of places,
so redefine them as void and use the opportunity to change their
names to enable_slot() and disable_slot(), respectively, which much
better reflects what they do.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
There is no need for a temporary variable and all the tricks with
ternary operators in acpiphp_get_(latch)|(adapter)_status(). Change
those functions to be a bit more straightforward.
[rjw: Changelog]
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The current implementation of acpiphp_check_bridge() is pretty dumb:
- It enables a slot if it's not enabled and the slot status is
ACPI_STA_ALL.
- It disables a slot if it's enabled and the slot status is not
ACPI_STA_ALL.
This behavior is not sufficient to handle the Thunderbolt daisy
chaining case properly, however, because in that case the bus
behind the already enabled slot needs to be rescanned for new
devices.
For this reason, modify acpiphp_check_bridge() so that slots are
disabled and stopped if they are not in the ACPI_STA_ALL state.
For slots in the ACPI_STA_ALL state, devices behind them that don't
respond are trimmed using a new function, trim_stale_devices(),
introduced specifically for this purpose. That function walks
the given bus and checks each device on it. If the device doesn't
respond, it is assumed to be gone and is removed.
Once all of the stale devices directy behind the slot have been
removed, acpiphp_check_bridge() will start looking for new devices
that might have appeared on the given bus. It will do that even if
the slot is already enabled (SLOT_ENABLED is set for it).
In addition to that, make the bus check notification ignore
SLOT_ENABLED and go for enable_device() directly if bridge is NULL,
so that devices behind the slot are re-enumerated in that case too.
This change is based on earlier patches from Kirill A Shutemov
and Mika Westerberg.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Currently, enable_device() checks the return value of pci_scan_slot()
and returns immediately if that's 0 (meaning that no new functions
have been found in the slot). However, if one of the functions in
the slot is a bridge, some new devices may appear below it even if
the bridge itself is present continuously, so it generally is
necessary to do the rescan anyway just in case. [In particular,
that's necessary with the Thunderbolt daisy chaining in which case
new devices may be connected to the existing ones down the chain.]
The correctness of this change relies on the ability of
pcibios_resource_survey_bus() to detect if it has already been called
for the given bus and to skip it if so. Failure to do that will lead
to resource allocation conflicts.
[rjw: Changelog]
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
With Thunderbolt you can daisy chain devices: connect new devices to
an already plugged one. In that case the "hotplug slot" is already
enabled, but we still want to look for new PCI devices behind it.
Reuse enable_device() to scan for new PCI devices on enabled slots
and push the SLOT_ENABLED check up into acpiphp_enable_slot().
[rjw: Rebased, modified the changelog]
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The ACPI-based PCI hotplug (acpiphp) core code need not and really
should not execute _PS0 and _PS3 directly for devices it handles.
First of all, it is not necessary to put devices into D3 after
acpi_bus_trim() has walked through them, because
acpi_device_unregister() invoked by it puts each device into D3cold
before returning. Thus after disable_device() the slot should be
powered down already.
Second, calling _PS0 directly on ACPI device objects may not be
appropriate, because it may require power resources to be set up in
a specific way in advance and that must be taken care of by the ACPI
core. Thus modify acpiphp_bus_add() to power up the device using
the appropriate interface after it has run acpi_bus_scan() on its
handle.
After that, the functions executing _PS0 and _PS3, power_on_slot()
and power_off_slot(), are not necessary any more, so drop them
and update the code calling them accordingly. Also drop the
function flags related to device power states, since they aren't
useful any more too.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Modify handle_hotplug_event() to avoid queing up the execution of
handle_hotplug_event_work_fn() as a work item on kacpi_hotplug_wq
for non-hotplug events, such as ACPI_NOTIFY_DEVICE_WAKE. Move
the code printing diagnostic messages for those events into
handle_hotplug_event().
In addition to that, remove the bogus comment about how the core
should distinguish between hotplug and non-hotplug events and
queue them up on different workqueues. The core clearly cannot
know in advance what events will be interesting to the given
caller of acpi_install_notify_handler().
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Both acpiphp_disable_slot() and acpiphp_eject_slot() are always
called together so instead of calling each separately we can
consolidate them into one function acpiphp_disable_and_eject_slot()
that does both (but it will return success on _EJ0 failures that
were ignored in the majority of call sites anyway).
[rjw: Rebased plus minor tweaks]
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Two checks in check_hotplug_bridge() are redundant (they have been
done by the caller already), so drop them.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
The acpiphp_bus_trim() and acpiphp_bus_add() functions need not
return error codes that are never checked, so redefine them and
simplify them a bit.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
To avoid chasing more pointers than necessary in some situations,
move the bridge pointer from struct acpiphp_slot to struct
acpiphp_func (and call it 'parent') and add a bus pointer to
struct acpiphp_slot.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
The handle field in struct acpiphp_bridge is only used by
acpiphp_enumerate_slots(), but in that function the local handle
variable can be used instead, so make that happen and drop handle
from struct acpiphp_bridge.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
The ACPI handle stored in struct acpiphp_func is also stored in the
struct acpiphp_context object containing it and it is trivial to get
from a struct acpiphp_func pointer to the handle field of the outer
struct acpiphp_context.
Hence, the handle field of struct acpiphp_func is redundant, so drop
it and provide a helper function, func_to_handle(), allowing it
users to get the ACPI handle for the given struct acpiphp_func
pointer.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Since there has to be a struct acpiphp_func object for every struct
acpiphp_context created by register_slot(), the struct acpiphp_func
one can be embedded into the struct acpiphp_context one, which allows
some code simplifications to be made.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
The only bridge flag used by the ACPI-based PCI hotplug (ACPIPHP)
code is BRIDGE_HAS_EJ0, but it is only used by the event handling
function hotplug_event() and if that flag is set, the corresponding
function flag FUNC_HAS_EJ0 is set as well, so that bridge flag is
redundant.
For this reason, drop BRIDGE_HAS_EJ0 and all code referring to it
and since it is the only bridge flag defined, drop the flags field
from struct acpiphp_bridge entirely.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
If the slot unique number is passed as an additional argument to
acpiphp_register_hotplug_slot(), the 'sun' field in struct
acpiphp_slot is only used by ibm_[s|g]et_attention_status(),
but then it's more efficient to store it in struct slot.
Thus move the 'sun' field from struct acpiphp_slot to struct slot
changing its data type to unsigned int in the process, and redefine
acpiphp_register_hotplug_slot() to take the slot number as separate
argument.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Rework register_slot() to create a struct acpiphp_func object for
every function it is called for and to create acpiphp slots for all
of them. Although acpiphp_register_hotplug_slot() is only called for
the slots whose functions are identified as "ejectable", so that user
space can manipulate them, the ACPIPHP notify handler,
handle_hotplug_event(), is now installed for all of the registered
functions (that aren't dock stations) and hotplug events may be
handled for all of them.
As a result, essentially, all PCI bridges represented by objects in
the ACPI namespace are now going to be "hotplug" bridges and that may
affect resources allocation in general, although it shouldn't lead to
problems.
This allows the code to be simplified substantially and addresses
the problem where bus check or device check notifications for some
PCI bridges or devices are not handled, because those devices are
not recognized as "ejectable" or there appear to be no "ejectable"
devices under those bridges.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
To make the code in register_slot() a bit easier to follow, change
the way the slot allocation part is organized. Drop one local
variable that's not used any more after that modification.
This code change should not lead to any changes in behavior.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Since the func pointer in struct acpiphp_context can always be used
instead of the func pointer in struct acpiphp_bridge, drop the
latter.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
There are separate handling event functions for hotplug bridges and
for hotplug functions, but they may be combined into one common
hotplug event handling function which simplifies the code slightly.
That also allows a theoretical bug to be dealt with which in
principle may occur if a hotplug bridge is on a dock station, because
in that case the bridge-specific notification should be used instead
of the function-specific one, but the dock station always uses the
latter.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Modify handle_hotplug_event() to pass the entire context object
(instead of its fields individually) to work functions started by it.
This change makes the subsequent consolidation of the event handling
work functions a bit more straightforward.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Using the hotplug context objects introduced previously rework the
ACPI-based PCI hotplug (ACPIPHP) core code to get to acpiphp_bridge
objects associated with hotplug bridges from those context objects
rather than from the global list of hotplug bridges.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Using the hotplug context objects introduced previously rework the
ACPI-based PCI hotplug (ACPIPHP) core code so that all notifications
for ACPI device objects corresponding to the hotplug PCI devices are
handled by one function, handle_hotplug_event(), which recognizes
whether it has to handle a bridge or a function.
In addition to code size reduction it allows some ugly pieces of code
where notify handlers have to be uninstalled and installed again to
go away. Moreover, it fixes a theoretically possible race between
handle_hotplug_event() and free_bridge() tearing down data structures
for the same handle.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
When either a new hotplug bridge or a new hotplug function is added
by the ACPI-based PCI hotplug (ACPIPHP) code, attach a context object
to its ACPI handle to store hotplug-related information in it. To
start with, put the handle's bridge and function pointers into that
object. Count references to the context objects and drop them when
they are not needed any more.
First of all, this makes it possible to find out if the given bridge
has been registered as a function already in a much more
straightforward way and acpiphp_bridge_handle_to_function() can be
dropped (Yay!).
This also will allow some more simplifications to be made going
forward.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
When a new ACPIPHP function is added by register_slot() and the
notify handler cannot be installed for it, register_slot() returns an
error status without cleaning up, which causes the entire namespace
walk in acpiphp_enumerate_slots() to be aborted, although it still
may be possible to successfully install the function notify handler
for other device objects under the given brigde.
To address this issue make register_slot() return success after
a new function has been added, even if the addition of the notify
handler for it has failed.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
The acpiphp_enumerate_slots() function is now split into two parts,
acpiphp_enumerate_slots() proper and init_bridge_misc() which is
only called by the former. If these functions are combined,
it is possible to make the code easier to follow and to clean up
the error handling (to prevent memory leaks on error from
happening in particular), so do that.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Since acpi_pci_slot_enumerate() and acpiphp_enumerate_slots() can get
the ACPI device handle they need from bus->bridge, it is not
necessary to pass that handle to them as an argument.
Drop the second argument of acpi_pci_slot_enumerate() and
acpiphp_enumerate_slots(), rework them to obtain the ACPI handle
from bus->bridge and make acpi_pci_add_bus() and
acpi_pci_remove_bus() entirely symmetrical.
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
The only user of the ACPI dock notifier chain is the ACPI-based PCI
hotplug (acpiphp) driver that uses it to carry out post-dock fixups
needed by some systems with broken _DCK. However, it is not
necessary to use a separate notifier chain for that, as it can be
simply replaced with a new callback in struct acpi_dock_ops.
For this reason, add a new .fixup() callback to struct acpi_dock_ops
and make hotplug_dock_devices() execute it for all dock devices with
hotplug operations registered. Accordingly, make acpiphp point that
callback to the function carrying out the post-dock fixups and
do not register a separate dock notifier for each device
registering dock operations. Finally, drop the ACPI dock notifier
chain that has no more users.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Use the new helper functions introduced previously to simplify the
ACPI-based PCI hotplug (acpiphp) driver.
[rjw: Changelog]
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
The interactions between the ACPI dock driver and the ACPI-based PCI
hotplug (acpiphp) are currently problematic because of ordering
issues during hot-remove operations.
First of all, the current ACPI glue code expects that physical
devices will always be deleted before deleting the companion ACPI
device objects. Otherwise, acpi_unbind_one() will fail with a
warning message printed to the kernel log, for example:
[ 185.026073] usb usb5: Oops, 'acpi_handle' corrupt
[ 185.035150] pci 0000:1b:00.0: Oops, 'acpi_handle' corrupt
[ 185.035515] pci 0000:18:02.0: Oops, 'acpi_handle' corrupt
[ 180.013656] port1: Oops, 'acpi_handle' corrupt
This means, in particular, that struct pci_dev objects have to
be deleted before the struct acpi_device objects they are "glued"
with.
Now, the following happens the during the undocking of an ACPI-based
dock station:
1) hotplug_dock_devices() invokes registered hotplug callbacks to
destroy physical devices associated with the ACPI device objects
depending on the dock station. It calls dd->ops->handler() for
each of those device objects.
2) For PCI devices dd->ops->handler() points to
handle_hotplug_event_func() that queues up a separate work item
to execute _handle_hotplug_event_func() for the given device and
returns immediately. That work item will be executed later.
3) hotplug_dock_devices() calls dock_remove_acpi_device() for each
device depending on the dock station. This runs acpi_bus_trim()
for each of them, which causes the underlying ACPI device object
to be destroyed, but the work items queued up by
handle_hotplug_event_func() haven't been started yet.
4) _handle_hotplug_event_func() queued up in step 2) are executed
and cause the above failure to happen, because the PCI devices
they handle do not have the companion ACPI device objects any
more (those objects have been deleted in step 3).
The possible breakage doesn't end here, though, because
hotplug_dock_devices() may return before at least some of the
_handle_hotplug_event_func() work items spawned by it have a
chance to complete and then undock() will cause _DCK to be
evaluated and that will cause the devices handled by the
_handle_hotplug_event_func() to go away possibly while they are
being accessed.
This means that dd->ops->handler() for PCI devices should not point
to handle_hotplug_event_func(). Instead, it should point to a
function that will do the work of _handle_hotplug_event_func()
synchronously. For this reason, introduce such a function,
hotplug_event_func(), and modity acpiphp_dock_ops to point to
it as the handler.
Unfortunately, however, this is not sufficient, because if the dock
code were not changed further, hotplug_event_func() would now
deadlock with hotplug_dock_devices() that called it, since it would
run unregister_hotplug_dock_device() which in turn would attempt to
acquire the dock station's hp_lock mutex already acquired by
hotplug_dock_devices().
To resolve that deadlock use the observation that
unregister_hotplug_dock_device() won't need to acquire hp_lock
if PCI bridges the devices on the dock station depend on are
prevented from being removed prematurely while the first loop in
hotplug_dock_devices() is in progress.
To make that possible, introduce a mechanism by which the callers of
register_hotplug_dock_device() can provide "init" and "release"
routines that will be executed, respectively, during the addition
and removal of the physical device object associated with the
given ACPI device handle. Make acpiphp use two new functions,
acpiphp_dock_init() and acpiphp_dock_release(), that call
get_bridge() and put_bridge(), respectively, on the acpiphp bridge
holding the given device, for this purpose.
In addition to that, remove the dock station's list of
"hotplug devices" and make the dock code always walk the whole list
of "dependent devices" instead in such a way that the loops in
hotplug_dock_devices() and dock_event() (replacing the loops over
"hotplug devices") will take references to the list entries that
register_hotplug_dock_device() has been called for. That prevents
the "release" routines associated with those entries from being
called while the given entry is being processed and for PCI
devices this means that their bridges won't be removed (by a
concurrent thread) while hotplug_event_func() handling them is
being executed.
This change is based on two earlier patches from Jiang Liu.
References: https://bugzilla.kernel.org/show_bug.cgi?id=59501
Reported-and-tested-by: Alexander E. Patrakov <patrakov@gmail.com>
Tracked-down-by: Jiang Liu <jiang.liu@huawei.com>
Tested-by: Illya Klymov <xanf@xanf.me>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Cc: 3.9+ <stable@vger.kernel.org>
On x86 platforms, the kernel respects PCI resource assignments from
the BIOS and only reassigns resources for unassigned BARs at boot
time. However, with the ACPI-based hotplug (acpiphp), it ignores the
BIOS' PCI resource assignments completely and reassigns all resources
by itself. This causes differences in PCI resource allocation
between boot time and runtime hotplug to occur, which is generally
undesirable and sometimes actively breaks things.
Namely, if there are enough resources, reassigning all PCI resources
during runtime hotplug should work, but it may fail if the resources
are constrained. This may happen, for instance, when some PCI
devices with huge MMIO BARs are involved in the runtime hotplug
operations, because the current PCI MMIO alignment algorithm may
waste huge chunks of MMIO address space in those cases.
On the Alexander's Sony VAIO VPCZ23A4R the BIOS allocates limited
MMIO resources for the dock station which contains a device
(graphics adapter) with a 256MB MMIO BAR. An attempt to reassign
that during runtime hotplug causes the dock station MMIO window to be
exhausted and acpiphp fails to allocate resources for the majority
of devices on the dock station as a result.
To prevent that from happening, modify acpiphp to follow the boot
time resources allocation behavior so that the BIOS' resource
assignments are respected during runtime hotplug too.
[rjw: Changelog]
References: https://bugzilla.kernel.org/show_bug.cgi?id=56531
Reported-and-tested-by: Alexander E. Patrakov <patrakov@gmail.com>
Tested-by: Illya Klymov <xanf@xanf.me>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Cc: 3.9+ <stable@vger.kernel.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
When a PCI host bridge device receives a Bus Check notification, we
must re-enumerate starting with the bridge to discover changes (devices
that have been added or removed).
Prior to 668192b678 ("PCI: acpiphp: Move host bridge hotplug to
pci_root.c"), this happened in _handle_hotplug_event_bridge(). After that
commit, _handle_hotplug_event_bridge() is not installed for host bridges,
and the host bridge notify handler, _handle_hotplug_event_root() did not
re-enumerate.
This patch adds re-enumeration to _handle_hotplug_event_root().
This fixes cases where we don't notice the addition or removal of
PCI devices, e.g., the PCI-to-USB ExpressCard in the bugzilla below.
[bhelgaas: changelog, references]
Reference: https://lkml.kernel.org/r/CAAh6nkmbKR3HTqm5ommevsBwhL_u0N8Rk7Wsms_LfP=nBgKNew@mail.gmail.com
Reference: https://bugzilla.kernel.org/show_bug.cgi?id=57961
Reported-by: Gavin Guo <tuffkidtt@gmail.com>
Tested-by: Gavin Guo <tuffkidtt@gmail.com>
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Jiang Liu <jiang.liu@huawei.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
CC: stable@vger.kernel.org # v3.9+
Now acpiphp_enumerate_slots() and acpiphp_remove_slots() may be invoked
concurrently by the PCI core, so add a bridge_mutex and reference count
mechanism to protect acpiphp bridge/slot/function data structures.
To avoid deadlock, handle_hotplug_event_bridge() will requeue the
hotplug event onto the kacpi_hotplug_wq by calling alloc_acpi_hp_work().
But the workaround has introduced a minor race window because the
'bridge' passed to _handle_hotplug_event_bridge() may have already been
destroyed when _handle_hotplug_event_bridge() is actually executed by
the kacpi_hotplug_wq. So hold a reference count on the passed 'bridge'.
Fix the same issue for handle_hotplug_event_func() too.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Use normal list for struct acpiphp_slot to simplify implementation.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Previously the acpiphp driver registered itself as an ACPI PCI subdriver,
so its callbacks were invoked when creating/destroying PCI root
buses to manage ACPI-based PCI hotplug slots. But it doesn't handle
P2P bridge hotplug events, so it will cause strange behaviour if there
are hotplug slots associated with a hot-removed P2P bridge.
This patch fixes this issue by:
1) Directly hooking into PCI core to update hotplug slot devices when
creating/destroying PCI buses through:
pci_{add|remove}_bus() -> acpi_pci_{add|remove}_bus()
2) Getting rid of unused ACPI PCI subdriver-related code
It also cleans up unused code in the acpiphp driver.
[bhelgaas: keep acpi_pci_add_bus() stub for CONFIG_ACPI=n]
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Replace local defined macros (ACPI_STA_xxx) with standard ACPI macros
(ACPI_STA_DEVICE_xxx).
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Currently function disable_device() detects slot state by checking
existence of PCI function 0. It's unreliable because the PCI device
for function 0 may be removed through the sysfs interface. If that
happens, it will cause powering off a hotplug slot without destroying
all PCI devices.
On the other hand, it won't hurt us except wasting some computation
power if the check is removed, because all code of disable_device()
is self-protected. So remove the check.
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Function acpiphp_sanitize_bus() may call pci_stop_and_remove_bus_device(),
which in turn may remove device from bus->devices list. So walk the
bus->devices list with list_for_each_entry_safe().
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Yinghai Lu <yinghai@kernel.org>
Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
Cc: Toshi Kani <toshi.kani@hp.com>
Host bridge hotplug
- Major overhaul of ACPI host bridge add/start (Rafael Wysocki, Yinghai Lu)
- Major overhaul of PCI/ACPI binding (Rafael Wysocki, Yinghai Lu)
- Split out ACPI host bridge and ACPI PCI device hotplug (Yinghai Lu)
- Stop caching _PRT and make independent of bus numbers (Yinghai Lu)
PCI device hotplug
- Clean up cpqphp dead code (Sasha Levin)
- Disable ARI unless device and upstream bridge support it (Yijing Wang)
- Initialize all hot-added devices (not functions 0-7) (Yijing Wang)
Power management
- Don't touch ASPM if disabled (Joe Lawrence)
- Fix ASPM link state management (Myron Stowe)
Miscellaneous
- Fix PCI_EXP_FLAGS accessor (Alex Williamson)
- Disable Bus Master in pci_device_shutdown (Konstantin Khlebnikov)
- Document hotplug resource and MPS parameters (Yijing Wang)
- Add accessor for PCIe capabilities (Myron Stowe)
- Drop pciehp suspend/resume messages (Paul Bolle)
- Make pci_slot built-in only (not a module) (Jiang Liu)
- Remove unused PCI/ACPI bind ops (Jiang Liu)
- Removed used pci_root_bus (Bjorn Helgaas)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
iQIcBAABAgAGBQJRKS3hAAoJEFmIoMA60/r8xxoP/j1CS4oCZAnBIVT9fKBkis+/
CENcfHIUKj6J9iMfJEVvqBELvqaLqtpeNwAGMcGPxV7VuT3K1QumChfaTpRDP0HC
VDRmrjcmfenEK+YPOG7acsrTyqk2wjpLOyu9MKRxtC5u7tF6376KQpkEFpO4haL4
eUHTxfE76OkrPBSvx3+PUSf6jqrvrNbjX8K6HdDVVlm3sVAQKmYJU/Wphv2NPOqa
CAMyCzEGybFjr8hDRwvWgr+06c718GMwQUbnrPdHXAe7lMNMrN/XVBmU9ABN3Aas
icd3lrDs+yPObgcO/gT8+sAZErCtdJ9zuHGYHdYpRbIQj/5JT4TMk7tw/Bj7vKY9
Mqmho9GR5YmYTRN9f1r+2n5AQ/KYWXJDrRNOnt5/ys5BOM3vwJ7WJ902zpSwtFQp
nLX+oD/hLfzpnoIQGDuBAoAXp2Kam3XWRgVvG78buRNrPj+kUzimk14a8qQeY+CB
El6UKuwi5Uv/qgs1gAqqjmZmsAkon2DnsRZa6Fl8NTkDlis7LY4gp9OU38ySFpB+
PhCmRyCZmDDqTVtwj6XzR3nPQ5LBSbvsTfgMxYMIUSXHa06tyb2q5p4mEIas0OmU
RKaP5xQqZuTgD8fbdYrx0xgSrn7JHt/j/X//Qs6unlLCWhlpm3LjJZKxyw2FwBGr
o4Lci+PiBh3MowCrju9D
=ER3b
-----END PGP SIGNATURE-----
Merge tag 'pci-v3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas:
"Host bridge hotplug
- Major overhaul of ACPI host bridge add/start (Rafael Wysocki, Yinghai Lu)
- Major overhaul of PCI/ACPI binding (Rafael Wysocki, Yinghai Lu)
- Split out ACPI host bridge and ACPI PCI device hotplug (Yinghai Lu)
- Stop caching _PRT and make independent of bus numbers (Yinghai Lu)
PCI device hotplug
- Clean up cpqphp dead code (Sasha Levin)
- Disable ARI unless device and upstream bridge support it (Yijing Wang)
- Initialize all hot-added devices (not functions 0-7) (Yijing Wang)
Power management
- Don't touch ASPM if disabled (Joe Lawrence)
- Fix ASPM link state management (Myron Stowe)
Miscellaneous
- Fix PCI_EXP_FLAGS accessor (Alex Williamson)
- Disable Bus Master in pci_device_shutdown (Konstantin Khlebnikov)
- Document hotplug resource and MPS parameters (Yijing Wang)
- Add accessor for PCIe capabilities (Myron Stowe)
- Drop pciehp suspend/resume messages (Paul Bolle)
- Make pci_slot built-in only (not a module) (Jiang Liu)
- Remove unused PCI/ACPI bind ops (Jiang Liu)
- Removed used pci_root_bus (Bjorn Helgaas)"
* tag 'pci-v3.9-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (51 commits)
PCI/ACPI: Don't cache _PRT, and don't associate them with bus numbers
PCI: Fix PCI Express Capability accessors for PCI_EXP_FLAGS
ACPI / PCI: Make pci_slot built-in only, not a module
PCI/PM: Clear state_saved during suspend
PCI: Use atomic_inc_return() rather than atomic_add_return()
PCI: Catch attempts to disable already-disabled devices
PCI: Disable Bus Master unconditionally in pci_device_shutdown()
PCI: acpiphp: Remove dead code for PCI host bridge hotplug
PCI: acpiphp: Create companion ACPI devices before creating PCI devices
PCI: Remove unused "rc" in virtfn_add_bus()
PCI: pciehp: Drop suspend/resume ENTRY messages
PCI/ASPM: Don't touch ASPM if forcibly disabled
PCI/ASPM: Deallocate upstream link state even if device is not PCIe
PCI: Document MPS parameters pci=pcie_bus_safe, pci=pcie_bus_perf, etc
PCI: Document hpiosize= and hpmemsize= resource reservation parameters
PCI: Use PCI Express Capability accessor
PCI: Introduce accessor to retrieve PCIe Capabilities Register
PCI: Put pci_dev in device tree as early as possible
PCI: Skip attaching driver in device_add()
PCI: acpiphp: Keep driver loaded even if no slots found
...
This changeset is aimed at fixing a few different but related
problems in the ACPI hotplug infrastructure.
First of all, since notify handlers may be run in parallel with
acpi_bus_scan(), acpi_bus_trim() and acpi_bus_hot_remove_device()
and some of them are installed for ACPI handles that have no struct
acpi_device objects attached (i.e. before those objects are created),
those notify handlers have to take acpi_scan_lock to prevent races
from taking place (e.g. a struct acpi_device is found to be present
for the given ACPI handle, but right after that it is removed by
acpi_bus_trim() running in parallel to the given notify handler).
Moreover, since some of them call acpi_bus_scan() and
acpi_bus_trim(), this leads to the conclusion that acpi_scan_lock
should be acquired by the callers of these two funtions rather by
these functions themselves.
For these reasons, make all notify handlers that can handle device
addition and eject events take acpi_scan_lock and remove the
acpi_scan_lock locking from acpi_bus_scan() and acpi_bus_trim().
Accordingly, update all of their users to make sure that they
are always called under acpi_scan_lock.
Furthermore, since eject operations are carried out asynchronously
with respect to the notify events that trigger them, with the help
of acpi_bus_hot_remove_device(), even if notify handlers take the
ACPI scan lock, it still is possible that, for example,
acpi_bus_trim() will run between acpi_bus_hot_remove_device() and
the notify handler that scheduled its execution and that
acpi_bus_trim() will remove the device node passed to
acpi_bus_hot_remove_device() for ejection. In that case, the struct
acpi_device object obtained by acpi_bus_hot_remove_device() will be
invalid and not-so-funny things will ensue. To protect agaist that,
make the users of acpi_bus_hot_remove_device() run get_device() on
ACPI device node objects that are about to be passed to it and make
acpi_bus_hot_remove_device() run put_device() on them and check if
their ACPI handles are not NULL (make acpi_device_unregister() clear
the device nodes' ACPI handles for that check to work).
Finally, observe that acpi_os_hotplug_execute() actually can fail,
in which case its caller ought to free memory allocated for the
context object to prevent leaks from happening. It also needs to
run put_device() on the device node that it ran get_device() on
previously in that case. Modify the code accordingly.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>