diff options
author | Jean Delvare <khali@linux-fr.org> | 2011-11-04 07:00:46 -0400 |
---|---|---|
committer | Jean Delvare <khali@endymion.delvare> | 2011-11-04 07:00:46 -0400 |
commit | da8ebe4e09ee5661f125a8401ade58baf226aa57 (patch) | |
tree | a336300b6568c72455c85eef4024630b2735cc57 /drivers/hwmon/ibmaem.c | |
parent | 9d84c9e8b5b0386ee1d7769de0ff8a2546a2d054 (diff) |
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.c | 28 |
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 { | |||
147 | int id; | 147 | int id; |
148 | struct aem_ipmi_data ipmi; | 148 | struct aem_ipmi_data ipmi; |
149 | 149 | ||
150 | /* Function to update sensors */ | 150 | /* Function and buffer to update sensors */ |
151 | void (*update)(struct aem_data *data); | 151 | void (*update)(struct aem_data *data); |
152 | struct aem_read_sensor_resp *rs_resp; | ||
152 | 153 | ||
153 | /* | 154 | /* |
154 | * AEM 1.x sensors: | 155 | * AEM 1.x sensors: |
@@ -355,13 +356,14 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
355 | 356 | ||
356 | /* Sensor support functions */ | 357 | /* Sensor support functions */ |
357 | 358 | ||
358 | /* Read a sensor value */ | 359 | /* Read a sensor value; must be called with data->lock held */ |
359 | static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, | 360 | static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, |
360 | void *buf, size_t size) | 361 | void *buf, size_t size) |
361 | { | 362 | { |
362 | int rs_size, res; | 363 | int rs_size, res; |
363 | struct aem_read_sensor_req rs_req; | 364 | struct aem_read_sensor_req rs_req; |
364 | struct aem_read_sensor_resp *rs_resp; | 365 | /* Use preallocated rx buffer */ |
366 | struct aem_read_sensor_resp *rs_resp = data->rs_resp; | ||
365 | struct aem_ipmi_data *ipmi = &data->ipmi; | 367 | struct aem_ipmi_data *ipmi = &data->ipmi; |
366 | 368 | ||
367 | /* AEM registers are 1, 2, 4 or 8 bytes */ | 369 | /* 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 | ipmi->tx_message.data_len = sizeof(rs_req); | 389 | ipmi->tx_message.data_len = sizeof(rs_req); |
388 | 390 | ||
389 | rs_size = sizeof(*rs_resp) + size; | 391 | rs_size = sizeof(*rs_resp) + size; |
390 | rs_resp = kzalloc(rs_size, GFP_KERNEL); | ||
391 | if (!rs_resp) | ||
392 | return -ENOMEM; | ||
393 | |||
394 | ipmi->rx_msg_data = rs_resp; | 392 | ipmi->rx_msg_data = rs_resp; |
395 | ipmi->rx_msg_len = rs_size; | 393 | ipmi->rx_msg_len = rs_size; |
396 | 394 | ||
@@ -433,7 +431,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, | |||
433 | res = 0; | 431 | res = 0; |
434 | 432 | ||
435 | out: | 433 | out: |
436 | kfree(rs_resp); | ||
437 | return res; | 434 | return res; |
438 | } | 435 | } |
439 | 436 | ||
@@ -491,6 +488,7 @@ static void aem_delete(struct aem_data *data) | |||
491 | { | 488 | { |
492 | list_del(&data->list); | 489 | list_del(&data->list); |
493 | aem_remove_sensors(data); | 490 | aem_remove_sensors(data); |
491 | kfree(data->rs_resp); | ||
494 | hwmon_device_unregister(data->hwmon_dev); | 492 | hwmon_device_unregister(data->hwmon_dev); |
495 | ipmi_destroy_user(data->ipmi.user); | 493 | ipmi_destroy_user(data->ipmi.user); |
496 | platform_set_drvdata(data->pdev, NULL); | 494 | 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 | } | 582 | } |
585 | 583 | ||
586 | data->update = update_aem1_sensors; | 584 | data->update = update_aem1_sensors; |
585 | data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL); | ||
586 | if (!data->rs_resp) { | ||
587 | res = -ENOMEM; | ||
588 | goto alloc_resp_err; | ||
589 | } | ||
587 | 590 | ||
588 | /* Find sensors */ | 591 | /* Find sensors */ |
589 | res = aem1_find_sensors(data); | 592 | res = aem1_find_sensors(data); |
@@ -599,6 +602,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle) | |||
599 | return 0; | 602 | return 0; |
600 | 603 | ||
601 | sensor_err: | 604 | sensor_err: |
605 | kfree(data->rs_resp); | ||
606 | alloc_resp_err: | ||
602 | hwmon_device_unregister(data->hwmon_dev); | 607 | hwmon_device_unregister(data->hwmon_dev); |
603 | hwmon_reg_err: | 608 | hwmon_reg_err: |
604 | ipmi_destroy_user(data->ipmi.user); | 609 | ipmi_destroy_user(data->ipmi.user); |
@@ -717,6 +722,11 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
717 | } | 722 | } |
718 | 723 | ||
719 | data->update = update_aem2_sensors; | 724 | data->update = update_aem2_sensors; |
725 | data->rs_resp = kzalloc(sizeof(*(data->rs_resp)) + 8, GFP_KERNEL); | ||
726 | if (!data->rs_resp) { | ||
727 | res = -ENOMEM; | ||
728 | goto alloc_resp_err; | ||
729 | } | ||
720 | 730 | ||
721 | /* Find sensors */ | 731 | /* Find sensors */ |
722 | res = aem2_find_sensors(data); | 732 | res = aem2_find_sensors(data); |
@@ -732,6 +742,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe, | |||
732 | return 0; | 742 | return 0; |
733 | 743 | ||
734 | sensor_err: | 744 | sensor_err: |
745 | kfree(data->rs_resp); | ||
746 | alloc_resp_err: | ||
735 | hwmon_device_unregister(data->hwmon_dev); | 747 | hwmon_device_unregister(data->hwmon_dev); |
736 | hwmon_reg_err: | 748 | hwmon_reg_err: |
737 | ipmi_destroy_user(data->ipmi.user); | 749 | ipmi_destroy_user(data->ipmi.user); |