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

Commit 98a83f18 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: msm_bus: fix memory allocation issues"

parents 1d342a98 8d3b6fc0
Loading
Loading
Loading
Loading
+77 −16
Original line number Diff line number Diff line
@@ -501,17 +501,58 @@ static int copy_rule(struct bus_rule_type *src, struct rules_def *node_rule,
					__func__);
		return -ENOMEM;
	}
	memcpy(node_rule->rule_ops.src_id, src->src_id,
				sizeof(int) * src->num_src);

	node_rule->rule_ops.thresh = kzalloc(
			(sizeof(u64) * node_rule->rule_ops.num_thresh),
							GFP_KERNEL);
	if (!node_rule->rule_ops.thresh) {
		pr_err("%s:Failed to allocate for thresh",
					__func__);
		kfree(node_rule->rule_ops.src_id);
		return -ENOMEM;
	}
	node_rule->rule_ops.src_field = kzalloc(
			(sizeof(int) * node_rule->rule_ops.num_thresh),
							GFP_KERNEL);
	if (!node_rule->rule_ops.src_field) {
		pr_err("%s:Failed to allocate for src_field",
					__func__);
		kfree(node_rule->rule_ops.src_id);
		kfree(node_rule->rule_ops.thresh);
		return -ENOMEM;
	}
	node_rule->rule_ops.op = kzalloc(
				(sizeof(int) * node_rule->rule_ops.num_thresh),
							GFP_KERNEL);

	if (!node_rule->rule_ops.op) {
		pr_err("%s:Failed to allocate for OP",
					__func__);
		kfree(node_rule->rule_ops.src_id);
		kfree(node_rule->rule_ops.thresh);
		kfree(node_rule->rule_ops.src_field);
		return -ENOMEM;
	}

	memcpy(node_rule->rule_ops.thresh, src->thresh,
				sizeof(u64) * src->num_thresh);
	memcpy(node_rule->rule_ops.src_field, src->src_field,
				sizeof(int) * src->num_thresh);
	memcpy(node_rule->rule_ops.op, src->op,
				sizeof(int) * src->num_thresh);
	memcpy(node_rule->rule_ops.src_id, src->src_id,
				sizeof(int) * src->num_src);
	if (!nb) {
		node_rule->rule_ops.dst_node = kzalloc(
			(sizeof(int) * node_rule->rule_ops.num_dst),
						GFP_KERNEL);
		if (!node_rule->rule_ops.dst_node) {
			pr_err("%s:Failed to allocate for src_id",
			pr_err("%s:Failed to allocate for dst_node",
							__func__);
			kfree(node_rule->rule_ops.src_id);
			kfree(node_rule->rule_ops.thresh);
			kfree(node_rule->rule_ops.src_field);
			kfree(node_rule->rule_ops.op);
			return -ENOMEM;
		}
		memcpy(node_rule->rule_ops.dst_node, src->dst_node,
@@ -523,8 +564,14 @@ static int copy_rule(struct bus_rule_type *src, struct rules_def *node_rule,
		(sizeof(struct node_vote_info) * node_rule->rule_ops.num_src),
							GFP_KERNEL);
	if (!node_rule->src_info) {
		pr_err("%s:Failed to allocate for src_id",
		pr_err("%s:Failed to allocate for src_info",
						__func__);
		kfree(node_rule->rule_ops.src_id);
		kfree(node_rule->rule_ops.thresh);
		kfree(node_rule->rule_ops.src_field);
		kfree(node_rule->rule_ops.op);
		if (!nb)
			kfree(node_rule->rule_ops.dst_node);
		return -ENOMEM;
	}
	for (i = 0; i < src->num_src; i++)
@@ -587,6 +634,7 @@ static bool __rule_register(int num_rules, struct bus_rule_type *rule,
			list_add_tail(&node_rule->link, &node->node_rules);
		}
	}
	if (!nb)
		list_sort(NULL, &node->node_rules, node_rules_compare);
	if (nb && nb != node->rule_notify_list.head)
		raw_notifier_chain_register(&node->rule_notify_list, nb);
@@ -628,6 +676,20 @@ void msm_rule_register(int num_rules, struct bus_rule_type *rule,
	mutex_unlock(&msm_bus_rules_lock);
}

static void free_rule_params(struct rules_def *node_rule)
{
	struct bus_rule_type *rule = &node_rule->rule_ops;

	kfree(rule->src_id);
	kfree(rule->src_field);
	kfree(rule->op);
	kfree(rule->thresh);
	kfree(rule->dst_node);
	kfree(node_rule->src_info);

	list_del(&node_rule->link);
}

static bool __rule_unregister(int num_rules, struct bus_rule_type *rule,
					struct notifier_block *nb)
{
@@ -647,21 +709,20 @@ static bool __rule_unregister(int num_rules, struct bus_rule_type *rule,
			pr_err("%s: Can't find node", __func__);
			goto exit_unregister_rule;
		}
		match_found = true;

		for (i = 0; i < num_rules; i++) {
			list_for_each_entry_safe(node_rule, node_rule_tmp,
					&node->node_rules, link) {
				if (comp_rules(&node_rule->rule_ops,
					&rule[i]) == 0) {
				list_del(&node_rule->link);
					free_rule_params(node_rule);
					kfree(node_rule);
					match_found = true;
					node->num_rules--;
				list_sort(NULL,
					&node->node_rules,
					node_rules_compare);
					break;
				}
			}
		}
		if (!node->num_rules)
			raw_notifier_chain_unregister(
					&node->rule_notify_list, nb);
+6 −6
Original line number Diff line number Diff line
@@ -39,18 +39,18 @@ struct rule_apply_rcm_info {

struct bus_rule_type {
	int num_src;
	int *src_id;
	int *src_field;
	int *op;
	int combo_op;
	int num_thresh;
	u64 *thresh;
	int num_dst;
	int *dst_node;
	u64 dst_bw;
	int mode;
	void *client_data;
	u64 curr_bw;
	void *client_data;
	int *src_id;
	int *src_field;
	int *op;
	u64 *thresh;
	int *dst_node;
};

#if (defined(CONFIG_BUS_TOPOLOGY_ADHOC))