aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2005-07-06 13:56:03 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-09-08 17:57:23 -0400
commitd42c69972b853fd33a26c8c7405624be41a22136 (patch)
tree2ac805f0da1279492939f8627103f5f9a040034c
parent56d8456b06ad1316bff3c75caed5e06e786f20d8 (diff)
[PATCH] PCI: Run PCI driver initialization on local node
Run PCI driver initialization on local node Instead of adding messy kmalloc_node()s everywhere run the PCI driver probe on the node local to the device. This would not have helped for IDE, but should for other more clean drivers that do more initialization in probe(). It won't help for drivers that do most of the work on first open (like many network drivers) Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/pci/pci-driver.c31
-rw-r--r--include/linux/mempolicy.h1
-rw-r--r--mm/mempolicy.c2
3 files changed, 32 insertions, 2 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index e4115a0d5ba6..414c77299c7d 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -7,6 +7,7 @@
7#include <linux/module.h> 7#include <linux/module.h>
8#include <linux/init.h> 8#include <linux/init.h>
9#include <linux/device.h> 9#include <linux/device.h>
10#include <linux/mempolicy.h>
10#include "pci.h" 11#include "pci.h"
11 12
12/* 13/*
@@ -163,6 +164,34 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv,
163 return NULL; 164 return NULL;
164} 165}
165 166
167static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
168 const struct pci_device_id *id)
169{
170 int error;
171#ifdef CONFIG_NUMA
172 /* Execute driver initialization on node where the
173 device's bus is attached to. This way the driver likely
174 allocates its local memory on the right node without
175 any need to change it. */
176 struct mempolicy *oldpol;
177 cpumask_t oldmask = current->cpus_allowed;
178 int node = pcibus_to_node(dev->bus);
179 if (node >= 0 && node_online(node))
180 set_cpus_allowed(current, node_to_cpumask(node));
181 /* And set default memory allocation policy */
182 oldpol = current->mempolicy;
183 current->mempolicy = &default_policy;
184 mpol_get(current->mempolicy);
185#endif
186 error = drv->probe(dev, id);
187#ifdef CONFIG_NUMA
188 set_cpus_allowed(current, oldmask);
189 mpol_free(current->mempolicy);
190 current->mempolicy = oldpol;
191#endif
192 return error;
193}
194
166/** 195/**
167 * __pci_device_probe() 196 * __pci_device_probe()
168 * 197 *
@@ -180,7 +209,7 @@ __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
180 209
181 id = pci_match_device(drv, pci_dev); 210 id = pci_match_device(drv, pci_dev);
182 if (id) 211 if (id)
183 error = drv->probe(pci_dev, id); 212 error = pci_call_probe(drv, pci_dev, id);
184 if (error >= 0) { 213 if (error >= 0) {
185 pci_dev->driver = drv; 214 pci_dev->driver = drv;
186 error = 0; 215 error = 0;
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index 94a46f38c532..58385ee1c0ac 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -155,6 +155,7 @@ struct mempolicy *get_vma_policy(struct task_struct *task,
155 155
156extern void numa_default_policy(void); 156extern void numa_default_policy(void);
157extern void numa_policy_init(void); 157extern void numa_policy_init(void);
158extern struct mempolicy default_policy;
158 159
159#else 160#else
160 161
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 13492d66b7c8..afa06e184d88 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -88,7 +88,7 @@ static kmem_cache_t *sn_cache;
88 policied. */ 88 policied. */
89static int policy_zone; 89static int policy_zone;
90 90
91static struct mempolicy default_policy = { 91struct mempolicy default_policy = {
92 .refcnt = ATOMIC_INIT(1), /* never free it */ 92 .refcnt = ATOMIC_INIT(1), /* never free it */
93 .policy = MPOL_DEFAULT, 93 .policy = MPOL_DEFAULT,
94}; 94};