Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 drivers/pci/pci-driver.c  |   31 ++++++++++++++++++++++++++++++-
 include/linux/mempolicy.h |    1 +
 mm/mempolicy.c            |    2 +-
 3 files changed, 32 insertions(+), 2 deletions(-)

diff -puN drivers/pci/pci-driver.c~gregkh-pci-pci-driver-init-on-node drivers/pci/pci-driver.c
--- devel/drivers/pci/pci-driver.c~gregkh-pci-pci-driver-init-on-node	2005-09-07 20:10:11.000000000 -0700
+++ devel-akpm/drivers/pci/pci-driver.c	2005-09-07 20:10:11.000000000 -0700
@@ -7,6 +7,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/device.h>
+#include <linux/mempolicy.h>
 #include "pci.h"
 
 /*
@@ -163,6 +164,34 @@ const struct pci_device_id *pci_match_de
 	return NULL;
 }
 
+static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
+			  const struct pci_device_id *id)
+{
+	int error;
+#ifdef CONFIG_NUMA
+	/* Execute driver initialization on node where the
+	   device's bus is attached to.  This way the driver likely
+	   allocates its local memory on the right node without
+	   any need to change it. */
+	struct mempolicy *oldpol;
+	cpumask_t oldmask = current->cpus_allowed;
+	int node = pcibus_to_node(dev->bus);
+	if (node >= 0 && node_online(node))
+	    set_cpus_allowed(current, node_to_cpumask(node));
+	/* And set default memory allocation policy */
+	oldpol = current->mempolicy;
+	current->mempolicy = &default_policy;
+	mpol_get(current->mempolicy);
+#endif
+	error = drv->probe(dev, id);
+#ifdef CONFIG_NUMA
+	set_cpus_allowed(current, oldmask);
+	mpol_free(current->mempolicy);
+	current->mempolicy = oldpol;
+#endif
+	return error;
+}
+
 /**
  * __pci_device_probe()
  * 
@@ -180,7 +209,7 @@ __pci_device_probe(struct pci_driver *dr
 
 		id = pci_match_device(drv, pci_dev);
 		if (id)
-			error = drv->probe(pci_dev, id);
+			error = pci_call_probe(drv, pci_dev, id);
 		if (error >= 0) {
 			pci_dev->driver = drv;
 			error = 0;
diff -puN include/linux/mempolicy.h~gregkh-pci-pci-driver-init-on-node include/linux/mempolicy.h
--- devel/include/linux/mempolicy.h~gregkh-pci-pci-driver-init-on-node	2005-09-07 20:10:11.000000000 -0700
+++ devel-akpm/include/linux/mempolicy.h	2005-09-07 20:10:11.000000000 -0700
@@ -155,6 +155,7 @@ struct mempolicy *get_vma_policy(struct 
 
 extern void numa_default_policy(void);
 extern void numa_policy_init(void);
+extern struct mempolicy default_policy;
 
 #else
 
diff -puN mm/mempolicy.c~gregkh-pci-pci-driver-init-on-node mm/mempolicy.c
--- devel/mm/mempolicy.c~gregkh-pci-pci-driver-init-on-node	2005-09-07 20:10:11.000000000 -0700
+++ devel-akpm/mm/mempolicy.c	2005-09-07 20:10:11.000000000 -0700
@@ -88,7 +88,7 @@ static kmem_cache_t *sn_cache;
    policied. */
 static int policy_zone;
 
-static struct mempolicy default_policy = {
+struct mempolicy default_policy = {
 	.refcnt = ATOMIC_INIT(1), /* never free it */
 	.policy = MPOL_DEFAULT,
 };
_