summaryrefslogtreecommitdiff
path: root/drivers/hwmon/ibmaem.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2011-11-04 15:00:46 +0400
committerJean Delvare <khali@endymion.delvare>2011-11-04 15:00:46 +0400
commitda8ebe4e09ee5661f125a8401ade58baf226aa57 (patch)
treea336300b6568c72455c85eef4024630b2735cc57 /drivers/hwmon/ibmaem.c
parent9d84c9e8b5b0386ee1d7769de0ff8a2546a2d054 (diff)
downloadlinux-da8ebe4e09ee5661f125a8401ade58baf226aa57.tar.xz
hwmon: (ibmaem) Avoid repeated memory allocations
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>
Diffstat (limited to 'drivers/hwmon/ibmaem.c')
-rw-r--r--drivers/hwmon/ibmaem.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index 1fed86b307f5..6a967d7dbdee 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -147,8 +147,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:
@@ -355,13 +356,14 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
/* 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 */
@@ -387,10 +389,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;
@@ -433,7 +431,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
res = 0;
out:
- kfree(rs_resp);
return res;
}
@@ -491,6 +488,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);
@@ -584,6 +582,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);
@@ -599,6 +602,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);
@@ -717,6 +722,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);
@@ -732,6 +742,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);