PCI/AER: Avoid memory allocation in interrupt handling path
authorJon Derrick <jonathan.derrick@intel.com>
Wed, 14 Sep 2016 16:38:55 +0000 (10:38 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Tue, 27 Sep 2016 19:30:36 +0000 (14:30 -0500)
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>
drivers/pci/pcie/aer/aerdrv.h
drivers/pci/pcie/aer/aerdrv_core.c

index f15ca8dc38822424169e3e21ac4542b334c77319..d51e4a57b190095c0e1641f44d4f7a530c457db7 100644 (file)
@@ -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;
index 8262527e7fed05a8d5eb495ce46770d659f207a7..9fd18a08b23ed1247254becbb8fc53ba4f551240 100644 (file)
@@ -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);
 }
 
 /**