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@xxxxxxxxxxxx> Cc: Darrick J. Wong <djwong@xxxxxxxxxx> Cc: Guenter Roeck <guenter.roeck@xxxxxxxxxxxx> --- Darrick, can you please test this patch and report? I do not have the hardware. drivers/hwmon/ibmaem.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) --- linux-3.1-rc2.orig/drivers/hwmon/ibmaem.c 2011-08-18 19:16:12.000000000 +0200 +++ linux-3.1-rc2/drivers/hwmon/ibmaem.c 2011-08-18 19:31:36.000000000 +0200 @@ -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: @@ -390,13 +391,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 */ @@ -422,9 +424,6 @@ static int aem_read_sensor(struct aem_da 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; @@ -468,7 +467,6 @@ static int aem_read_sensor(struct aem_da res = 0; out: - kfree(rs_resp); return res; } @@ -526,6 +524,7 @@ static void aem_delete(struct aem_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); @@ -618,6 +617,11 @@ static int aem_init_aem1_inst(struct aem } 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); @@ -633,6 +637,8 @@ static int aem_init_aem1_inst(struct aem 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); @@ -753,6 +759,11 @@ static int aem_init_aem2_inst(struct aem } 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); @@ -768,6 +779,8 @@ static int aem_init_aem2_inst(struct aem 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); -- Jean Delvare _______________________________________________ lm-sensors mailing list lm-sensors@xxxxxxxxxxxxxx http://lists.lm-sensors.org/mailman/listinfo/lm-sensors