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>
This commit is contained in:
parent
9d84c9e8b5
commit
da8ebe4e09
@ -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)
|
|||||||
|
|
||||||
/* 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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
{
|
{
|
||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user