Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+20 −8
Original line number Diff line number Diff line
@@ -147,8 +147,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:
@@ -355,13 +356,14 @@ static void aem_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data)

/* 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 */
@@ -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);

	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;

@@ -433,7 +431,6 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg,
	res = 0;

out:
	kfree(rs_resp);
	return res;
}

@@ -491,6 +488,7 @@ static void aem_delete(struct aem_data *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);
@@ -584,6 +582,11 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
	}

	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);
@@ -599,6 +602,8 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
	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);
@@ -717,6 +722,11 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
	}

	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);
@@ -732,6 +742,8 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
	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);