]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
hwmon: (ibmaem) Avoid repeated memory allocations
authorJean Delvare <khali@linux-fr.org>
Tue, 30 Aug 2011 01:16:55 +0000 (11:16 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Tue, 30 Aug 2011 01:16:55 +0000 (11:16 +1000)
Preallocate a buffer for the response to sensor reads, and reuse it
for each read instead of allocating a new one each time. This should
be faster and should also avoid memory fragmentation.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Darrick J. Wong <djwong@us.ibm.com>
Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>
drivers/hwmon/ibmaem.c

index 880d6442c3b4b5c9f355d10e9575263bce6a9846..c6d59b1788d7d835b901297a93fdf8dcb737504f 100644 (file)
@@ -148,8 +148,9 @@ struct aem_data {
        int                     id;
        struct aem_ipmi_data    ipmi;
 
-       /* Function to update sensors */
+       /* Function and buffer to update sensors */
        void (*update)(struct aem_data *data);
+       struct aem_read_sensor_resp *rs_resp;
 
        /*
         * AEM 1.x sensors:
@@ -388,13 +389,14 @@ static void aem_idr_put(int id)
 
 /* Sensor support functions */
 
-/* Read a sensor value */
+/* Read a sensor value; must be called with data->lock held */
 static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
                           void *buf, size_t size)
 {
        int rs_size, res;
        struct aem_read_sensor_req rs_req;
-       struct aem_read_sensor_resp *rs_resp;
+       /* Use preallocated rx buffer */
+       struct aem_read_sensor_resp *rs_resp = data->rs_resp;
        struct aem_ipmi_data *ipmi = &data->ipmi;
 
        /* AEM registers are 1, 2, 4 or 8 bytes */
@@ -420,10 +422,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
        ipmi->tx_message.data_len = sizeof(rs_req);
 
        rs_size = sizeof(*rs_resp) + size;
-       rs_resp = kzalloc(rs_size, GFP_KERNEL);
-       if (!rs_resp)
-               return -ENOMEM;
-
        ipmi->rx_msg_data = rs_resp;
        ipmi->rx_msg_len = rs_size;
 
@@ -466,7 +464,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
        res = 0;
 
 out:
-       kfree(rs_resp);
        return res;
 }
 
@@ -524,6 +521,7 @@ static void aem_delete(struct aem_data *data)
 {
        list_del(&data->list);
        aem_remove_sensors(data);
+       kfree(data->rs_resp);
        hwmon_device_unregister(data->hwmon_dev);
        ipmi_destroy_user(data->ipmi.user);
        platform_set_drvdata(data->pdev, NULL);
@@ -616,6 +614,11 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
        }
 
        data->update = update_aem1_sensors;
+       data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
+       if (!data->rs_resp) {
+               res = -ENOMEM;
+               goto alloc_resp_err;
+       }
 
        /* Find sensors */
        res = aem1_find_sensors(data);
@@ -631,6 +634,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
        return 0;
 
 sensor_err:
+       kfree(data->rs_resp);
+alloc_resp_err:
        hwmon_device_unregister(data->hwmon_dev);
 hwmon_reg_err:
        ipmi_destroy_user(data->ipmi.user);
@@ -748,6 +753,11 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
        }
 
        data->update = update_aem2_sensors;
+       data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL);
+       if (!data->rs_resp) {
+               res = -ENOMEM;
+               goto alloc_resp_err;
+       }
 
        /* Find sensors */
        res = aem2_find_sensors(data);
@@ -763,6 +773,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
        return 0;
 
 sensor_err:
+       kfree(data->rs_resp);
+alloc_resp_err:
        hwmon_device_unregister(data->hwmon_dev);
 hwmon_reg_err:
        ipmi_destroy_user(data->ipmi.user);