Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/783385/?format=api
{ "id": 783385, "url": "http://patchwork.ozlabs.org/api/patches/783385/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/1499074673-30576-8-git-send-email-anju@linux.vnet.ibm.com/", "project": { "id": 2, "url": "http://patchwork.ozlabs.org/api/projects/2/?format=api", "name": "Linux PPC development", "link_name": "linuxppc-dev", "list_id": "linuxppc-dev.lists.ozlabs.org", "list_email": "linuxppc-dev@lists.ozlabs.org", "web_url": "https://github.com/linuxppc/wiki/wiki", "scm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git", "webscm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/", "list_archive_url": "https://lore.kernel.org/linuxppc-dev/", "list_archive_url_format": "https://lore.kernel.org/linuxppc-dev/{}/", "commit_url_format": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id={}" }, "msgid": "<1499074673-30576-8-git-send-email-anju@linux.vnet.ibm.com>", "list_archive_url": "https://lore.kernel.org/linuxppc-dev/1499074673-30576-8-git-send-email-anju@linux.vnet.ibm.com/", "date": "2017-07-03T09:37:53", "name": "[v12,09/10] powerpc/perf: Thread IMC PMU functions", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "7653c9b92301c0e3af1b52bf0a71c6a550545d70", "submitter": { "id": 67491, "url": "http://patchwork.ozlabs.org/api/people/67491/?format=api", "name": "Anju T Sudhakar", "email": "anju@linux.vnet.ibm.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/1499074673-30576-8-git-send-email-anju@linux.vnet.ibm.com/mbox/", "series": [], "comments": "http://patchwork.ozlabs.org/api/patches/783385/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/783385/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>", "X-Original-To": [ "patchwork-incoming@ozlabs.org", "linuxppc-dev@lists.ozlabs.org" ], "Delivered-To": [ "patchwork-incoming@ozlabs.org", "linuxppc-dev@lists.ozlabs.org" ], "Received": [ "from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3x1Ml9471Wz9rxl\n\tfor <patchwork-incoming@ozlabs.org>;\n\tMon, 3 Jul 2017 19:48:21 +1000 (AEST)", "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3x1Ml93JCRzDrRM\n\tfor <patchwork-incoming@ozlabs.org>;\n\tMon, 3 Jul 2017 19:48:21 +1000 (AEST)", "from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com\n\t[148.163.156.1])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3x1MWm53klzDr8r\n\tfor <linuxppc-dev@lists.ozlabs.org>;\n\tMon, 3 Jul 2017 19:38:28 +1000 (AEST)", "from pps.filterd (m0098396.ppops.net [127.0.0.1])\n\tby mx0a-001b2d01.pphosted.com (8.16.0.20/8.16.0.20) with SMTP id\n\tv639XioT053356\n\tfor <linuxppc-dev@lists.ozlabs.org>; Mon, 3 Jul 2017 05:38:26 -0400", "from e23smtp06.au.ibm.com (e23smtp06.au.ibm.com [202.81.31.148])\n\tby mx0a-001b2d01.pphosted.com with ESMTP id 2bfh29dn9s-1\n\t(version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT)\n\tfor <linuxppc-dev@lists.ozlabs.org>; Mon, 03 Jul 2017 05:38:26 -0400", "from localhost\n\tby e23smtp06.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use\n\tOnly! Violators will be prosecuted\n\tfor <linuxppc-dev@lists.ozlabs.org> from <anju@linux.vnet.ibm.com>;\n\tMon, 3 Jul 2017 19:38:23 +1000", "from d23relay06.au.ibm.com (202.81.31.225)\n\tby e23smtp06.au.ibm.com (202.81.31.212) with IBM ESMTP SMTP Gateway:\n\tAuthorized Use Only! Violators will be prosecuted; \n\tMon, 3 Jul 2017 19:38:20 +1000", "from d23av03.au.ibm.com (d23av03.au.ibm.com [9.190.234.97])\n\tby d23relay06.au.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id\n\tv639cKLM63832168\n\tfor <linuxppc-dev@lists.ozlabs.org>; Mon, 3 Jul 2017 19:38:20 +1000", "from d23av03.au.ibm.com (localhost [127.0.0.1])\n\tby d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id\n\tv639cBGa028571\n\tfor <linuxppc-dev@lists.ozlabs.org>; Mon, 3 Jul 2017 19:38:12 +1000", "from xenial-xerus.in.ibm.com (xenial-xerus.in.ibm.com [9.124.35.20]\n\t(may be forged))\n\tby d23av03.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id\n\tv639bkFU027271; Mon, 3 Jul 2017 19:38:08 +1000" ], "From": "Anju T Sudhakar <anju@linux.vnet.ibm.com>", "To": "mpe@ellerman.id.au", "Subject": "[PATCH v12 09/10] powerpc/perf: Thread IMC PMU functions", "Date": "Mon, 3 Jul 2017 15:07:53 +0530", "X-Mailer": "git-send-email 2.7.4", "In-Reply-To": "<1499074673-30576-1-git-send-email-anju@linux.vnet.ibm.com>", "References": "<1499074673-30576-1-git-send-email-anju@linux.vnet.ibm.com>", "X-TM-AS-MML": "disable", "x-cbid": "17070309-0040-0000-0000-0000033B6D79", "X-IBM-AV-DETECTION": "SAVI=unused REMOTE=unused XFE=unused", "x-cbparentid": "17070309-0041-0000-0000-00000CB69065", "Message-Id": "<1499074673-30576-8-git-send-email-anju@linux.vnet.ibm.com>", "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2017-07-03_06:, , signatures=0", "X-Proofpoint-Spam-Details": "rule=outbound_notspam policy=outbound score=0\n\tspamscore=0 suspectscore=3\n\tmalwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam\n\tadjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000\n\tdefinitions=main-1707030160", "X-BeenThere": "linuxppc-dev@lists.ozlabs.org", "X-Mailman-Version": "2.1.23", "Precedence": "list", "List-Id": "Linux on PowerPC Developers Mail List\n\t<linuxppc-dev.lists.ozlabs.org>", "List-Unsubscribe": "<https://lists.ozlabs.org/options/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>", "List-Archive": "<http://lists.ozlabs.org/pipermail/linuxppc-dev/>", "List-Post": "<mailto:linuxppc-dev@lists.ozlabs.org>", "List-Help": "<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>", "List-Subscribe": "<https://lists.ozlabs.org/listinfo/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>", "Cc": "stewart@linux.vnet.ibm.com, ego@linux.vnet.ibm.com, mikey@neuling.org,\n\tmaddy@linux.vnet.ibm.com, hemant@linux.vnet.ibm.com,\n\tlinux-kernel@vger.kernel.org, eranian@google.com,\n\tanju@linux.vnet.ibm.com, anton@samba.org, sukadev@linux.vnet.ibm.com,\n\tlinuxppc-dev@lists.ozlabs.org, dja@axtens.net", "Errors-To": "linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org", "Sender": "\"Linuxppc-dev\"\n\t<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>" }, "content": "Code to add PMU functions required for event initialization,\nread, update, add, del etc. for thread IMC PMU. Thread IMC PMUs are used\nfor per-task monitoring.\n\nFor each CPU, a page of memory is allocated and is kept static i.e.,\nthese pages will exist till the machine shuts down. The base address of\nthis page is assigned to the ldbar of that cpu. As soon as we do that,\nthe thread IMC counters start running for that cpu and the data of these\ncounters are assigned to the page allocated. But we use this for\nper-task monitoring. Whenever we start monitoring a task, the event is\nadded is onto the task. At that point, we read the initial value of the\nevent. Whenever, we stop monitoring the task, the final value is taken\nand the difference is the event data.\n\nNow, a task can move to a different cpu. Suppose a task X is moving from\ncpu A to cpu B. When the task is scheduled out of A, we get an\nevent_del for A, and hence, the event data is updated. And, we stop\nupdating the X's event data. As soon as X moves on to B, event_add is\ncalled for B, and we again update the event_data. And this is how it\nkeeps on updating the event data even when the task is scheduled on to\ndifferent cpus.\n\nSigned-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>\nSigned-off-by: Hemant Kumar <hemant@linux.vnet.ibm.com>\nSigned-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>\n---\n arch/powerpc/include/asm/imc-pmu.h | 4 +\n arch/powerpc/perf/imc-pmu.c | 241 ++++++++++++++++++++++++++++--\n arch/powerpc/platforms/powernv/opal-imc.c | 2 +\n 3 files changed, 238 insertions(+), 9 deletions(-)", "diff": "diff --git a/arch/powerpc/include/asm/imc-pmu.h b/arch/powerpc/include/asm/imc-pmu.h\nindex e71e0d77d1d7..470301ac806b 100644\n--- a/arch/powerpc/include/asm/imc-pmu.h\n+++ b/arch/powerpc/include/asm/imc-pmu.h\n@@ -44,6 +44,9 @@\n #define IMC_DTB_COMPAT\t\t\t\"ibm,opal-in-memory-counters\"\n #define IMC_DTB_UNIT_COMPAT\t\t\"ibm,imc-counters\"\n \n+#define THREAD_IMC_LDBAR_MASK 0x0003ffffffffe000ULL\n+#define THREAD_IMC_ENABLE 0x8000000000000000ULL\n+\n /*\n * Structure to hold memory address information for imc units.\n */\n@@ -122,4 +125,5 @@ enum {\n extern struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS];\n extern struct imc_pmu *core_imc_pmu;\n extern int init_imc_pmu(struct imc_events *events, int idx, struct imc_pmu *pmu_ptr);\n+void thread_imc_disable(void);\n #endif /* PPC_POWERNV_IMC_PMU_DEF_H */\ndiff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c\nindex c1a275ed2510..bea4dafc2aad 100644\n--- a/arch/powerpc/perf/imc-pmu.c\n+++ b/arch/powerpc/perf/imc-pmu.c\n@@ -18,6 +18,9 @@\n #include <asm/smp.h>\n #include <linux/string.h>\n \n+/* Maintains base address for all the cpus */\n+static DEFINE_PER_CPU(u64 *, thread_imc_mem);\n+\n /* Needed for sanity check */\n struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS];\n static cpumask_t nest_imc_cpumask;\n@@ -33,6 +36,7 @@ static DEFINE_MUTEX(imc_nest_inited_reserve);\n struct imc_pmu_ref *nest_imc_refc;\n struct imc_pmu_ref *core_imc_refc;\n struct imc_pmu *core_imc_pmu;\n+static int thread_imc_mem_size;\n \n struct imc_pmu *imc_event_to_pmu(struct perf_event *event)\n {\n@@ -568,6 +572,137 @@ static int core_imc_event_init(struct perf_event *event)\n \treturn 0;\n }\n \n+static int thread_imc_event_init(struct perf_event *event)\n+{\n+\tint rc, core_id;\n+\tu32 config = event->attr.config;\n+\tstruct task_struct *target;\n+\tstruct imc_pmu *pmu;\n+\tstruct imc_pmu_ref *ref;\n+\n+\tif (event->attr.type != event->pmu->type)\n+\t\treturn -ENOENT;\n+\n+\t/* Sampling not supported */\n+\tif (event->hw.sample_period)\n+\t\treturn -EINVAL;\n+\n+\tevent->hw.idx = -1;\n+\tpmu = imc_event_to_pmu(event);\n+\tcore_id = event->cpu / threads_per_core;\n+\n+\t/* Sanity check for config (event offset and rvalue) */\n+\tif (((config & IMC_EVENT_OFFSET_MASK) > pmu->counter_mem_size) ||\n+\t ((config & IMC_EVENT_RVALUE_MASK) != 0))\n+\t\treturn -EINVAL;\n+\n+\ttarget = event->hw.target;\n+\tif (!target)\n+\t\treturn -EINVAL;\n+\n+\tif (!is_core_imc_mem_inited(event->cpu))\n+\t\treturn -ENODEV;\n+\n+\tevent->pmu->task_ctx_nr = perf_sw_context;\n+\tcore_id = event->cpu / threads_per_core;\n+\n+\t/*\n+\t * Core pmu units are enabled only when it is used.\n+\t * See if this is triggered for the first time.\n+\t * If yes, take the mutex lock and enable the core counters.\n+\t * If not, just increment the count in core_imc_refc struct.\n+\t */\n+\tref = &core_imc_refc[core_id];\n+\tif (!ref)\n+\t\treturn -EINVAL;\n+\n+\tmutex_lock(&ref->lock);\n+\tif (ref->refc == 0) {\n+\t\trc = opal_imc_counters_start(OPAL_IMC_COUNTERS_CORE,\n+\t\t\t\t\t get_hard_smp_processor_id(event->cpu));\n+\t\tif (rc) {\n+\t\t\tmutex_unlock(&ref->lock);\n+\t\t\tpr_err(\"IMC: Unable to start the counters for core %d\\n\", core_id);\n+\t\t\treturn rc;\n+\t\t}\n+\t}\n+\t++ref->refc;\n+\tmutex_unlock(&ref->lock);\n+\n+\tevent->destroy = core_imc_counters_release;\n+\treturn 0;\n+}\n+\n+static void thread_imc_read_counter(struct perf_event *event)\n+{\n+\tu64 *addr, data;\n+\n+\taddr = per_cpu(thread_imc_mem, smp_processor_id()) +\n+\t\t(event->attr.config & IMC_EVENT_OFFSET_MASK);\n+\tdata = __be64_to_cpu(READ_ONCE(*addr));\n+\tlocal64_set(&event->hw.prev_count, data);\n+}\n+\n+static void thread_imc_perf_event_update(struct perf_event *event)\n+{\n+\tu64 counter_prev, counter_new, final_count, *addr;\n+\n+\taddr = per_cpu(thread_imc_mem, smp_processor_id()) +\n+\t\t(event->attr.config & IMC_EVENT_OFFSET_MASK);\n+\tcounter_prev = local64_read(&event->hw.prev_count);\n+\tcounter_new = __be64_to_cpu(READ_ONCE(*addr));\n+\tfinal_count = counter_new - counter_prev;\n+\n+\tlocal64_set(&event->hw.prev_count, counter_new);\n+\tlocal64_add(final_count, &event->count);\n+}\n+\n+static void thread_imc_event_start(struct perf_event *event, int flags)\n+{\n+\tthread_imc_read_counter(event);\n+}\n+\n+static void thread_imc_event_stop(struct perf_event *event, int flags)\n+{\n+\tthread_imc_perf_event_update(event);\n+}\n+\n+static void thread_imc_event_del(struct perf_event *event, int flags)\n+{\n+\tthread_imc_perf_event_update(event);\n+}\n+\n+static int thread_imc_event_add(struct perf_event *event, int flags)\n+{\n+\tthread_imc_event_start(event, flags);\n+\treturn 0;\n+}\n+\n+static void thread_imc_pmu_start_txn(struct pmu *pmu,\n+\t\t\t\t unsigned int txn_flags)\n+{\n+\tif (txn_flags & ~PERF_PMU_TXN_ADD)\n+\t\treturn;\n+\tperf_pmu_disable(pmu);\n+}\n+\n+static void thread_imc_pmu_cancel_txn(struct pmu *pmu)\n+{\n+\tperf_pmu_enable(pmu);\n+}\n+\n+static int thread_imc_pmu_commit_txn(struct pmu *pmu)\n+{\n+\tperf_pmu_enable(pmu);\n+\treturn 0;\n+}\n+\n+static void thread_imc_pmu_sched_task(struct perf_event_context *ctx,\n+\t\t\t\t bool sched_in)\n+{\n+\treturn;\n+}\n+\n static void imc_read_counter(struct perf_event *event)\n {\n \tu64 *addr, data;\n@@ -650,7 +785,27 @@ static int update_pmu_ops(struct imc_pmu *pmu)\n \tpmu->pmu.read = imc_perf_event_update;\n \tpmu->attr_groups[IMC_CPUMASK_ATTR] = &imc_pmu_cpumask_attr_group;\n \tpmu->pmu.attr_groups = pmu->attr_groups;\n+\tif (pmu->domain == IMC_DOMAIN_THREAD) {\n+\t\tpmu->pmu.event_init = thread_imc_event_init;\n+\t\tpmu->pmu.start = thread_imc_event_start;\n+\t\tpmu->pmu.add = thread_imc_event_add;\n+\t\tpmu->pmu.del = thread_imc_event_del;\n+\t\tpmu->pmu.stop = thread_imc_event_stop;\n+\t\tpmu->pmu.read = thread_imc_perf_event_update;\n+\t\tpmu->pmu.start_txn = thread_imc_pmu_start_txn;\n+\t\tpmu->pmu.cancel_txn = thread_imc_pmu_cancel_txn;\n+\t\tpmu->pmu.commit_txn = thread_imc_pmu_commit_txn;\n+\t\tpmu->pmu.sched_task = thread_imc_pmu_sched_task;\n+\t\tpmu->attr_groups[IMC_FORMAT_ATTR] = &core_imc_format_group;\n \n+\t\t/*\n+\t\t * Since thread_imc does not have any CPUMASK attr,\n+\t\t * this may drop the \"events\" attr all together.\n+\t\t * So swap the IMC_EVENT_ATTR slot with IMC_CPUMASK_ATTR.\n+\t\t */\n+\t\tpmu->attr_groups[IMC_CPUMASK_ATTR] = pmu->attr_groups[IMC_EVENT_ATTR];\n+\t\tpmu->attr_groups[IMC_EVENT_ATTR] = NULL;\n+\t}\n \treturn 0;\n }\n \n@@ -748,28 +903,93 @@ static void cleanup_all_core_imc_memory(struct imc_pmu *pmu_ptr)\n }\n \n /*\n+ * Allocates a page of memory for each of the online cpus, and, writes the\n+ * physical base address of that page to the LDBAR for that cpu. This starts\n+ * the thread IMC counters.\n+ */\n+static int thread_imc_mem_alloc(int cpu_id, int size)\n+{\n+\tu64 ldbar_value, *local_mem;\n+\tint phys_id = topology_physical_package_id(cpu_id);\n+\n+\tif (per_cpu(thread_imc_mem, cpu_id) != NULL)\n+\t\treturn 0;\n+\n+\tlocal_mem = page_address(alloc_pages_node(phys_id,\n+\t\t\t\t GFP_KERNEL | __GFP_ZERO | __GFP_THISNODE,\n+\t\t\t\t get_order(size)));\n+\n+\tif (!local_mem)\n+\t\treturn -ENOMEM;\n+\n+\tper_cpu(thread_imc_mem, cpu_id) = local_mem;\n+\n+\tldbar_value = ((u64)local_mem & (u64)THREAD_IMC_LDBAR_MASK) |\n+\t(u64)THREAD_IMC_ENABLE;\n+\n+\tmtspr(SPRN_LDBAR, ldbar_value);\n+\treturn 0;\n+}\n+\n+/*\n * imc_mem_init : Function to support memory allocation for core imc.\n */\n static int imc_mem_init(struct imc_pmu *pmu_ptr)\n {\n-\tint nr_cores;\n+\tint nr_cores, res, cpu;\n \n \tif (pmu_ptr->imc_counter_mmaped)\n \t\treturn 0;\n \n-\tnr_cores = num_present_cpus() / threads_per_core;\n-\tpmu_ptr->mem_info = kzalloc((sizeof(struct imc_mem_info) * nr_cores), GFP_KERNEL);\n-\tif (!pmu_ptr->mem_info)\n-\t\treturn -ENOMEM;\n+\tswitch (pmu_ptr->domain) {\n+\tcase IMC_DOMAIN_CORE:\n+\t\tnr_cores = num_present_cpus() / threads_per_core;\n+\t\tpmu_ptr->mem_info = kzalloc((sizeof(struct imc_mem_info) * nr_cores), GFP_KERNEL);\n+\t\tif (!pmu_ptr->mem_info)\n+\t\t\treturn -ENOMEM;\n \n-\tcore_imc_refc = kzalloc((sizeof(struct imc_pmu_ref) * nr_cores),\n-\t\t\t\t GFP_KERNEL);\n-\tif (!core_imc_refc)\n-\t\treturn -ENOMEM;\n+\t\tcore_imc_refc = kzalloc((sizeof(struct imc_pmu_ref) * nr_cores),\n+\t\t\t\t\t GFP_KERNEL);\n+\t\tif (!core_imc_refc)\n+\t\t\treturn -ENOMEM;\n+\n+\t\tbreak;\n+\tcase IMC_DOMAIN_THREAD:\n+\t\tthread_imc_mem_size = pmu_ptr->counter_mem_size;\n+\t\tfor_each_online_cpu(cpu) {\n+\t\t\tres = thread_imc_mem_alloc(cpu, pmu_ptr->counter_mem_size);\n+\t\t\tif (res)\n+\t\t\t\treturn res;\n+\t\t}\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n \n \treturn 0;\n }\n \n+static void thread_imc_ldbar_disable(void *dummy)\n+{\n+\t/* LDBAR spr is a per-thread */\n+\tmtspr(SPRN_LDBAR, 0);\n+}\n+\n+void thread_imc_disable(void)\n+{\n+\ton_each_cpu(thread_imc_ldbar_disable, NULL, 1);\n+}\n+\n+static void cleanup_all_thread_imc_memory(void)\n+{\n+\tint i;\n+\n+\tfor_each_online_cpu(i) {\n+\t\tif (per_cpu(thread_imc_mem, i))\n+\t\t\tfree_pages((u64)per_cpu(thread_imc_mem, i), 0);\n+\t}\n+}\n+\n /*\n * init_imc_pmu : Setup and register the IMC pmu device.\n *\n@@ -874,5 +1094,8 @@ int init_imc_pmu(struct imc_events *events, int idx,\n \t\tcpuhp_remove_state(CPUHP_AP_PERF_POWERPC_CORE_IMC_ONLINE);\n \t\tcleanup_all_core_imc_memory(pmu_ptr);\n \t}\n+\t/* For thread_imc, we have allocated memory, we need to free it */\n+\tif (pmu_ptr->domain == IMC_DOMAIN_THREAD)\n+\t\tcleanup_all_thread_imc_memory();\n \treturn ret;\n }\ndiff --git a/arch/powerpc/platforms/powernv/opal-imc.c b/arch/powerpc/platforms/powernv/opal-imc.c\nindex 2f857ec826e6..ccb7060bdc18 100644\n--- a/arch/powerpc/platforms/powernv/opal-imc.c\n+++ b/arch/powerpc/platforms/powernv/opal-imc.c\n@@ -545,6 +545,8 @@ static void opal_imc_counters_shutdown(struct platform_device *pdev)\n {\n \t/* Disable the IMC Core functions */\n \tdisable_core_pmu_counters();\n+\t/* Disable the IMC Thread functions */\n+\tthread_imc_disable();\n }\n \n static const struct of_device_id opal_imc_match[] = {\n", "prefixes": [ "v12", "09/10" ] }