diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2018-12-05 06:01:22 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-12-05 06:01:22 -0800 |
| commit | 22b90bcbe5286095200538fc6d89980599ea7d1b (patch) | |
| tree | ce064ac630e05326ace2400f0084f0cc8d39c34f | |
| parent | a3eba1613d5b0ab4a281cb71576d8ddaddec558f (diff) | |
| parent | e3051954fbf9b3c452496d9db80abb0db0e93499 (diff) | |
Merge "soc: qcom: glink: Add support to set affinities"
| -rw-r--r-- | Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt | 2 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink.c | 1 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_core_if.h | 5 | ||||
| -rw-r--r-- | drivers/soc/qcom/glink_smem_native_xprt.c | 40 |
4 files changed, 46 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt b/Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt index f68c8e4a4554..7011d5cf4bf5 100644 --- a/Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt +++ b/Documentation/devicetree/bindings/arm/msm/glink_smem_native_xprt.txt @@ -11,6 +11,7 @@ Required properties: -label : the name of the subsystem this link connects to Optional properties: +-cpu-affinity: Cores to pin the interrupt and receiving work thread to. -qcom,qos-config: Reference to the qos configuration elements.It depends on ramp-time. -qcom,ramp-time: Worst case time in microseconds to transition to this power @@ -36,6 +37,7 @@ Example: qcom,irq-mask = <0x1000>; interrupts = <0 25 1>; label = "lpass"; + cpu-affinity = <1 2>; qcom,qos-config = <&glink_qos_adsp>; qcom,ramp-time = <0x10>, <0x20>, diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index 813c97bb4a50..af7d22e7bb23 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.c @@ -4108,6 +4108,7 @@ int glink_core_register_transport(struct glink_transport_if *if_ptr, kfree(xprt_ptr); return -ENOMEM; } + cfg->tx_task = xprt_ptr->tx_task; ret = glink_core_init_xprt_qos_cfg(xprt_ptr, cfg); if (ret < 0) { kfree(xprt_ptr); diff --git a/drivers/soc/qcom/glink_core_if.h b/drivers/soc/qcom/glink_core_if.h index 14113305a50e..704171fdbf34 100644 --- a/drivers/soc/qcom/glink_core_if.h +++ b/drivers/soc/qcom/glink_core_if.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-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 @@ -14,6 +14,7 @@ #include <linux/of.h> #include <linux/types.h> +#include <linux/sched.h> #include "glink_private.h" /* Local Channel state */ @@ -105,6 +106,7 @@ struct glink_core_flow_info { * @versions_entries: Number of entries in @versions. * @max_cid: Maximum number of channel identifiers supported. * @max_iid: Maximum number of intent identifiers supported. + * @tx_task: Task structure for tx thread. * @mtu: MTU supported by this transport. * @num_flows: Number of traffic flows/priority buckets. * @flow_info: Information about each flow/priority. @@ -117,6 +119,7 @@ struct glink_core_transport_cfg { size_t versions_entries; uint32_t max_cid; uint32_t max_iid; + struct task_struct *tx_task; size_t mtu; uint32_t num_flows; diff --git a/drivers/soc/qcom/glink_smem_native_xprt.c b/drivers/soc/qcom/glink_smem_native_xprt.c index e532f071c9ee..431fe6748990 100644 --- a/drivers/soc/qcom/glink_smem_native_xprt.c +++ b/drivers/soc/qcom/glink_smem_native_xprt.c @@ -33,6 +33,7 @@ #include <linux/spinlock.h> #include <linux/srcu.h> #include <linux/wait.h> +#include <linux/cpumask.h> #include <soc/qcom/smem.h> #include <soc/qcom/tracer_pkt.h> #include "glink_core_if.h" @@ -2299,17 +2300,40 @@ static int subsys_name_to_id(const char *name) return -ENODEV; } +static void glink_set_affinity(struct edge_info *einfo, u32 *arr, size_t size) +{ + struct cpumask cpumask; + pid_t pid; + int i; + + cpumask_clear(&cpumask); + for (i = 0; i < size; i++) { + if (arr[i] < num_possible_cpus()) + cpumask_set_cpu(arr[i], &cpumask); + } + if (irq_set_affinity(einfo->irq_line, &cpumask)) + pr_err("%s: Failed to set irq affinity\n", __func__); + + if (sched_setaffinity(einfo->task->pid, &cpumask)) + pr_err("%s: Failed to set rx cpu affinity\n", __func__); + + pid = einfo->xprt_cfg.tx_task->pid; + if (sched_setaffinity(pid, &cpumask)) + pr_err("%s: Failed to set tx cpu affinity\n", __func__); +} + static int glink_smem_native_probe(struct platform_device *pdev) { struct device_node *node; struct device_node *phandle_node; struct edge_info *einfo; - int rc; + int rc, cpu_size; char *key; const char *subsys_name; uint32_t irq_line; uint32_t irq_mask; struct resource *r; + u32 *cpu_array; node = pdev->dev.of_node; @@ -2456,6 +2480,20 @@ static int glink_smem_native_probe(struct platform_device *pdev) pr_err("%s: enable_irq_wake() failed on %d\n", __func__, irq_line); + key = "cpu-affinity"; + cpu_size = of_property_count_u32_elems(node, key); + if (cpu_size > 0) { + cpu_array = kmalloc_array(cpu_size, sizeof(u32), GFP_KERNEL); + if (!cpu_array) { + rc = -ENOMEM; + goto request_irq_fail; + } + rc = of_property_read_u32_array(node, key, cpu_array, cpu_size); + if (!rc) + glink_set_affinity(einfo, cpu_array, cpu_size); + kfree(cpu_array); + } + register_debugfs_info(einfo); /* fake an interrupt on this edge to see if the remote side is up */ irq_handler(0, einfo); |
