summaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
authorJon Derrick <jonathan.derrick@intel.com>2016-09-14 10:38:55 -0600
committerBjorn Helgaas <bhelgaas@google.com>2016-09-27 14:30:36 -0500
commit4b202b716e4e282c26c4a95952ea33e318c363ab (patch)
tree672529777b3c47350a78ed1374dd3a8329737147 /drivers/pci/pcie
parent2458d66b245e39786bc5b51062e6d30aa5ad0282 (diff)
downloadlinux-4b202b716e4e282c26c4a95952ea33e318c363ab.tar.bz2
PCI/AER: Avoid memory allocation in interrupt handling path
When handling AER events, we previously allocated a struct aer_err_info, processed the error, and freed the struct. But aer_isr_one_error() is serialized by rpc_mutex, so we never need more than one copy of the struct, and the struct is only about 70 bytes, so we're not saving much by allocating it dynamically. Embed a struct aer_err_info directly in struct aer_rpc, which is allocated at probe-time by aer_probe(). [bhelgaas: changelog] Suggested-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Jon Derrick <jonathan.derrick@intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h1
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c13
2 files changed, 3 insertions, 11 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index f15ca8dc3882..d51e4a57b190 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -60,6 +60,7 @@ struct aer_rpc {
struct pcie_device *rpd; /* Root Port device */
struct work_struct dpc_handler;
struct aer_err_source e_sources[AER_ERROR_SOURCES_MAX];
+ struct aer_err_info e_info;
unsigned short prod_idx; /* Error Producer Index */
unsigned short cons_idx; /* Error Consumer Index */
int isr;
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 8262527e7fed..9fd18a08b23e 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -711,15 +711,8 @@ static inline void aer_process_err_devices(struct pcie_device *p_device,
static void aer_isr_one_error(struct pcie_device *p_device,
struct aer_err_source *e_src)
{
- struct aer_err_info *e_info;
-
- /* struct aer_err_info might be big, so we allocate it with slab */
- e_info = kmalloc(sizeof(struct aer_err_info), GFP_KERNEL);
- if (!e_info) {
- dev_printk(KERN_DEBUG, &p_device->port->dev,
- "Can't allocate mem when processing AER errors\n");
- return;
- }
+ struct aer_rpc *rpc = get_service_data(p_device);
+ struct aer_err_info *e_info = &rpc->e_info;
/*
* There is a possibility that both correctable error and
@@ -758,8 +751,6 @@ static void aer_isr_one_error(struct pcie_device *p_device,
if (find_source_device(p_device->port, e_info))
aer_process_err_devices(p_device, e_info);
}
-
- kfree(e_info);
}
/**