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

Commit 75b042df authored by Odelu Kukatla's avatar Odelu Kukatla Committed by Gerrit - the friendly Code Review server
Browse files

soc: qcom: msm_bus: Add debug logging for max bandwidth votes



Max bandwidth vote on each bus device is required to be
printed when the device panics, so add a panic notifier
to print the max BW votes on each bus device.

Change-Id: I2256407638fe5085cb4b0f4d5a594dd00f4f3bce
Signed-off-by: default avatarOdelu Kukatla <okukatla@codeaurora.org>
parent c2719049
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -50,9 +50,12 @@ struct nodebw {
	uint64_t sum_ab;
	uint64_t last_sum_ab;
	uint64_t max_ib;
	uint64_t max_ab;
	uint64_t cur_clk_hz;
	uint32_t util_used;
	uint32_t vrail_used;
	const char *max_ab_cl_name;
	const char *max_ib_cl_name;
};

struct msm_bus_fab_device_type {
+13 −1
Original line number Diff line number Diff line
/* Copyright (c) 2014-2016, 2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, 2018-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -547,6 +547,7 @@ static uint64_t aggregate_bus_req(struct msm_bus_node_device_type *bus_dev,
	struct msm_bus_node_device_type *fab_dev = NULL;
	uint32_t agg_scheme;
	uint64_t max_ib = 0;
	uint64_t max_ab = 0;
	uint64_t sum_ab = 0;

	if (!bus_dev || !to_msm_bus_node(bus_dev->node_info->bus_device)) {
@@ -554,14 +555,25 @@ static uint64_t aggregate_bus_req(struct msm_bus_node_device_type *bus_dev,
		goto exit_agg_bus_req;
	}

	bus_dev->node_bw[ctx].max_ib_cl_name = NULL;
	bus_dev->node_bw[ctx].max_ab_cl_name = NULL;
	fab_dev = to_msm_bus_node(bus_dev->node_info->bus_device);
	for (i = 0; i < bus_dev->num_lnodes; i++) {
		if (bus_dev->lnode_list[i].lnode_ib[ctx] > max_ib)
			bus_dev->node_bw[ctx].max_ib_cl_name =
					bus_dev->lnode_list[i].cl_name;
		max_ib = max(max_ib, bus_dev->lnode_list[i].lnode_ib[ctx]);
		if (bus_dev->lnode_list[i].lnode_ab[ctx] > max_ab) {
			max_ab = bus_dev->lnode_list[i].lnode_ab[ctx];
			bus_dev->node_bw[ctx].max_ab_cl_name =
					bus_dev->lnode_list[i].cl_name;
		}
		sum_ab += bus_dev->lnode_list[i].lnode_ab[ctx];
	}

	bus_dev->node_bw[ctx].sum_ab = sum_ab;
	bus_dev->node_bw[ctx].max_ib = max_ib;
	bus_dev->node_bw[ctx].max_ab = max_ab;

	if (bus_dev->node_info->agg_params.agg_scheme != AGG_SCHEME_NONE)
		agg_scheme = bus_dev->node_info->agg_params.agg_scheme;
+121 −1
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
#include "msm_bus_noc.h"
#include "msm_bus_bimc.h"

static LIST_HEAD(fabdev_list);

static int msm_bus_dev_init_qos(struct device *dev, void *data);

ssize_t bw_show(struct device *dev, struct device_attribute *attr,
@@ -411,6 +413,68 @@ static int msm_bus_agg_fab_clks(struct msm_bus_node_device_type *bus_dev)
	return ret;
}

static void msm_bus_log_fab_max_votes(struct msm_bus_node_device_type *bus_dev)
{
	int ctx;
	struct timespec ts;
	uint32_t vrail_comp = 0;
	struct msm_bus_node_device_type *node;
	uint64_t max_ib, max_ib_temp[NUM_CTX];

	for (ctx = 0; ctx < NUM_CTX; ctx++) {
		max_ib_temp[ctx] = 0;
		bus_dev->node_bw[ctx].max_ib = 0;
		bus_dev->node_bw[ctx].max_ab = 0;
		bus_dev->node_bw[ctx].max_ib_cl_name = NULL;
		bus_dev->node_bw[ctx].max_ab_cl_name = NULL;
	}

	list_for_each_entry(node, &bus_dev->devlist, dev_link) {
		for (ctx = 0; ctx < NUM_CTX; ctx++) {
			max_ib = node->node_bw[ctx].max_ib;
			vrail_comp = node->node_bw[ctx].vrail_used;

			if (vrail_comp && (vrail_comp != 100)) {
				max_ib *= 100;
				max_ib = msm_bus_div64(vrail_comp, max_ib);
			}

			if (max_ib > max_ib_temp[ctx]) {
				max_ib_temp[ctx] = max_ib;
				bus_dev->node_bw[ctx].max_ib =
					node->node_bw[ctx].max_ib;
				bus_dev->node_bw[ctx].max_ib_cl_name =
					node->node_bw[ctx].max_ib_cl_name;
			}

			if (node->node_bw[ctx].max_ab >
					bus_dev->node_bw[ctx].max_ab) {
				bus_dev->node_bw[ctx].max_ab =
					node->node_bw[ctx].max_ab;
				bus_dev->node_bw[ctx].max_ab_cl_name =
					node->node_bw[ctx].max_ab_cl_name;
			}
		}
	}

	ts = ktime_to_timespec(ktime_get());
	for (ctx = 0; ctx < NUM_CTX; ctx++) {
		trace_bus_max_votes((int)ts.tv_sec, (int)ts.tv_nsec,
				bus_dev->node_info->name,
				((ctx == ACTIVE_CTX) ? "active" : "sleep"),
				"ib", bus_dev->node_bw[ctx].max_ib,
				bus_dev->node_bw[ctx].max_ib_cl_name);
	}

	for (ctx = 0; ctx < NUM_CTX; ctx++) {
		trace_bus_max_votes((int)ts.tv_sec, (int)ts.tv_nsec,
				bus_dev->node_info->name,
				((ctx == ACTIVE_CTX) ? "active" : "sleep"),
				"ab", bus_dev->node_bw[ctx].max_ab,
				bus_dev->node_bw[ctx].max_ab_cl_name);
	}
}

int msm_bus_commit_data(struct list_head *clist)
{
	int ret = 0;
@@ -420,8 +484,10 @@ int msm_bus_commit_data(struct list_head *clist)

	list_for_each_entry(node, clist, link) {
		/* Aggregate the bus clocks */
		if (node->node_info->is_fab_dev)
		if (node->node_info->is_fab_dev) {
			msm_bus_agg_fab_clks(node);
			msm_bus_log_fab_max_votes(node);
		}
	}

	list_for_each_entry_safe(node, node_tmp, clist, link) {
@@ -1117,6 +1183,53 @@ int msm_bus_device_remove(struct platform_device *pdev)
	return 0;
}

