[PATCH 2/2] hwmon: (ibmaem) Avoid repeated memory allocations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Kernel]     [Linux Hardware Monitoring]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux