aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2012-08-23 03:45:03 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-08-24 14:33:13 -0400
commitb9443f401bb20ae6414e3e68bca0413bad28b689 (patch)
tree3ca037179461b893083963acd166b6835a0da47c
parent0d7614f09c1ebdbaa1599a5aba7593f147bf96ee (diff)
PCI: Use pci_device_id on stack for pci_get_subsys/class() to avoid kmalloc
This fixes a kernel warning https://lkml.org/lkml/2012/7/31/682 pci_get_subsys() may get called in late system reboot stage, using a sleepable kmalloc() sounds fragile and will cause a kernel warning with my recent commmit 55c844a "x86/reboot: Fix a warning message triggered by stop_other_cpus()" which disable local interrupt in late system shutdown/reboot phase. Using a local parameter instead will fix it and make it eligible for calling from atomic context. Do the same change for the pci_get_class() as suggested by Bjorn Helgaas. Initializing the on-stack struct pci_device_id suggested by Fengguang Wu and Jiri Slaby. Section 6.7.8 of the C99 standard guarantees that when we initialize some of the struct members, the rest of the struct is implicitly initialized the same as objects with static storage duration, i.e., to zero in this case. [bhelgaas: changelog, incorporate Fengguang/Jiri initialization fix] Bisected-by: Fengguang Wu <fengguang.wu@intel.com> Signed-off-by: Feng Tang <feng.tang@intel.com> Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Fengguang Wu <fengguang.wu@intel.com>
-rw-r--r--drivers/pci/search.c44
1 files changed, 17 insertions, 27 deletions
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 993d4a0a246..9148b6e8056 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -245,8 +245,12 @@ struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
245 unsigned int ss_vendor, unsigned int ss_device, 245 unsigned int ss_vendor, unsigned int ss_device,
246 struct pci_dev *from) 246 struct pci_dev *from)
247{ 247{
248 struct pci_dev *pdev; 248 struct pci_device_id id = {
249 struct pci_device_id *id; 249 .vendor = vendor,
250 .device = device,
251 .subvendor = ss_vendor,
252 .subdevice = ss_device,
253 };
250 254
251 /* 255 /*
252 * pci_find_subsys() can be called on the ide_setup() path, 256 * pci_find_subsys() can be called on the ide_setup() path,
@@ -257,18 +261,7 @@ struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
257 if (unlikely(no_pci_devices())) 261 if (unlikely(no_pci_devices()))
258 return NULL; 262 return NULL;
259 263
260 id = kzalloc(sizeof(*id), GFP_KERNEL); 264 return pci_get_dev_by_id(&id, from);
261 if (!id)
262 return NULL;
263 id->vendor = vendor;
264 id->device = device;
265 id->subvendor = ss_vendor;
266 id->subdevice = ss_device;
267
268 pdev = pci_get_dev_by_id(id, from);
269 kfree(id);
270
271 return pdev;
272} 265}
273 266
274/** 267/**
@@ -307,19 +300,16 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)
307 */ 300 */
308struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) 301struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
309{ 302{
310 struct pci_dev *dev; 303 struct pci_device_id id = {
311 struct pci_device_id *id; 304 .vendor = PCI_ANY_ID,
312 305 .device = PCI_ANY_ID,
313 id = kzalloc(sizeof(*id), GFP_KERNEL); 306 .subvendor = PCI_ANY_ID,
314 if (!id) 307 .subdevice = PCI_ANY_ID,
315 return NULL; 308 .class_mask = PCI_ANY_ID,
316 id->vendor = id->device = id->subvendor = id->subdevice = PCI_ANY_ID; 309 .class = class,
317 id->class_mask = PCI_ANY_ID; 310 };
318 id->class = class; 311
319 312 return pci_get_dev_by_id(&id, from);
320 dev = pci_get_dev_by_id(id, from);
321 kfree(id);
322 return dev;
323} 313}
324 314
325/** 315/**