Signed-off-by: Andrew Morton --- 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 #include #include +#include #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, }; _