Resend: [PATCH] 2.6 ppc64 -- Yet another unbalanced pci_dev_get()/put()
Linas Vepstas
linas at austin.ibm.com
Thu Jul 22 07:10:01 EST 2004
forwarding more bounced email, this one had a patch attached.
--linas
----- Forwarded message from Mail Delivery System <Mailer-Daemon at bilge> -----
------ This is a copy of the message, including all the headers. ------
Return-path: <linas at bilge>
Received: from linas by bilge with local (Exim 3.36 #1 (Debian))
id 1Bkrua-0008BY-00; Wed, 14 Jul 2004 17:07:36 -0500
Date: Wed, 14 Jul 2004 17:07:36 -0500
To: paulus at au1.ibm.com, paulus at samba.org
Cc: linuxppc64-dev at lists.linuxppc.org
Subject: [PATCH] 2.6 ppc64 -- Yet another unbalanced pci_dev_get()/put()
Message-ID: <20040714220736.GW17333 at bilge>
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="TybLhxa8M7aNoW+V"
Content-Disposition: inline
User-Agent: Mutt/1.5.6+20040523i
From: Linas Vepstas <linas at bilge>
--TybLhxa8M7aNoW+V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Paul,
Please review & forward upstream ...
This patch fixes yet another set of mis-matched pci_dev_get() /
pci_dev_put() calls. The bug should affect graphics cards only;
no other card types will see a put() without a matching get().
The mismatch ocured because we ignore eeh errors on graphics
cards :(
There is a small timing window during which this bug may cause memory
corruption on machines with lots of memory pressure, for which a pci
graphics device is being hot-removed...
--linas
--TybLhxa8M7aNoW+V
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="eeh-more-unbalanced-get-put.patch"
===== arch/ppc64/kernel/eeh.c 1.28 vs edited =====
--- 1.28/arch/ppc64/kernel/eeh.c Mon Jul 12 18:29:16 2004
+++ edited/arch/ppc64/kernel/eeh.c Wed Jul 14 15:40:47 2004
@@ -250,6 +250,7 @@
static void __pci_addr_cache_insert_device(struct pci_dev *dev)
{
struct device_node *dn;
+ int really_did_insert = 0;
int i;
dn = pci_device_to_OF_node(dev);
@@ -268,7 +269,6 @@
#endif
return;
}
- pci_dev_get(dev);
/* Walk resources on this device, poke them into the tree */
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
@@ -282,6 +282,11 @@
if (start == 0 || ~start == 0 || end == 0 || ~end == 0)
continue;
pci_addr_cache_insert(dev, start, end, flags);
+ really_did_insert = 1;
+ }
+
+ if (really_did_insert) {
+ pci_dev_get (dev);
}
}
@@ -305,6 +310,7 @@
static inline void __pci_addr_cache_remove_device(struct pci_dev *dev)
{
struct rb_node *n;
+ int really_did_remove = 0;
restart:
n = rb_first(&pci_io_addr_cache_root.rb_root);
@@ -315,11 +321,14 @@
if (piar->pcidev == dev) {
rb_erase(n, &pci_io_addr_cache_root.rb_root);
kfree(piar);
+ really_did_remove = 1;
goto restart;
}
n = rb_next(n);
}
- pci_dev_put(dev);
+ if (really_did_remove) {
+ pci_dev_put(dev);
+ }
}
/**
--TybLhxa8M7aNoW+V--
----- End forwarded message -----
** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc64-dev
mailing list