/**
 * msm_bus_panic_callback() - panic notification callback function.
 *              This function is invoked when a kernel panic occurs.
 * @nfb:        Notifier block pointer
 * @event:      Value passed unmodified to notifier function
 * @data:       Pointer passed unmodified to notifier function
 *
 * Return: NOTIFY_OK
 */
static int msm_bus_panic_callback(struct notifier_block *nfb,
					unsigned long event, void *data)
{
	struct msm_bus_node_device_type *bus_node = NULL;
	unsigned int ctx;

	list_for_each_entry(bus_node, &fabdev_list, dev_link) {
		for (ctx = 0; ctx < NUM_CTX; ctx++) {
			if (bus_node->node_bw[ctx].max_ib_cl_name &&
				bus_node->node_bw[ctx].max_ib) {
				pr_err("%s: %s: %s max_ib: %llu: client-name: %s\n",
				__func__, bus_node->node_info->name,
				((ctx == ACTIVE_CTX) ? "active" : "sleep"),
				bus_node->node_bw[ctx].max_ib,
				bus_node->node_bw[ctx].max_ib_cl_name);
			}
		}

		for (ctx = 0; ctx < NUM_CTX; ctx++) {
			if (bus_node->node_bw[ctx].max_ab_cl_name &&
				bus_node->node_bw[ctx].max_ab) {
				pr_err("%s: %s: %s max_ab: %llu: client-name: %s\n",
				__func__, bus_node->node_info->name,
				((ctx == ACTIVE_CTX) ? "active" : "sleep"),
				bus_node->node_bw[ctx].max_ab,
				bus_node->node_bw[ctx].max_ab_cl_name);
			}
		}
	}

	return NOTIFY_OK;
}

