Commit da8ebe4e authored by Jean Delvare's avatar Jean Delvare Committed by Jean Delvare

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: default avatarJean Delvare <khali@linux-fr.org>
Acked-by: default avatarDarrick J. Wong <djwong@us.ibm.com>
Acked-by: default avatarGuenter Roeck <guenter.roeck@ericsson.com>
parent 9d84c9e8
...@@ -147,8 +147,9 @@ struct aem_data { ...@@ -147,8 +147,9 @@ struct aem_data {
int id; int id;
struct aem_ipmi_data ipmi; struct aem_ipmi_data ipmi;
/* Function to update sensors */ /* Function and buffer to update sensors */
void (*update)(struct aem_data *data); void (*update)(struct aem_data *data);
struct aem_read_sensor_resp *rs_resp;
/* /*
* AEM 1.x sensors: * AEM 1.x sensors:
...@@ -355,13 +356,14 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) ...@@ -355,13 +356,14 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)
/* Sensor support functions */ /* 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, static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
void *buf, size_t size) void *buf, size_t size)
{ {
int rs_size, res; int rs_size, res;
struct aem_read_sensor_req rs_req; 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; struct aem_ipmi_data *ipmi = &data->ipmi;
/* AEM registers are 1, 2, 4 or 8 bytes */ /* 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, ...@@ -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); ipmi->tx_message.data_len = sizeof(rs_req);
rs_size = sizeof(*rs_resp) + size; 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_data = rs_resp;
ipmi->rx_msg_len = rs_size; ipmi->rx_msg_len = rs_size;
...@@ -433,7 +431,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, ...@@ -433,7 +431,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
res = 0; res = 0;
out: out:
kfree(rs_resp);
return res; return res;
} }
...@@ -491,6 +488,7 @@ static void aem_delete(struct aem_data *data) ...@@ -491,6 +488,7 @@ static void aem_delete(struct aem_data *data)
{ {
list_del(&data->list); list_del(&data->list);
aem_remove_sensors(data); aem_remove_sensors(data);
kfree(data->rs_resp);
hwmon_device_unregister(data->hwmon_dev); hwmon_device_unregister(data->hwmon_dev);
ipmi_destroy_user(data->ipmi.user); ipmi_destroy_user(data->ipmi.user);
platform_set_drvdata(data->pdev, NULL); platform_set_drvdata(data->pdev, NULL);
...@@ -584,6 +582,11 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) ...@@ -584,6 +582,11 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
} }
data->update = update_aem1_sensors; 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 */ /* Find sensors */
res = aem1_find_sensors(data); res = aem1_find_sensors(data);
...@@ -599,6 +602,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) ...@@ -599,6 +602,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
return 0; return 0;
sensor_err: sensor_err:
kfree(data->rs_resp);
alloc_resp_err:
hwmon_device_unregister(data->hwmon_dev); hwmon_device_unregister(data->hwmon_dev);
hwmon_reg_err: hwmon_reg_err:
ipmi_destroy_user(data->ipmi.user); ipmi_destroy_user(data->ipmi.user);
...@@ -717,6 +722,11 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, ...@@ -717,6 +722,11 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
} }
data->update = update_aem2_sensors; 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 */ /* Find sensors */
res = aem2_find_sensors(data); res = aem2_find_sensors(data);
...@@ -732,6 +742,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, ...@@ -732,6 +742,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
return 0; return 0;
sensor_err: sensor_err:
kfree(data->rs_resp);
alloc_resp_err:
hwmon_device_unregister(data->hwmon_dev); hwmon_device_unregister(data->hwmon_dev);
hwmon_reg_err: hwmon_reg_err:
ipmi_destroy_user(data->ipmi.user); ipmi_destroy_user(data->ipmi.user);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment