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