static struct notifier_block msm_bus_panic_notifier = {
	.notifier_call = msm_bus_panic_callback,
	.priority = 1,
};

static int msm_bus_device_probe(struct platform_device *pdev)
{
	unsigned int i, ret;
@@ -1139,6 +1252,7 @@ static int msm_bus_device_probe(struct platform_device *pdev)

	for (i = 0; i < pdata->num_devices; i++) {
		struct device *node_dev = NULL;
		struct msm_bus_node_device_type *bus_node = NULL;

		node_dev = msm_bus_device_init(&pdata->info[i]);

@@ -1165,6 +1279,9 @@ static int msm_bus_device_probe(struct platform_device *pdev)
					__func__, pdata->info[i].node_info->id);
				goto exit_device_probe;
			}

			bus_node = to_msm_bus_node(node_dev);
			list_add_tail(&bus_node->dev_link, &fabdev_list);
		}
	}

@@ -1186,6 +1303,9 @@ static int msm_bus_device_probe(struct platform_device *pdev)
	msm_bus_arb_setops_adhoc(&arb_ops);
	bus_for_each_dev(&msm_bus_type, NULL, NULL, msm_bus_node_debug);

	atomic_notifier_chain_register(&panic_notifier_list,
						&msm_bus_panic_notifier);

	devm_kfree(&pdev->dev, pdata->info);
	devm_kfree(&pdev->dev, pdata);

+39 −1
Original line number Diff line number Diff line
/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2016, 2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -72,6 +72,44 @@ TRACE_EVENT(bus_update_request_end,
	TP_printk("client-name=%s", __get_str(name))
);

TRACE_EVENT(bus_max_votes,

	TP_PROTO(int sec, int nsec, const char *bus_name, const char *ctx,
		const char *bw_type_name, unsigned long long bw,
		const char *cl_name),

	TP_ARGS(sec, nsec, bus_name, ctx, bw_type_name, bw, cl_name),

	TP_STRUCT__entry(
		__field(int, sec)
		__field(int, nsec)
		__string(bus_name, bus_name)
		__string(ctx, ctx)
		__string(bw_type_name, bw_type_name)
		__field(u64, bw)
		__string(cl_name, cl_name)
	),

	TP_fast_assign(
		__entry->sec = sec;
		__entry->nsec = nsec;
		__assign_str(bus_name, bus_name);
		__assign_str(ctx, ctx);
		__assign_str(bw_type_name, bw_type_name);
		__entry->bw = bw;
		__assign_str(cl_name, cl_name);
	),

	TP_printk("time= %u.%09u %s: %s max_%s: %llu: client-name: %s",
		__entry->sec,
		__entry->nsec,
		__get_str(bus_name),
		__get_str(ctx),
		__get_str(bw_type_name),
		(unsigned long long)__entry->bw,
		__get_str(cl_name))
);

TRACE_EVENT(bus_bimc_config_limiter,

	TP_PROTO(int mas_id, unsigned long long cur_lim_bw),