diff options
| author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-11-09 09:58:56 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-11-09 09:58:56 -0800 |
| commit | d36a884a1ef5b6808bea1f402fdbe976f85d993c (patch) | |
| tree | daa55efe2b6dd99a3bbfb21f2de0320824652534 | |
| parent | 59b028f31db3a73cf66f6947eece80d141ad36e4 (diff) | |
| parent | 16d78cda70e116fb9cb61790b93b0c85e107ba4b (diff) | |
Merge "soc: qcom: msm_bus: Add debug logging for max bandwidth votes"
| -rw-r--r-- | drivers/soc/qcom/msm_bus/msm_bus_adhoc.h | 5 | ||||
| -rw-r--r-- | drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c | 12 | ||||
| -rw-r--r-- | drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c | 124 | ||||
| -rw-r--r-- | include/trace/events/trace_msm_bus.h | 40 |
4 files changed, 177 insertions, 4 deletions
diff --git a/drivers/soc/qcom/msm_bus/msm_bus_adhoc.h b/drivers/soc/qcom/msm_bus/msm_bus_adhoc.h index 7440e0473e8b..5906e2ed8532 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_adhoc.h +++ b/drivers/soc/qcom/msm_bus/msm_bus_adhoc.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2015, 2017, 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 @@ -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 { diff --git a/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c b/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c index aafe82f59b9a..4ed3e65c0293 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_arb_adhoc.c @@ -549,6 +549,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)) { @@ -556,14 +557,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; diff --git a/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c b/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c index 305f31f31bf8..7288c79de428 100644 --- a/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c +++ b/drivers/soc/qcom/msm_bus/msm_bus_fabric_adhoc.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2017, 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 @@ -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, @@ -431,6 +433,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; @@ -440,8 +504,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) { @@ -1146,6 +1212,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; @@ -1167,6 +1280,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]); @@ -1193,6 +1307,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); } } @@ -1214,6 +1331,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); exit_device_probe: diff --git a/include/trace/events/trace_msm_bus.h b/include/trace/events/trace_msm_bus.h index d914a9660049..3f56fc1e80fb 100644 --- a/include/trace/events/trace_msm_bus.h +++ b/include/trace/events/trace_msm_bus.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2015, 2017, 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), |
