aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-12-31 08:24:56 -0500
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-01-07 14:13:09 -0500
commit873392ca514f87eae39f53b6944caf85b1a047cb (patch)
tree510d70a5a8efb122139f5ada4363b3f5985663a4 /drivers
parenta79d682f789730dfabaebbb507c87a90c0671a62 (diff)
PCI: work_on_cpu: use in drivers/pci/pci-driver.c
This uses work_on_cpu(), rather than altering the cpumask of the thread which we happen to be. Note the cleanups: 1) I've removed the CONFIG_NUMA test, since dev_to_node() returns -1 for !CONFIG_NUMA anyway and the compiler will eliminate it. 2) No need to reset mempolicy to default (a bad idea anyway) since work_on_cpu is run from a workqueue. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/pci-driver.c52
1 files changed, 32 insertions, 20 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 888191a3b0d1..c3f76be832d4 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -16,6 +16,7 @@
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/cpu.h>
19#include "pci.h" 20#include "pci.h"
20 21
21/* 22/*
@@ -185,32 +186,43 @@ static const struct pci_device_id *pci_match_device(struct pci_driver *drv,
185 return pci_match_id(drv->id_table, dev); 186 return pci_match_id(drv->id_table, dev);
186} 187}
187 188
189struct drv_dev_and_id {
190 struct pci_driver *drv;
191 struct pci_dev *dev;
192 const struct pci_device_id *id;
193};
194
195static long local_pci_probe(void *_ddi)
196{
197 struct drv_dev_and_id *ddi = _ddi;
198
199 return ddi->drv->probe(ddi->dev, ddi->id);
200}
201
188static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, 202static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
189 const struct pci_device_id *id) 203 const struct pci_device_id *id)
190{ 204{
191 int error; 205 int error, node;
192#ifdef CONFIG_NUMA 206 struct drv_dev_and_id ddi = { drv, dev, id };
193 /* Execute driver initialization on node where the
194 device's bus is attached to. This way the driver likely
195 allocates its local memory on the right node without
196 any need to change it. */
197 struct mempolicy *oldpol;
198 cpumask_t oldmask = current->cpus_allowed;
199 int node = dev_to_node(&dev->dev);
200 207
208 /* Execute driver initialization on node where the device's
209 bus is attached to. This way the driver likely allocates
210 its local memory on the right node without any need to
211 change it. */
212 node = dev_to_node(&dev->dev);
201 if (node >= 0) { 213 if (node >= 0) {
214 int cpu;
202 node_to_cpumask_ptr(nodecpumask, node); 215 node_to_cpumask_ptr(nodecpumask, node);
203 set_cpus_allowed_ptr(current, nodecpumask); 216
204 } 217 get_online_cpus();
205 /* And set default memory allocation policy */ 218 cpu = cpumask_any_and(nodecpumask, cpu_online_mask);
206 oldpol = current->mempolicy; 219 if (cpu < nr_cpu_ids)
207 current->mempolicy = NULL; /* fall back to system default policy */ 220 error = work_on_cpu(cpu, local_pci_probe, &ddi);
208#endif 221 else
209 error = drv->probe(dev, id); 222 error = local_pci_probe(&ddi);
210#ifdef CONFIG_NUMA 223 put_online_cpus();
211 set_cpus_allowed_ptr(current, &oldmask); 224 } else
212 current->mempolicy = oldpol; 225 error = local_pci_probe(&ddi);
213#endif
214 return error; 226 return error;
215} 227}
216 228