PCI: endpoint: Use a separate lock for protecting epc->pci_epf list
authorManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Tue, 24 Jan 2023 07:11:56 +0000 (12:41 +0530)
committerKrzysztof Wilczyński <kwilczynski@kernel.org>
Mon, 13 Feb 2023 22:27:15 +0000 (07:27 +0900)
commitd6dd5bafaabf98a99a76227ab8dc9a89e76a198f
tree503776881520baf9866e23927a88bfdf6313ad35
parentc2cc5cdda46c0a94ff82bf61016ada2e120f1a3f
PCI: endpoint: Use a separate lock for protecting epc->pci_epf list

The EPC controller maintains a list of EPF drivers added to it. For
protecting this list against the concurrent accesses, the epc->lock
(used for protecting epc_ops) has been used so far. Since there were
no users trying to use epc_ops and modify the pci_epf list simultaneously,
this was not an issue.

But with the addition of callback mechanism for passing the events, this
will be a problem. Because the pci_epf list needs to be iterated first
for getting hold of the EPF driver and then the relevant event specific
callback needs to be called for the driver.

If the same epc->lock is used, then it will result in a deadlock scenario.

For instance,

...
mutex_lock(&epc->lock);
list_for_each_entry(epf, &epc->pci_epf, list) {
epf->event_ops->core_init(epf);
|
|-> pci_epc_set_bar();
|
|-> mutex_lock(&epc->lock) # DEADLOCK
...

So to fix this issue, use a separate lock called "list_lock" for
protecting the pci_epf list against the concurrent accesses. This lock
will also be used by the callback mechanism.

Link: https://lore.kernel.org/linux-pci/20230124071158.5503-4-manivannan.sadhasivam@linaro.org
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
drivers/pci/endpoint/pci-epc-core.c
include/linux/pci-epc.h