diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-21 07:52:41 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-24 09:20:41 -0400 |
commit | a3e1541637f2096ab31af311c53eaeb0853650d3 (patch) | |
tree | 879f49d58f5b36a571950249eb04a80376b0b508 /drivers/edac | |
parent | 79daef2099a02fed35747c23bad22f30441133ea (diff) |
i7core_edac: Avoid PCI refcount to reach zero on successive load/reload
That's a nasty bug that took me a lot of time to track, and whose
solution took just one line to solve. The best fragrances and the worse
poisons are shipped on the smalest bottles.
The drivers/pci/quick.c implements the pci_get_device function. The normal
behavior is that you call it, the function returns you a pdev pointer
and increment pdev->kobj.kref.refcount of the pci device. However,
if you want to keep searching an object, you need to pass the previous
pdev function to the search.
When you use a not null pointer to pdev "from" field, pci_get_device
will decrement pdev->kobj.kref.refcount, assuming that the driver won't
be using the previous pdev.
The solution is simple: we just need to call pci_dev_get() manually,
for the pdev's that the driver will actually use.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/edac')
-rw-r--r-- | drivers/edac/i7core_edac.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 9868796f4871..71f4dc699abe 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c | |||
@@ -1395,6 +1395,13 @@ static int i7core_get_onedevice(struct pci_dev **prev, | |||
1395 | dev_descr->func, | 1395 | dev_descr->func, |
1396 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); | 1396 | PCI_VENDOR_ID_INTEL, dev_descr->dev_id); |
1397 | 1397 | ||
1398 | /* | ||
1399 | * As stated on drivers/pci/search.c, the reference count for | ||
1400 | * @from is always decremented if it is not %NULL. So, as we need | ||
1401 | * to get all devices up to null, we need to do a get for the device | ||
1402 | */ | ||
1403 | pci_dev_get(pdev); | ||
1404 | |||
1398 | *prev = pdev; | 1405 | *prev = pdev; |
1399 | 1406 | ||
1400 | return 0; | 1407 | return 0; |