Compare commits
No commits in common. "9c129c18a4694f69ead30167ba88991e2692bff4" and "f8a00b125c55bb2718add107fe7c3a84dc6e14f3" have entirely different histories.
9c129c18a4
...
f8a00b125c
File diff suppressed because it is too large
Load Diff
24
0001-PATCH-clang-Don-t-install-static-libraries.patch
Normal file
24
0001-PATCH-clang-Don-t-install-static-libraries.patch
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
From 88704fc2eabb9dd19a9c3eb81a9b3dc37d95651c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Tom Stellard <tstellar@redhat.com>
|
||||||
|
Date: Fri, 31 Jan 2020 11:04:57 -0800
|
||||||
|
Subject: [PATCH][clang] Don't install static libraries
|
||||||
|
|
||||||
|
---
|
||||||
|
clang/cmake/modules/AddClang.cmake | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/clang/cmake/modules/AddClang.cmake b/clang/cmake/modules/AddClang.cmake
|
||||||
|
index 5752f4277444..0f52822d91f0 100644
|
||||||
|
--- a/clang/cmake/modules/AddClang.cmake
|
||||||
|
+++ b/clang/cmake/modules/AddClang.cmake
|
||||||
|
@@ -113,7 +113,7 @@ macro(add_clang_library name)
|
||||||
|
if(TARGET ${lib})
|
||||||
|
target_link_libraries(${lib} INTERFACE ${LLVM_COMMON_LIBS})
|
||||||
|
|
||||||
|
- if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN)
|
||||||
|
+ if (ARG_SHARED AND (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN))
|
||||||
|
get_target_export_arg(${name} Clang export_to_clangtargets UMBRELLA clang-libraries)
|
||||||
|
install(TARGETS ${lib}
|
||||||
|
COMPONENT ${lib}
|
||||||
|
--
|
||||||
|
2.30.2
|
||||||
@ -1,794 +0,0 @@
|
|||||||
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
|
|
||||||
index 7d02dc522..b1194a3fb 100644
|
|
||||||
--- a/fs/nfs/client.c
|
|
||||||
+++ b/fs/nfs/client.c
|
|
||||||
@@ -48,7 +48,7 @@
|
|
||||||
#include "callback.h"
|
|
||||||
#include "delegation.h"
|
|
||||||
#include "iostat.h"
|
|
||||||
-#include "internal.h"
|
|
||||||
+#include "enfs_adapter.h"
|
|
||||||
#include "fscache.h"
|
|
||||||
#include "pnfs.h"
|
|
||||||
#include "nfs.h"
|
|
||||||
@@ -255,6 +255,7 @@ void nfs_free_client(struct nfs_client *clp)
|
|
||||||
put_nfs_version(clp->cl_nfs_mod);
|
|
||||||
kfree(clp->cl_hostname);
|
|
||||||
kfree(clp->cl_acceptor);
|
|
||||||
+ nfs_free_multi_path_client(clp);
|
|
||||||
kfree(clp);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(nfs_free_client);
|
|
||||||
@@ -324,11 +325,26 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
|
|
||||||
continue;
|
|
||||||
/* Match the full socket address */
|
|
||||||
if (!rpc_cmp_addr_port(sap, clap))
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ {
|
|
||||||
+ if (data->enfs_option != NULL)
|
|
||||||
+ continue;
|
|
||||||
+ else {
|
|
||||||
+ if (IS_ERR(clp->cl_rpcclient) ||
|
|
||||||
+ !rpc_clnt_xprt_switch_has_addr(
|
|
||||||
+ clp->cl_rpcclient, sap))
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+#else
|
|
||||||
/* Match all xprt_switch full socket addresses */
|
|
||||||
if (IS_ERR(clp->cl_rpcclient) ||
|
|
||||||
!rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient,
|
|
||||||
sap))
|
|
||||||
continue;
|
|
||||||
+#endif
|
|
||||||
+ if (!nfs_multipath_client_match(clp, data))
|
|
||||||
+ continue;
|
|
||||||
|
|
||||||
refcount_inc(&clp->cl_count);
|
|
||||||
return clp;
|
|
||||||
@@ -512,6 +528,9 @@ int nfs_create_rpc_client(struct nfs_client *clp,
|
|
||||||
.program = &nfs_program,
|
|
||||||
.version = clp->rpc_ops->version,
|
|
||||||
.authflavor = flavor,
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ .multipath_option = cl_init->enfs_option,
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
if (test_bit(NFS_CS_DISCRTRY, &clp->cl_flags))
|
|
||||||
@@ -634,6 +653,13 @@ struct nfs_client *nfs_init_client(struct nfs_client *clp,
|
|
||||||
/* the client is already initialised */
|
|
||||||
if (clp->cl_cons_state == NFS_CS_READY)
|
|
||||||
return clp;
|
|
||||||
+ error = nfs_create_multi_path_client(clp, cl_init);
|
|
||||||
+ if (error < 0) {
|
|
||||||
+ dprintk("%s: create failed.%d!\n", __func__, error);
|
|
||||||
+ nfs_put_client(clp);
|
|
||||||
+ clp = ERR_PTR(error);
|
|
||||||
+ return clp;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a client RPC handle for doing FSSTAT with UNIX auth only
|
|
||||||
@@ -666,6 +692,9 @@ static int nfs_init_server(struct nfs_server *server,
|
|
||||||
.net = data->net,
|
|
||||||
.timeparms = &timeparms,
|
|
||||||
.init_flags = (1UL << NFS_CS_REUSEPORT),
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ .enfs_option = data->enfs_option,
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
struct nfs_client *clp;
|
|
||||||
int error;
|
|
||||||
diff --git a/fs/nfs/enfs_adapter.c b/fs/nfs/enfs_adapter.c
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..e0f3841c1
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/fs/nfs/enfs_adapter.c
|
|
||||||
@@ -0,0 +1,276 @@
|
|
||||||
+// SPDX-License-Identifier: GPL-2.0
|
|
||||||
+/*
|
|
||||||
+ * Client-side ENFS adapter.
|
|
||||||
+ *
|
|
||||||
+ * Copyright (c) 2023. Huawei Technologies Co., Ltd. All rights reserved.
|
|
||||||
+ */
|
|
||||||
+#include <linux/types.h>
|
|
||||||
+#include <linux/sunrpc/clnt.h>
|
|
||||||
+#include <linux/nfs.h>
|
|
||||||
+#include <linux/nfs4.h>
|
|
||||||
+#include <linux/nfs3.h>
|
|
||||||
+#include <linux/nfs_fs.h>
|
|
||||||
+#include <linux/nfs_fs_sb.h>
|
|
||||||
+#include <linux/sunrpc/sched.h>
|
|
||||||
+#include <linux/nfs_iostat.h>
|
|
||||||
+#include "enfs_adapter.h"
|
|
||||||
+#include "iostat.h"
|
|
||||||
+
|
|
||||||
+struct enfs_adapter_ops __rcu *enfs_adapter;
|
|
||||||
+
|
|
||||||
+int enfs_adapter_register(struct enfs_adapter_ops *ops)
|
|
||||||
+{
|
|
||||||
+ struct enfs_adapter_ops *old;
|
|
||||||
+
|
|
||||||
+ old = cmpxchg((struct enfs_adapter_ops **)&enfs_adapter, NULL, ops);
|
|
||||||
+ if (old == NULL || old == ops)
|
|
||||||
+ return 0;
|
|
||||||
+ pr_err("regist %s ops %p failed. old %p\n", __func__, ops, old);
|
|
||||||
+ return -EPERM;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(enfs_adapter_register);
|
|
||||||
+
|
|
||||||
+int enfs_adapter_unregister(struct enfs_adapter_ops *ops)
|
|
||||||
+{
|
|
||||||
+ struct enfs_adapter_ops *old;
|
|
||||||
+
|
|
||||||
+ old = cmpxchg((struct enfs_adapter_ops **)&enfs_adapter, ops, NULL);
|
|
||||||
+ if (old == ops || old == NULL)
|
|
||||||
+ return 0;
|
|
||||||
+ pr_err("unregist %s ops %p failed. old %p\n", __func__, ops, old);
|
|
||||||
+ return -EPERM;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(enfs_adapter_unregister);
|
|
||||||
+
|
|
||||||
+struct enfs_adapter_ops *nfs_multipath_router_get(void)
|
|
||||||
+{
|
|
||||||
+ struct enfs_adapter_ops *ops;
|
|
||||||
+
|
|
||||||
+ rcu_read_lock();
|
|
||||||
+ ops = rcu_dereference(enfs_adapter);
|
|
||||||
+ if (ops == NULL) {
|
|
||||||
+ rcu_read_unlock();
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ if (!try_module_get(ops->owner))
|
|
||||||
+ ops = NULL;
|
|
||||||
+ rcu_read_unlock();
|
|
||||||
+ return ops;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void nfs_multipath_router_put(struct enfs_adapter_ops *ops)
|
|
||||||
+{
|
|
||||||
+ if (ops)
|
|
||||||
+ module_put(ops->owner);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+bool is_valid_option(enum nfs_multi_path_options option)
|
|
||||||
+{
|
|
||||||
+ if (option < REMOTEADDR || option >= INVALID_OPTION) {
|
|
||||||
+ pr_warn("%s: ENFS invalid option %d\n", __func__, option);
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return true;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int enfs_parse_mount_options(enum nfs_multi_path_options option, char *str,
|
|
||||||
+ struct nfs_parsed_mount_data *mnt)
|
|
||||||
+{
|
|
||||||
+ int rc;
|
|
||||||
+ struct enfs_adapter_ops *ops;
|
|
||||||
+
|
|
||||||
+ ops = nfs_multipath_router_get();
|
|
||||||
+ if ((ops == NULL) || (ops->parse_mount_options == NULL) ||
|
|
||||||
+ !is_valid_option(option)) {
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+ dfprintk(MOUNT,
|
|
||||||
+ "NFS: parsing nfs mount option enfs not load[%s]\n"
|
|
||||||
+ , __func__);
|
|
||||||
+ return -EOPNOTSUPP;
|
|
||||||
+ }
|
|
||||||
+ // nfs_multipath_parse_options
|
|
||||||
+ dfprintk(MOUNT, "NFS: parsing nfs mount option '%s' type: %d[%s]\n"
|
|
||||||
+ , str, option, __func__);
|
|
||||||
+ rc = ops->parse_mount_options(option, str, &mnt->enfs_option, mnt->net);
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+ return rc;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void enfs_free_mount_options(struct nfs_parsed_mount_data *data)
|
|
||||||
+{
|
|
||||||
+ struct enfs_adapter_ops *ops;
|
|
||||||
+
|
|
||||||
+ if (data->enfs_option == NULL)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ ops = nfs_multipath_router_get();
|
|
||||||
+ if ((ops == NULL) || (ops->free_mount_options == NULL)) {
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+ ops->free_mount_options((void *)&data->enfs_option);
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int nfs_create_multi_path_client(struct nfs_client *client,
|
|
||||||
+ const struct nfs_client_initdata *cl_init)
|
|
||||||
+{
|
|
||||||
+ int ret = 0;
|
|
||||||
+ struct enfs_adapter_ops *ops;
|
|
||||||
+
|
|
||||||
+ if (cl_init->enfs_option == NULL)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ ops = nfs_multipath_router_get();
|
|
||||||
+ if (ops != NULL && ops->client_info_init != NULL)
|
|
||||||
+ ret = ops->client_info_init(
|
|
||||||
+ (void *)&client->cl_multipath_data, cl_init);
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(nfs_create_multi_path_client);
|
|
||||||
+
|
|
||||||
+void nfs_free_multi_path_client(struct nfs_client *clp)
|
|
||||||
+{
|
|
||||||
+ struct enfs_adapter_ops *ops;
|
|
||||||
+
|
|
||||||
+ if (clp->cl_multipath_data == NULL)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ ops = nfs_multipath_router_get();
|
|
||||||
+ if (ops != NULL && ops->client_info_free != NULL)
|
|
||||||
+ ops->client_info_free(clp->cl_multipath_data);
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int nfs_multipath_client_match(struct nfs_client *clp,
|
|
||||||
+ const struct nfs_client_initdata *sap)
|
|
||||||
+{
|
|
||||||
+ bool ret = true;
|
|
||||||
+ struct enfs_adapter_ops *ops;
|
|
||||||
+
|
|
||||||
+ pr_info("%s src %p dst %p\n.", __func__,
|
|
||||||
+ clp->cl_multipath_data, sap->enfs_option);
|
|
||||||
+
|
|
||||||
+ if (clp->cl_multipath_data == NULL && sap->enfs_option == NULL)
|
|
||||||
+ return true;
|
|
||||||
+
|
|
||||||
+ if ((clp->cl_multipath_data == NULL && sap->enfs_option) ||
|
|
||||||
+ (clp->cl_multipath_data && sap->enfs_option == NULL)) {
|
|
||||||
+ pr_err("not match client src %p dst %p\n.",
|
|
||||||
+ clp->cl_multipath_data, sap->enfs_option);
|
|
||||||
+ return false;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ops = nfs_multipath_router_get();
|
|
||||||
+ if (ops != NULL && ops->client_info_match != NULL)
|
|
||||||
+ ret = ops->client_info_match(clp->cl_multipath_data,
|
|
||||||
+ sap->enfs_option);
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int nfs4_multipath_client_match(struct nfs_client *src, struct nfs_client *dst)
|
|
||||||
+{
|
|
||||||
+ int ret = true;
|
|
||||||
+ struct enfs_adapter_ops *ops;
|
|
||||||
+
|
|
||||||
+ if (src->cl_multipath_data == NULL && dst->cl_multipath_data == NULL)
|
|
||||||
+ return true;
|
|
||||||
+
|
|
||||||
+ if (src->cl_multipath_data == NULL || dst->cl_multipath_data == NULL)
|
|
||||||
+ return false;
|
|
||||||
+
|
|
||||||
+ ops = nfs_multipath_router_get();
|
|
||||||
+ if (ops != NULL && ops->nfs4_client_info_match != NULL)
|
|
||||||
+ ret = ops->nfs4_client_info_match(src->cl_multipath_data,
|
|
||||||
+ src->cl_multipath_data);
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(nfs4_multipath_client_match);
|
|
||||||
+
|
|
||||||
+void nfs_multipath_show_client_info(struct seq_file *mount_option,
|
|
||||||
+ struct nfs_server *server)
|
|
||||||
+{
|
|
||||||
+ struct enfs_adapter_ops *ops;
|
|
||||||
+
|
|
||||||
+ if (mount_option == NULL || server == NULL ||
|
|
||||||
+ server->client == NULL ||
|
|
||||||
+ server->nfs_client->cl_multipath_data == NULL)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ ops = nfs_multipath_router_get();
|
|
||||||
+ if (ops != NULL && ops->client_info_show != NULL)
|
|
||||||
+ ops->client_info_show(mount_option, server);
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int nfs_remount_iplist(struct nfs_client *nfs_client, void *data)
|
|
||||||
+{
|
|
||||||
+ int ret = 0;
|
|
||||||
+ struct enfs_adapter_ops *ops;
|
|
||||||
+ struct nfs_parsed_mount_data *parsed_data =
|
|
||||||
+ (struct nfs_parsed_mount_data *)data;
|
|
||||||
+
|
|
||||||
+ if (!parsed_data->enfs_option)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ if (nfs_client == NULL || nfs_client->cl_rpcclient == NULL)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ ops = nfs_multipath_router_get();
|
|
||||||
+ if (ops != NULL && ops->remount_ip_list != NULL)
|
|
||||||
+ ret = ops->remount_ip_list(nfs_client,
|
|
||||||
+ parsed_data->enfs_option);
|
|
||||||
+ nfs_multipath_router_put(ops);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(nfs_remount_iplist);
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * Error-check and convert a string of mount options from
|
|
||||||
+ * user space into a data structure. The whole mount string
|
|
||||||
+ * is processed; bad options are skipped as they are encountered.
|
|
||||||
+ * If there were no errors, return 1; otherwise return zero(0)
|
|
||||||
+ */
|
|
||||||
+int enfs_check_mount_parse_info(char *p, int token,
|
|
||||||
+ struct nfs_parsed_mount_data *mnt, const substring_t *args)
|
|
||||||
+{
|
|
||||||
+ char *string;
|
|
||||||
+ int rc;
|
|
||||||
+
|
|
||||||
+ string = match_strdup(args);
|
|
||||||
+ if (string == NULL) {
|
|
||||||
+ pr_info("NFS: not enough memory to parse option\n");
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ rc = enfs_parse_mount_options(get_nfs_multi_path_opt(token),
|
|
||||||
+ string, mnt);
|
|
||||||
+
|
|
||||||
+ kfree(string);
|
|
||||||
+ switch (rc) {
|
|
||||||
+ case 0:
|
|
||||||
+ return 1;
|
|
||||||
+ case -ENOMEM:
|
|
||||||
+ pr_info("NFS: not enough memory to parse option\n");
|
|
||||||
+ return 0;
|
|
||||||
+ case -ENOSPC:
|
|
||||||
+ pr_info("NFS: param is more than supported limit: %d\n", rc);
|
|
||||||
+ return 0;
|
|
||||||
+ case -EINVAL:
|
|
||||||
+ pr_info("NFS: bad IP address specified: %s\n", p);
|
|
||||||
+ return 0;
|
|
||||||
+ case -ENOTSUPP:
|
|
||||||
+ pr_info("NFS: bad IP address specified: %s\n", p);
|
|
||||||
+ return 0;
|
|
||||||
+ case -EOPNOTSUPP:
|
|
||||||
+ pr_info("NFS: bad IP address specified: %s\n", p);
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
diff --git a/fs/nfs/enfs_adapter.h b/fs/nfs/enfs_adapter.h
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000..98b4e3292
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/fs/nfs/enfs_adapter.h
|
|
||||||
@@ -0,0 +1,116 @@
|
|
||||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
+/*
|
|
||||||
+ * Client-side ENFS adapt header.
|
|
||||||
+ *
|
|
||||||
+ * Copyright (c) 2023. Huawei Technologies Co., Ltd. All rights reserved.
|
|
||||||
+ */
|
|
||||||
+#ifndef _NFS_MULTIPATH_H_
|
|
||||||
+#define _NFS_MULTIPATH_H_
|
|
||||||
+
|
|
||||||
+#include <linux/parser.h>
|
|
||||||
+#include "internal.h"
|
|
||||||
+
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+enum nfs_multi_path_options {
|
|
||||||
+ REMOTEADDR,
|
|
||||||
+ LOCALADDR,
|
|
||||||
+ REMOTEDNSNAME,
|
|
||||||
+ REMOUNTREMOTEADDR,
|
|
||||||
+ REMOUNTLOCALADDR,
|
|
||||||
+ INVALID_OPTION
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+struct enfs_adapter_ops {
|
|
||||||
+ const char *name;
|
|
||||||
+ struct module *owner;
|
|
||||||
+ int (*parse_mount_options)(enum nfs_multi_path_options option,
|
|
||||||
+ char *str, void **enfs_option, struct net *net_ns);
|
|
||||||
+
|
|
||||||
+ void (*free_mount_options)(void **data);
|
|
||||||
+
|
|
||||||
+ int (*client_info_init)(void **data,
|
|
||||||
+ const struct nfs_client_initdata *cl_init);
|
|
||||||
+ void (*client_info_free)(void *data);
|
|
||||||
+ int (*client_info_match)(void *src, void *dst);
|
|
||||||
+ int (*nfs4_client_info_match)(void *src, void *dst);
|
|
||||||
+ void (*client_info_show)(struct seq_file *mount_option, void *data);
|
|
||||||
+ int (*remount_ip_list)(struct nfs_client *nfs_client,
|
|
||||||
+ void *enfs_option);
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+int enfs_parse_mount_options(enum nfs_multi_path_options option, char *str,
|
|
||||||
+ struct nfs_parsed_mount_data *mnt);
|
|
||||||
+void enfs_free_mount_options(struct nfs_parsed_mount_data *data);
|
|
||||||
+int nfs_create_multi_path_client(struct nfs_client *client,
|
|
||||||
+ const struct nfs_client_initdata *cl_init);
|
|
||||||
+void nfs_free_multi_path_client(struct nfs_client *clp);
|
|
||||||
+int nfs_multipath_client_match(struct nfs_client *clp,
|
|
||||||
+ const struct nfs_client_initdata *sap);
|
|
||||||
+int nfs4_multipath_client_match(struct nfs_client *src, struct nfs_client *dst);
|
|
||||||
+void nfs_multipath_show_client_info(struct seq_file *mount_option,
|
|
||||||
+ struct nfs_server *server);
|
|
||||||
+int enfs_adapter_register(struct enfs_adapter_ops *ops);
|
|
||||||
+int enfs_adapter_unregister(struct enfs_adapter_ops *ops);
|
|
||||||
+int nfs_remount_iplist(struct nfs_client *nfs_client, void *data);
|
|
||||||
+int nfs4_create_multi_path(struct nfs_server *server,
|
|
||||||
+ struct nfs_parsed_mount_data *data,
|
|
||||||
+ const struct rpc_timeout *timeparms);
|
|
||||||
+int enfs_check_mount_parse_info(char *p, int token,
|
|
||||||
+ struct nfs_parsed_mount_data *mnt, const substring_t *args);
|
|
||||||
+
|
|
||||||
+#else
|
|
||||||
+static inline
|
|
||||||
+void nfs_free_multi_path_client(struct nfs_client *clp)
|
|
||||||
+{
|
|
||||||
+
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline
|
|
||||||
+int nfs_multipath_client_match(struct nfs_client *clp,
|
|
||||||
+ const struct nfs_client_initdata *sap)
|
|
||||||
+{
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline
|
|
||||||
+int nfs_create_multi_path_client(struct nfs_client *client,
|
|
||||||
+ const struct nfs_client_initdata *cl_init)
|
|
||||||
+{
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline
|
|
||||||
+void nfs_multipath_show_client_info(struct seq_file *mount_option,
|
|
||||||
+ struct nfs_server *server)
|
|
||||||
+{
|
|
||||||
+
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline
|
|
||||||
+int nfs4_multipath_client_match(struct nfs_client *src,
|
|
||||||
+ struct nfs_client *dst)
|
|
||||||
+{
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline
|
|
||||||
+void enfs_free_mount_options(struct nfs_parsed_mount_data *data)
|
|
||||||
+{
|
|
||||||
+
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline
|
|
||||||
+int enfs_check_mount_parse_info(char *p, int token,
|
|
||||||
+ struct nfs_parsed_mount_data *mnt, const substring_t *args)
|
|
||||||
+{
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline
|
|
||||||
+int nfs_remount_iplist(struct nfs_client *nfs_client, void *data)
|
|
||||||
+{
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+#endif // CONFIG_ENFS
|
|
||||||
+#endif // _NFS_MULTIPATH_H_
|
|
||||||
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
|
|
||||||
index 0ce5a9064..84ac82dbb 100644
|
|
||||||
--- a/fs/nfs/internal.h
|
|
||||||
+++ b/fs/nfs/internal.h
|
|
||||||
@@ -93,6 +93,9 @@ struct nfs_client_initdata {
|
|
||||||
u32 minorversion;
|
|
||||||
struct net *net;
|
|
||||||
const struct rpc_timeout *timeparms;
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ void *enfs_option; /* struct multipath_mount_options * */
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -135,6 +138,9 @@ struct nfs_parsed_mount_data {
|
|
||||||
|
|
||||||
struct security_mnt_opts lsm_opts;
|
|
||||||
struct net *net;
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ void *enfs_option; /* struct multipath_mount_options * */
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/* mount_clnt.c */
|
|
||||||
@@ -430,6 +436,10 @@ extern void nfs_sb_deactive(struct super_block *sb);
|
|
||||||
extern int nfs_client_for_each_server(struct nfs_client *clp,
|
|
||||||
int (*fn)(struct nfs_server *, void *),
|
|
||||||
void *data);
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+extern enum nfs_multi_path_options get_nfs_multi_path_opt(int token);
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
/* io.c */
|
|
||||||
extern void nfs_start_io_read(struct inode *inode);
|
|
||||||
extern void nfs_end_io_read(struct inode *inode);
|
|
||||||
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
|
|
||||||
index 1350ea673..f97646b98 100644
|
|
||||||
--- a/fs/nfs/nfs4client.c
|
|
||||||
+++ b/fs/nfs/nfs4client.c
|
|
||||||
@@ -10,7 +10,7 @@
|
|
||||||
#include <linux/sunrpc/xprt.h>
|
|
||||||
#include <linux/sunrpc/bc_xprt.h>
|
|
||||||
#include <linux/sunrpc/rpc_pipe_fs.h>
|
|
||||||
-#include "internal.h"
|
|
||||||
+#include "enfs_adapter.h"
|
|
||||||
#include "callback.h"
|
|
||||||
#include "delegation.h"
|
|
||||||
#include "nfs4session.h"
|
|
||||||
@@ -225,6 +225,14 @@ struct nfs_client *nfs4_alloc_client(const struct nfs_client_initdata *cl_init)
|
|
||||||
__set_bit(NFS_CS_DISCRTRY, &clp->cl_flags);
|
|
||||||
__set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags);
|
|
||||||
|
|
||||||
+ err = nfs_create_multi_path_client(clp, cl_init);
|
|
||||||
+ if (err < 0) {
|
|
||||||
+ dprintk("%s: create failed.%d\n", __func__, err);
|
|
||||||
+ nfs_put_client(clp);
|
|
||||||
+ clp = ERR_PTR(err);
|
|
||||||
+ return clp;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Set up the connection to the server before we add add to the
|
|
||||||
* global list.
|
|
||||||
@@ -529,6 +537,9 @@ static int nfs4_match_client(struct nfs_client *pos, struct nfs_client *new,
|
|
||||||
if (!nfs4_match_client_owner_id(pos, new))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
+ if (!nfs4_multipath_client_match(pos, new))
|
|
||||||
+ return 1;
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -860,7 +871,7 @@ static int nfs4_set_client(struct nfs_server *server,
|
|
||||||
const size_t addrlen,
|
|
||||||
const char *ip_addr,
|
|
||||||
int proto, const struct rpc_timeout *timeparms,
|
|
||||||
- u32 minorversion, struct net *net)
|
|
||||||
+ u32 minorversion, struct net *net, void *enfs_option)
|
|
||||||
{
|
|
||||||
struct nfs_client_initdata cl_init = {
|
|
||||||
.hostname = hostname,
|
|
||||||
@@ -872,6 +883,9 @@ static int nfs4_set_client(struct nfs_server *server,
|
|
||||||
.minorversion = minorversion,
|
|
||||||
.net = net,
|
|
||||||
.timeparms = timeparms,
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ .enfs_option = enfs_option,
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
struct nfs_client *clp;
|
|
||||||
|
|
||||||
@@ -1050,6 +1064,7 @@ static int nfs4_init_server(struct nfs_server *server,
|
|
||||||
{
|
|
||||||
struct rpc_timeout timeparms;
|
|
||||||
int error;
|
|
||||||
+ void *enfs_option = NULL;
|
|
||||||
|
|
||||||
nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
|
|
||||||
data->timeo, data->retrans);
|
|
||||||
@@ -1067,6 +1082,10 @@ static int nfs4_init_server(struct nfs_server *server,
|
|
||||||
else
|
|
||||||
data->selected_flavor = RPC_AUTH_UNIX;
|
|
||||||
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ enfs_option = data->enfs_option;
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
/* Get a client record */
|
|
||||||
error = nfs4_set_client(server,
|
|
||||||
data->nfs_server.hostname,
|
|
||||||
@@ -1076,7 +1095,7 @@ static int nfs4_init_server(struct nfs_server *server,
|
|
||||||
data->nfs_server.protocol,
|
|
||||||
&timeparms,
|
|
||||||
data->minorversion,
|
|
||||||
- data->net);
|
|
||||||
+ data->net, enfs_option);
|
|
||||||
if (error < 0)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
@@ -1161,7 +1180,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
|
|
||||||
XPRT_TRANSPORT_RDMA,
|
|
||||||
parent_server->client->cl_timeout,
|
|
||||||
parent_client->cl_mvops->minor_version,
|
|
||||||
- parent_client->cl_net);
|
|
||||||
+ parent_client->cl_net, NULL);
|
|
||||||
if (!error)
|
|
||||||
goto init_server;
|
|
||||||
#endif /* IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA) */
|
|
||||||
@@ -1174,7 +1193,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
|
|
||||||
XPRT_TRANSPORT_TCP,
|
|
||||||
parent_server->client->cl_timeout,
|
|
||||||
parent_client->cl_mvops->minor_version,
|
|
||||||
- parent_client->cl_net);
|
|
||||||
+ parent_client->cl_net, NULL);
|
|
||||||
if (error < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
@@ -1269,7 +1288,7 @@ int nfs4_update_server(struct nfs_server *server, const char *hostname,
|
|
||||||
set_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
|
|
||||||
error = nfs4_set_client(server, hostname, sap, salen, buf,
|
|
||||||
clp->cl_proto, clnt->cl_timeout,
|
|
||||||
- clp->cl_minorversion, net);
|
|
||||||
+ clp->cl_minorversion, net, NULL);
|
|
||||||
clear_bit(NFS_MIG_TSM_POSSIBLE, &server->mig_status);
|
|
||||||
if (error != 0) {
|
|
||||||
nfs_server_insert_lists(server);
|
|
||||||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
|
|
||||||
index a05e1eb2c..168da9700 100644
|
|
||||||
--- a/fs/nfs/super.c
|
|
||||||
+++ b/fs/nfs/super.c
|
|
||||||
@@ -51,7 +51,6 @@
|
|
||||||
#include <linux/netdevice.h>
|
|
||||||
#include <linux/nfs_xdr.h>
|
|
||||||
#include <linux/magic.h>
|
|
||||||
-#include <linux/parser.h>
|
|
||||||
#include <linux/nsproxy.h>
|
|
||||||
#include <linux/rcupdate.h>
|
|
||||||
|
|
||||||
@@ -61,7 +60,7 @@
|
|
||||||
#include "callback.h"
|
|
||||||
#include "delegation.h"
|
|
||||||
#include "iostat.h"
|
|
||||||
-#include "internal.h"
|
|
||||||
+#include "enfs_adapter.h"
|
|
||||||
#include "fscache.h"
|
|
||||||
#include "nfs4session.h"
|
|
||||||
#include "pnfs.h"
|
|
||||||
@@ -113,6 +112,12 @@ enum {
|
|
||||||
|
|
||||||
/* Special mount options */
|
|
||||||
Opt_userspace, Opt_deprecated, Opt_sloppy,
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ Opt_remote_iplist,
|
|
||||||
+ Opt_local_iplist,
|
|
||||||
+ Opt_remote_dnslist,
|
|
||||||
+ Opt_enfs_info,
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
Opt_err
|
|
||||||
};
|
|
||||||
@@ -183,6 +188,13 @@ static const match_table_t nfs_mount_option_tokens = {
|
|
||||||
{ Opt_fscache_uniq, "fsc=%s" },
|
|
||||||
{ Opt_local_lock, "local_lock=%s" },
|
|
||||||
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ { Opt_remote_iplist, "remoteaddrs=%s" },
|
|
||||||
+ { Opt_local_iplist, "localaddrs=%s" },
|
|
||||||
+ { Opt_remote_dnslist, "remotednsname=%s" },
|
|
||||||
+ { Opt_enfs_info, "enfs_info=%s" },
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
/* The following needs to be listed after all other options */
|
|
||||||
{ Opt_nfsvers, "v%s" },
|
|
||||||
|
|
||||||
@@ -365,6 +377,21 @@ static struct shrinker acl_shrinker = {
|
|
||||||
.seeks = DEFAULT_SEEKS,
|
|
||||||
};
|
|
||||||
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+enum nfs_multi_path_options get_nfs_multi_path_opt(int token)
|
|
||||||
+{
|
|
||||||
+ switch (token) {
|
|
||||||
+ case Opt_remote_iplist:
|
|
||||||
+ return REMOUNTREMOTEADDR;
|
|
||||||
+ case Opt_local_iplist:
|
|
||||||
+ return REMOUNTLOCALADDR;
|
|
||||||
+ case Opt_remote_dnslist:
|
|
||||||
+ return REMOTEDNSNAME;
|
|
||||||
+ }
|
|
||||||
+ return INVALID_OPTION;
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Register the NFS filesystems
|
|
||||||
*/
|
|
||||||
@@ -758,6 +785,9 @@ int nfs_show_options(struct seq_file *m, struct dentry *root)
|
|
||||||
seq_printf(m, ",addr=%s",
|
|
||||||
rpc_peeraddr2str(nfss->nfs_client->cl_rpcclient,
|
|
||||||
RPC_DISPLAY_ADDR));
|
|
||||||
+
|
|
||||||
+ nfs_multipath_show_client_info(m, nfss);
|
|
||||||
+
|
|
||||||
rcu_read_unlock();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
@@ -853,6 +883,8 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
|
|
||||||
seq_puts(m, root->d_sb->s_flags & SB_NODIRATIME ? ",nodiratime" : "");
|
|
||||||
nfs_show_mount_options(m, nfss, 1);
|
|
||||||
|
|
||||||
+ nfs_multipath_show_client_info(m, nfss);
|
|
||||||
+
|
|
||||||
seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
|
|
||||||
|
|
||||||
show_implementation_id(m, nfss);
|
|
||||||
@@ -977,6 +1009,7 @@ static void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data)
|
|
||||||
kfree(data->nfs_server.export_path);
|
|
||||||
kfree(data->nfs_server.hostname);
|
|
||||||
kfree(data->fscache_uniq);
|
|
||||||
+ enfs_free_mount_options(data);
|
|
||||||
security_free_mnt_opts(&data->lsm_opts);
|
|
||||||
kfree(data);
|
|
||||||
}
|
|
||||||
@@ -1641,7 +1674,6 @@ static int nfs_parse_mount_options(char *raw,
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Special options
|
|
||||||
*/
|
|
||||||
@@ -1654,7 +1686,18 @@ static int nfs_parse_mount_options(char *raw,
|
|
||||||
dfprintk(MOUNT, "NFS: ignoring mount option "
|
|
||||||
"'%s'\n", p);
|
|
||||||
break;
|
|
||||||
-
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ case Opt_remote_iplist:
|
|
||||||
+ case Opt_local_iplist:
|
|
||||||
+ case Opt_remote_dnslist:
|
|
||||||
+ rc = enfs_check_mount_parse_info(p,
|
|
||||||
+ token, mnt, args);
|
|
||||||
+ if (rc != 1)
|
|
||||||
+ return rc;
|
|
||||||
+ break;
|
|
||||||
+ case Opt_enfs_info:
|
|
||||||
+ break;
|
|
||||||
+#endif
|
|
||||||
default:
|
|
||||||
invalid_option = 1;
|
|
||||||
dfprintk(MOUNT, "NFS: unrecognized mount option "
|
|
||||||
@@ -2335,6 +2378,10 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
|
|
||||||
if (!nfs_parse_mount_options((char *)options, data))
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
+ error = nfs_remount_iplist(nfss->nfs_client, data);
|
|
||||||
+ if (error)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* noac is a special case. It implies -o sync, but that's not
|
|
||||||
* necessarily reflected in the mtab options. do_remount_sb
|
|
||||||
@@ -2347,6 +2394,8 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
|
|
||||||
/* compare new mount options with old ones */
|
|
||||||
error = nfs_compare_remount_data(nfss, data);
|
|
||||||
out:
|
|
||||||
+ /* release remount option member */
|
|
||||||
+ enfs_free_mount_options(data);
|
|
||||||
nfs_free_parsed_mount_data(data);
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
|
|
||||||
index 7023ae64e..2c19678af 100644
|
|
||||||
--- a/include/linux/nfs_fs_sb.h
|
|
||||||
+++ b/include/linux/nfs_fs_sb.h
|
|
||||||
@@ -123,6 +123,11 @@ struct nfs_client {
|
|
||||||
|
|
||||||
struct net *cl_net;
|
|
||||||
struct list_head pending_cb_stateids;
|
|
||||||
+
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ /* multi path private structure (struct multipath_client_info *) */
|
|
||||||
+ void *cl_multipath_data;
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
29
0002-Always-build-shared-libs-for-LLD.patch
Normal file
29
0002-Always-build-shared-libs-for-LLD.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From b1c60d7fa322a2d208556087df9e7ef94bfbffb8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nikita Popov <npopov@redhat.com>
|
||||||
|
Date: Wed, 8 May 2024 12:30:36 +0900
|
||||||
|
Subject: [PATCH] Always build shared libs for LLD
|
||||||
|
|
||||||
|
We don't want to enable BUILD_SHARED_LIBS for the whole build,
|
||||||
|
but we do want to build lld libraries.
|
||||||
|
---
|
||||||
|
lld/cmake/modules/AddLLD.cmake | 5 ++---
|
||||||
|
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lld/cmake/modules/AddLLD.cmake b/lld/cmake/modules/AddLLD.cmake
|
||||||
|
index 2ee066b41535..270c03f096ac 100644
|
||||||
|
--- a/lld/cmake/modules/AddLLD.cmake
|
||||||
|
+++ b/lld/cmake/modules/AddLLD.cmake
|
||||||
|
@@ -7,9 +7,8 @@ macro(add_lld_library name)
|
||||||
|
""
|
||||||
|
""
|
||||||
|
${ARGN})
|
||||||
|
- if(ARG_SHARED)
|
||||||
|
- set(ARG_ENABLE_SHARED SHARED)
|
||||||
|
- endif()
|
||||||
|
+ # Always build shared libs for LLD.
|
||||||
|
+ set(ARG_ENABLE_SHARED SHARED)
|
||||||
|
llvm_add_library(${name} ${ARG_ENABLE_SHARED} ${ARG_UNPARSED_ARGUMENTS})
|
||||||
|
set_target_properties(${name} PROPERTIES FOLDER "lld libraries")
|
||||||
|
|
||||||
|
--
|
||||||
|
2.44.0
|
||||||
@ -1,835 +0,0 @@
|
|||||||
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
|
|
||||||
index 5803a6891b30..eadfe3274a99 100644
|
|
||||||
--- a/include/linux/sunrpc/clnt.h
|
|
||||||
+++ b/include/linux/sunrpc/clnt.h
|
|
||||||
@@ -71,6 +71,10 @@ struct rpc_clnt {
|
|
||||||
#endif
|
|
||||||
struct rpc_xprt_iter cl_xpi;
|
|
||||||
struct super_block *pipefs_sb;
|
|
||||||
+
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ bool cl_enfs;
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -125,6 +129,9 @@ struct rpc_create_args {
|
|
||||||
unsigned long flags;
|
|
||||||
char *client_name;
|
|
||||||
struct svc_xprt *bc_xprt; /* NFSv4.1 backchannel */
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ void *multipath_option;
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rpc_add_xprt_test {
|
|
||||||
@@ -222,6 +229,13 @@ bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
|
|
||||||
const struct sockaddr *sap);
|
|
||||||
void rpc_cleanup_clids(void);
|
|
||||||
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+int
|
|
||||||
+rpc_clnt_test_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
|
|
||||||
+ const struct rpc_call_ops *ops, void *data, int flags);
|
|
||||||
+struct rpc_xprt *rpc_task_get_next_xprt(struct rpc_clnt *clnt);
|
|
||||||
+#endif /* CONFIG_ENFS */
|
|
||||||
+
|
|
||||||
static inline int rpc_reply_expected(struct rpc_task *task)
|
|
||||||
{
|
|
||||||
return (task->tk_msg.rpc_proc != NULL) &&
|
|
||||||
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
|
|
||||||
index ad2e243f3f03..124f5a0faf3e 100644
|
|
||||||
--- a/include/linux/sunrpc/sched.h
|
|
||||||
+++ b/include/linux/sunrpc/sched.h
|
|
||||||
@@ -90,6 +90,9 @@ struct rpc_task {
|
|
||||||
tk_garb_retry : 2,
|
|
||||||
tk_cred_retry : 2,
|
|
||||||
tk_rebind_retry : 2;
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ unsigned long tk_major_timeo; /* major timeout ticks */
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*rpc_action)(struct rpc_task *);
|
|
||||||
@@ -118,6 +121,9 @@ struct rpc_task_setup {
|
|
||||||
*/
|
|
||||||
#define RPC_TASK_ASYNC 0x0001 /* is an async task */
|
|
||||||
#define RPC_TASK_SWAPPER 0x0002 /* is swapping in/out */
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+#define RPC_TASK_FIXED 0x0004 /* detect xprt status task */
|
|
||||||
+#endif
|
|
||||||
#define RPC_CALL_MAJORSEEN 0x0020 /* major timeout seen */
|
|
||||||
#define RPC_TASK_ROOTCREDS 0x0040 /* force root creds */
|
|
||||||
#define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */
|
|
||||||
@@ -257,6 +263,9 @@ void rpc_destroy_mempool(void);
|
|
||||||
extern struct workqueue_struct *rpciod_workqueue;
|
|
||||||
extern struct workqueue_struct *xprtiod_workqueue;
|
|
||||||
void rpc_prepare_task(struct rpc_task *task);
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+void rpc_init_task_retry_counters(struct rpc_task *task);
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
static inline int rpc_wait_for_completion_task(struct rpc_task *task)
|
|
||||||
{
|
|
||||||
diff --git a/include/linux/sunrpc/sunrpc_enfs_adapter.h b/include/linux/sunrpc/sunrpc_enfs_adapter.h
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..cdd7fa699db2
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/include/linux/sunrpc/sunrpc_enfs_adapter.h
|
|
||||||
@@ -0,0 +1,135 @@
|
|
||||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
|
||||||
+/* Client-side SUNRPC ENFS adapter header.
|
|
||||||
+ * Copyright (c) 2023. Huawei Technologies Co., Ltd. All rights reserved.
|
|
||||||
+ */
|
|
||||||
+#ifndef _SUNRPC_ENFS_ADAPTER_H_
|
|
||||||
+#define _SUNRPC_ENFS_ADAPTER_H_
|
|
||||||
+#include <linux/sunrpc/clnt.h>
|
|
||||||
+
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+
|
|
||||||
+static inline void rpc_xps_nactive_add_one(struct rpc_xprt_switch *xps)
|
|
||||||
+{
|
|
||||||
+ xps->xps_nactive--;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void rpc_xps_nactive_sub_one(struct rpc_xprt_switch *xps)
|
|
||||||
+{
|
|
||||||
+ xps->xps_nactive--;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+struct rpc_xprt *rpc_task_get_xprt
|
|
||||||
+(struct rpc_clnt *clnt, struct rpc_xprt *xprt);
|
|
||||||
+
|
|
||||||
+struct rpc_multipath_ops {
|
|
||||||
+ struct module *owner;
|
|
||||||
+ void (*create_clnt)(struct rpc_create_args *args,
|
|
||||||
+ struct rpc_clnt *clnt);
|
|
||||||
+ void (*releas_clnt)(struct rpc_clnt *clnt);
|
|
||||||
+ void (*create_xprt)(struct rpc_xprt *xprt);
|
|
||||||
+ void (*destroy_xprt)(struct rpc_xprt *xprt);
|
|
||||||
+ void (*xprt_iostat)(struct rpc_task *task);
|
|
||||||
+ void (*failover_handle)(struct rpc_task *task);
|
|
||||||
+ bool (*task_need_call_start_again)(struct rpc_task *task);
|
|
||||||
+ void (*adjust_task_timeout)(struct rpc_task *task, void *condition);
|
|
||||||
+ void (*init_task_req)(struct rpc_task *task, struct rpc_rqst *req);
|
|
||||||
+ bool (*prepare_transmit)(struct rpc_task *task);
|
|
||||||
+ void (*set_transport)(struct rpc_task *task, struct rpc_clnt *clnt);
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+extern struct rpc_multipath_ops __rcu *multipath_ops;
|
|
||||||
+void rpc_init_task_retry_counters(struct rpc_task *task);
|
|
||||||
+int rpc_multipath_ops_register(struct rpc_multipath_ops *ops);
|
|
||||||
+int rpc_multipath_ops_unregister(struct rpc_multipath_ops *ops);
|
|
||||||
+struct rpc_multipath_ops *rpc_multipath_ops_get(void);
|
|
||||||
+void rpc_multipath_ops_put(struct rpc_multipath_ops *ops);
|
|
||||||
+void rpc_task_release_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt);
|
|
||||||
+void rpc_multipath_ops_create_clnt(struct rpc_create_args *args,
|
|
||||||
+ struct rpc_clnt *clnt);
|
|
||||||
+void rpc_multipath_ops_releas_clnt(struct rpc_clnt *clnt);
|
|
||||||
+bool rpc_multipath_ops_create_xprt(struct rpc_xprt *xprt);
|
|
||||||
+void rpc_multipath_ops_destroy_xprt(struct rpc_xprt *xprt);
|
|
||||||
+void rpc_multipath_ops_xprt_iostat(struct rpc_task *task);
|
|
||||||
+void rpc_multipath_ops_failover_handle(struct rpc_task *task);
|
|
||||||
+bool rpc_multipath_ops_task_need_call_start_again(struct rpc_task *task);
|
|
||||||
+void rpc_multipath_ops_adjust_task_timeout(struct rpc_task *task,
|
|
||||||
+ void *condition);
|
|
||||||
+void rpc_multipath_ops_init_task_req(struct rpc_task *task,
|
|
||||||
+ struct rpc_rqst *req);
|
|
||||||
+bool rpc_multipath_ops_prepare_transmit(struct rpc_task *task);
|
|
||||||
+void rpc_multipath_ops_set_transport(struct rpc_task *task,
|
|
||||||
+ struct rpc_clnt *clnt);
|
|
||||||
+#else
|
|
||||||
+static inline struct rpc_xprt *rpc_task_get_xprt(struct rpc_clnt *clnt,
|
|
||||||
+ struct rpc_xprt *xprt)
|
|
||||||
+{
|
|
||||||
+ return NULL;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void rpc_task_release_xprt(struct rpc_clnt *clnt,
|
|
||||||
+ struct rpc_xprt *xprt)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void rpc_xps_nactive_add_one(struct rpc_xprt_switch *xps)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void rpc_xps_nactive_sub_one(struct rpc_xprt_switch *xps)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void rpc_multipath_ops_create_clnt
|
|
||||||
+(struct rpc_create_args *args, struct rpc_clnt *clnt)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void rpc_multipath_ops_releas_clnt(struct rpc_clnt *clnt)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline bool rpc_multipath_ops_create_xprt(struct rpc_xprt *xprt)
|
|
||||||
+{
|
|
||||||
+ return false;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void rpc_multipath_ops_destroy_xprt(struct rpc_xprt *xprt)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void rpc_multipath_ops_xprt_iostat(struct rpc_task *task)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void rpc_multipath_ops_failover_handle(struct rpc_task *task)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline
|
|
||||||
+bool rpc_multipath_ops_task_need_call_start_again(struct rpc_task *task)
|
|
||||||
+{
|
|
||||||
+ return false;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void
|
|
||||||
+rpc_multipath_ops_adjust_task_timeout(struct rpc_task *task, void *condition)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void
|
|
||||||
+rpc_multipath_ops_init_task_req(struct rpc_task *task, struct rpc_rqst *req)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline bool rpc_multipath_ops_prepare_transmit(struct rpc_task *task)
|
|
||||||
+{
|
|
||||||
+ return false;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static inline void
|
|
||||||
+rpc_multipath_ops_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#endif
|
|
||||||
+#endif // _SUNRPC_ENFS_ADAPTER_H_
|
|
||||||
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
|
|
||||||
index ccfacca1eba9..2e47b3577947 100644
|
|
||||||
--- a/include/linux/sunrpc/xprt.h
|
|
||||||
+++ b/include/linux/sunrpc/xprt.h
|
|
||||||
@@ -279,6 +279,10 @@ struct rpc_xprt {
|
|
||||||
atomic_t inject_disconnect;
|
|
||||||
#endif
|
|
||||||
struct rcu_head rcu;
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ atomic_long_t queuelen;
|
|
||||||
+ void *multipath_context;
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(CONFIG_SUNRPC_BACKCHANNEL)
|
|
||||||
diff --git a/include/linux/sunrpc/xprtmultipath.h b/include/linux/sunrpc/xprtmultipath.h
|
|
||||||
index af1257c030d2..5677a46eec3b 100644
|
|
||||||
--- a/include/linux/sunrpc/xprtmultipath.h
|
|
||||||
+++ b/include/linux/sunrpc/xprtmultipath.h
|
|
||||||
@@ -22,6 +22,11 @@ struct rpc_xprt_switch {
|
|
||||||
const struct rpc_xprt_iter_ops *xps_iter_ops;
|
|
||||||
|
|
||||||
struct rcu_head xps_rcu;
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ unsigned int xps_nactive;
|
|
||||||
+ atomic_long_t xps_queuelen;
|
|
||||||
+ unsigned long xps_tmp_time;
|
|
||||||
+#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rpc_xprt_iter {
|
|
||||||
@@ -69,4 +74,8 @@ extern struct rpc_xprt *xprt_iter_get_next(struct rpc_xprt_iter *xpi);
|
|
||||||
|
|
||||||
extern bool rpc_xprt_switch_has_addr(struct rpc_xprt_switch *xps,
|
|
||||||
const struct sockaddr *sap);
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+extern void xprt_switch_add_xprt_locked(struct rpc_xprt_switch *xps,
|
|
||||||
+ struct rpc_xprt *xprt);
|
|
||||||
+#endif
|
|
||||||
#endif
|
|
||||||
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
|
|
||||||
index 1b224caf9a70..02633da2e506 100644
|
|
||||||
--- a/net/sunrpc/clnt.c
|
|
||||||
+++ b/net/sunrpc/clnt.c
|
|
||||||
@@ -37,6 +37,7 @@
|
|
||||||
#include <linux/sunrpc/rpc_pipe_fs.h>
|
|
||||||
#include <linux/sunrpc/metrics.h>
|
|
||||||
#include <linux/sunrpc/bc_xprt.h>
|
|
||||||
+#include <linux/sunrpc/sunrpc_enfs_adapter.h>
|
|
||||||
#include <trace/events/sunrpc.h>
|
|
||||||
|
|
||||||
#include "sunrpc.h"
|
|
||||||
@@ -493,6 +494,8 @@ static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ rpc_multipath_ops_create_clnt(args, clnt);
|
|
||||||
+
|
|
||||||
clnt->cl_softrtry = 1;
|
|
||||||
if (args->flags & RPC_CLNT_CREATE_HARDRTRY)
|
|
||||||
clnt->cl_softrtry = 0;
|
|
||||||
@@ -872,6 +875,8 @@ void rpc_shutdown_client(struct rpc_clnt *clnt)
|
|
||||||
list_empty(&clnt->cl_tasks), 1*HZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ rpc_multipath_ops_releas_clnt(clnt);
|
|
||||||
+
|
|
||||||
rpc_release_client(clnt);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(rpc_shutdown_client);
|
|
||||||
@@ -984,6 +989,12 @@ void rpc_task_release_transport(struct rpc_task *task)
|
|
||||||
|
|
||||||
if (xprt) {
|
|
||||||
task->tk_xprt = NULL;
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ if (task->tk_client) {
|
|
||||||
+ rpc_task_release_xprt(task->tk_client, xprt);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
xprt_put(xprt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -993,6 +1004,10 @@ void rpc_task_release_client(struct rpc_task *task)
|
|
||||||
{
|
|
||||||
struct rpc_clnt *clnt = task->tk_client;
|
|
||||||
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ rpc_task_release_transport(task);
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
if (clnt != NULL) {
|
|
||||||
/* Remove from client task list */
|
|
||||||
spin_lock(&clnt->cl_lock);
|
|
||||||
@@ -1002,14 +1017,31 @@ void rpc_task_release_client(struct rpc_task *task)
|
|
||||||
|
|
||||||
rpc_release_client(clnt);
|
|
||||||
}
|
|
||||||
- rpc_task_release_transport(task);
|
|
||||||
+
|
|
||||||
+ if (!IS_ENABLED(CONFIG_ENFS))
|
|
||||||
+ rpc_task_release_transport(task);
|
|
||||||
+
|
|
||||||
}
|
|
||||||
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+struct rpc_xprt *
|
|
||||||
+rpc_task_get_next_xprt(struct rpc_clnt *clnt)
|
|
||||||
+{
|
|
||||||
+ return rpc_task_get_xprt(clnt, xprt_iter_get_next(&clnt->cl_xpi));
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(rpc_task_get_next_xprt);
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
static
|
|
||||||
void rpc_task_set_transport(struct rpc_task *task, struct rpc_clnt *clnt)
|
|
||||||
{
|
|
||||||
+ rpc_multipath_ops_set_transport(task, clnt);
|
|
||||||
if (!task->tk_xprt)
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ task->tk_xprt = rpc_task_get_next_xprt(clnt);
|
|
||||||
+#else
|
|
||||||
task->tk_xprt = xprt_iter_get_next(&clnt->cl_xpi);
|
|
||||||
+#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
@@ -1600,6 +1632,14 @@ call_reserveresult(struct rpc_task *task)
|
|
||||||
return;
|
|
||||||
case -EIO: /* probably a shutdown */
|
|
||||||
break;
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ case -ETIMEDOUT: /* woken up; restart */
|
|
||||||
+ if (rpc_multipath_ops_task_need_call_start_again(task)) {
|
|
||||||
+ rpc_task_release_transport(task);
|
|
||||||
+ task->tk_action = call_start;
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+#endif
|
|
||||||
default:
|
|
||||||
printk(KERN_ERR "%s: unrecognized error %d, exiting\n",
|
|
||||||
__func__, status);
|
|
||||||
@@ -1965,6 +2005,10 @@ call_transmit(struct rpc_task *task)
|
|
||||||
return;
|
|
||||||
if (!xprt_prepare_transmit(task))
|
|
||||||
return;
|
|
||||||
+
|
|
||||||
+ if (rpc_multipath_ops_prepare_transmit(task))
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
task->tk_action = call_transmit_status;
|
|
||||||
/* Encode here so that rpcsec_gss can use correct sequence number. */
|
|
||||||
if (rpc_task_need_encode(task)) {
|
|
||||||
@@ -2280,6 +2324,7 @@ call_timeout(struct rpc_task *task)
|
|
||||||
|
|
||||||
retry:
|
|
||||||
task->tk_action = call_bind;
|
|
||||||
+ rpc_multipath_ops_failover_handle(task);
|
|
||||||
task->tk_status = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2801,8 +2846,12 @@ int rpc_clnt_add_xprt(struct rpc_clnt *clnt,
|
|
||||||
xprt->ops->set_connect_timeout(xprt,
|
|
||||||
connect_timeout,
|
|
||||||
reconnect_timeout);
|
|
||||||
-
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ if (!clnt->cl_enfs)
|
|
||||||
+ rpc_xprt_switch_set_roundrobin(xps);
|
|
||||||
+#else
|
|
||||||
rpc_xprt_switch_set_roundrobin(xps);
|
|
||||||
+#endif
|
|
||||||
if (setup) {
|
|
||||||
ret = setup(clnt, xps, xprt, data);
|
|
||||||
if (ret != 0)
|
|
||||||
@@ -2964,3 +3013,30 @@ rpc_clnt_swap_deactivate(struct rpc_clnt *clnt)
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(rpc_clnt_swap_deactivate);
|
|
||||||
#endif /* CONFIG_SUNRPC_SWAP */
|
|
||||||
+
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+/* rpc_clnt_test_xprt - Test and add a new transport to a rpc_clnt
|
|
||||||
+ * @clnt: pointer to struct rpc_clnt
|
|
||||||
+ * @xprt: pointer struct rpc_xprt
|
|
||||||
+ * @ops: async operation
|
|
||||||
+ */
|
|
||||||
+int
|
|
||||||
+rpc_clnt_test_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt,
|
|
||||||
+ const struct rpc_call_ops *ops, void *data, int flags)
|
|
||||||
+{
|
|
||||||
+ struct rpc_cred *cred;
|
|
||||||
+ struct rpc_task *task;
|
|
||||||
+
|
|
||||||
+ cred = authnull_ops.lookup_cred(NULL, NULL, 0);
|
|
||||||
+ task = rpc_call_null_helper(clnt, xprt, cred,
|
|
||||||
+ RPC_TASK_SOFT | RPC_TASK_SOFTCONN | flags,
|
|
||||||
+ ops, data);
|
|
||||||
+ put_rpccred(cred);
|
|
||||||
+ if (IS_ERR(task))
|
|
||||||
+ return PTR_ERR(task);
|
|
||||||
+
|
|
||||||
+ rpc_put_task(task);
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(rpc_clnt_test_xprt);
|
|
||||||
+#endif
|
|
||||||
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
|
|
||||||
index a873c92a4898..2254fea0e863 100644
|
|
||||||
--- a/net/sunrpc/sched.c
|
|
||||||
+++ b/net/sunrpc/sched.c
|
|
||||||
@@ -20,7 +20,7 @@
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
#include <linux/freezer.h>
|
|
||||||
|
|
||||||
-#include <linux/sunrpc/clnt.h>
|
|
||||||
+#include <linux/sunrpc/sunrpc_enfs_adapter.h>
|
|
||||||
|
|
||||||
#include "sunrpc.h"
|
|
||||||
|
|
||||||
@@ -962,7 +962,12 @@ static void rpc_init_task(struct rpc_task *task, const struct rpc_task_setup *ta
|
|
||||||
/* Initialize workqueue for async tasks */
|
|
||||||
task->tk_workqueue = task_setup_data->workqueue;
|
|
||||||
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ task->tk_xprt = rpc_task_get_xprt(task_setup_data->rpc_client,
|
|
||||||
+ xprt_get(task_setup_data->rpc_xprt));
|
|
||||||
+#else
|
|
||||||
task->tk_xprt = xprt_get(task_setup_data->rpc_xprt);
|
|
||||||
+#endif
|
|
||||||
|
|
||||||
if (task->tk_ops->rpc_call_prepare != NULL)
|
|
||||||
task->tk_action = rpc_prepare_task;
|
|
||||||
diff --git a/net/sunrpc/sunrpc_enfs_adapter.c b/net/sunrpc/sunrpc_enfs_adapter.c
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..106ad7309bef
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/net/sunrpc/sunrpc_enfs_adapter.c
|
|
||||||
@@ -0,0 +1,225 @@
|
|
||||||
+// SPDX-License-Identifier: GPL-2.0
|
|
||||||
+/* Client-side SUNRPC ENFS adapter header.
|
|
||||||
+ * Copyright (c) 2023. Huawei Technologies Co., Ltd. All rights reserved.
|
|
||||||
+ */
|
|
||||||
+#include <linux/sunrpc/sunrpc_enfs_adapter.h>
|
|
||||||
+
|
|
||||||
+struct rpc_multipath_ops __rcu *multipath_ops;
|
|
||||||
+
|
|
||||||
+void rpc_init_task_retry_counters(struct rpc_task *task)
|
|
||||||
+{
|
|
||||||
+ /* Initialize retry counters */
|
|
||||||
+ task->tk_garb_retry = 2;
|
|
||||||
+ task->tk_cred_retry = 2;
|
|
||||||
+ task->tk_rebind_retry = 2;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(rpc_init_task_retry_counters);
|
|
||||||
+
|
|
||||||
+struct rpc_xprt *
|
|
||||||
+rpc_task_get_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
|
|
||||||
+{
|
|
||||||
+ struct rpc_xprt_switch *xps;
|
|
||||||
+
|
|
||||||
+ if (!xprt)
|
|
||||||
+ return NULL;
|
|
||||||
+ rcu_read_lock();
|
|
||||||
+ xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch);
|
|
||||||
+ atomic_long_inc(&xps->xps_queuelen);
|
|
||||||
+ rcu_read_unlock();
|
|
||||||
+ atomic_long_inc(&xprt->queuelen);
|
|
||||||
+
|
|
||||||
+ return xprt;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int rpc_multipath_ops_register(struct rpc_multipath_ops *ops)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *old;
|
|
||||||
+
|
|
||||||
+ old = cmpxchg((struct rpc_multipath_ops **)&multipath_ops, NULL, ops);
|
|
||||||
+ if (!old || old == ops)
|
|
||||||
+ return 0;
|
|
||||||
+ pr_err("regist rpc_multipath ops %p fail. old %p\n", ops, old);
|
|
||||||
+ return -EPERM;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(rpc_multipath_ops_register);
|
|
||||||
+
|
|
||||||
+int rpc_multipath_ops_unregister(struct rpc_multipath_ops *ops)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *old;
|
|
||||||
+
|
|
||||||
+ old = cmpxchg((struct rpc_multipath_ops **)&multipath_ops, ops, NULL);
|
|
||||||
+ if (!old || old == ops)
|
|
||||||
+ return 0;
|
|
||||||
+ pr_err("regist rpc_multipath ops %p fail. old %p\n", ops, old);
|
|
||||||
+ return -EPERM;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(rpc_multipath_ops_unregister);
|
|
||||||
+
|
|
||||||
+struct rpc_multipath_ops *rpc_multipath_ops_get(void)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *ops;
|
|
||||||
+
|
|
||||||
+ rcu_read_lock();
|
|
||||||
+ ops = rcu_dereference(multipath_ops);
|
|
||||||
+ if (!ops) {
|
|
||||||
+ rcu_read_unlock();
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+ if (!try_module_get(ops->owner))
|
|
||||||
+ ops = NULL;
|
|
||||||
+ rcu_read_unlock();
|
|
||||||
+ return ops;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(rpc_multipath_ops_get);
|
|
||||||
+
|
|
||||||
+void rpc_multipath_ops_put(struct rpc_multipath_ops *ops)
|
|
||||||
+{
|
|
||||||
+ if (ops)
|
|
||||||
+ module_put(ops->owner);
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(rpc_multipath_ops_put);
|
|
||||||
+
|
|
||||||
+void rpc_task_release_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt)
|
|
||||||
+{
|
|
||||||
+ struct rpc_xprt_switch *xps;
|
|
||||||
+
|
|
||||||
+ atomic_long_dec(&xprt->queuelen);
|
|
||||||
+ rcu_read_lock();
|
|
||||||
+ xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch);
|
|
||||||
+ atomic_long_dec(&xps->xps_queuelen);
|
|
||||||
+ rcu_read_unlock();
|
|
||||||
+
|
|
||||||
+ xprt_put(xprt);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void rpc_multipath_ops_create_clnt(struct rpc_create_args *args,
|
|
||||||
+ struct rpc_clnt *clnt)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mops;
|
|
||||||
+
|
|
||||||
+ if (args->multipath_option) {
|
|
||||||
+ mops = rpc_multipath_ops_get();
|
|
||||||
+ if (mops && mops->create_clnt)
|
|
||||||
+ mops->create_clnt(args, clnt);
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void rpc_multipath_ops_releas_clnt(struct rpc_clnt *clnt)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mops;
|
|
||||||
+
|
|
||||||
+ mops = rpc_multipath_ops_get();
|
|
||||||
+ if (mops && mops->releas_clnt)
|
|
||||||
+ mops->releas_clnt(clnt);
|
|
||||||
+
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+bool rpc_multipath_ops_create_xprt(struct rpc_xprt *xprt)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mops = NULL;
|
|
||||||
+
|
|
||||||
+ mops = rpc_multipath_ops_get();
|
|
||||||
+ if (mops && mops->create_xprt) {
|
|
||||||
+ mops->create_xprt(xprt);
|
|
||||||
+ if (!xprt->multipath_context) {
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+ return false;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void rpc_multipath_ops_destroy_xprt(struct rpc_xprt *xprt)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mops;
|
|
||||||
+
|
|
||||||
+ if (xprt->multipath_context) {
|
|
||||||
+ mops = rpc_multipath_ops_get();
|
|
||||||
+ if (mops && mops->destroy_xprt)
|
|
||||||
+ mops->destroy_xprt(xprt);
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void rpc_multipath_ops_xprt_iostat(struct rpc_task *task)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mops;
|
|
||||||
+
|
|
||||||
+ mops = rpc_multipath_ops_get();
|
|
||||||
+ if (task->tk_client && mops && mops->xprt_iostat)
|
|
||||||
+ mops->xprt_iostat(task);
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void rpc_multipath_ops_failover_handle(struct rpc_task *task)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mpath_ops = NULL;
|
|
||||||
+
|
|
||||||
+ mpath_ops = rpc_multipath_ops_get();
|
|
||||||
+ if (mpath_ops && mpath_ops->failover_handle)
|
|
||||||
+ mpath_ops->failover_handle(task);
|
|
||||||
+ rpc_multipath_ops_put(mpath_ops);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+bool rpc_multipath_ops_task_need_call_start_again(struct rpc_task *task)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mpath_ops = NULL;
|
|
||||||
+ bool ret = false;
|
|
||||||
+
|
|
||||||
+ mpath_ops = rpc_multipath_ops_get();
|
|
||||||
+ if (mpath_ops && mpath_ops->task_need_call_start_again)
|
|
||||||
+ ret = mpath_ops->task_need_call_start_again(task);
|
|
||||||
+ rpc_multipath_ops_put(mpath_ops);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void rpc_multipath_ops_adjust_task_timeout(struct rpc_task *task,
|
|
||||||
+ void *condition)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mops = NULL;
|
|
||||||
+
|
|
||||||
+ mops = rpc_multipath_ops_get();
|
|
||||||
+ if (mops && mops->adjust_task_timeout)
|
|
||||||
+ mops->adjust_task_timeout(task, NULL);
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void rpc_multipath_ops_init_task_req(struct rpc_task *task,
|
|
||||||
+ struct rpc_rqst *req)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mops = NULL;
|
|
||||||
+
|
|
||||||
+ mops = rpc_multipath_ops_get();
|
|
||||||
+ if (mops && mops->init_task_req)
|
|
||||||
+ mops->init_task_req(task, req);
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+bool rpc_multipath_ops_prepare_transmit(struct rpc_task *task)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mops = NULL;
|
|
||||||
+
|
|
||||||
+ mops = rpc_multipath_ops_get();
|
|
||||||
+ if (mops && mops->prepare_transmit) {
|
|
||||||
+ if (!(mops->prepare_transmit(task))) {
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+ return true;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+ return false;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+void rpc_multipath_ops_set_transport(struct rpc_task *task,
|
|
||||||
+ struct rpc_clnt *clnt)
|
|
||||||
+{
|
|
||||||
+ struct rpc_multipath_ops *mops = NULL;
|
|
||||||
+
|
|
||||||
+ mops = rpc_multipath_ops_get();
|
|
||||||
+ if (mops && mops->set_transport)
|
|
||||||
+ mops->set_transport(task, clnt);
|
|
||||||
+ rpc_multipath_ops_put(mops);
|
|
||||||
+}
|
|
||||||
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
|
|
||||||
index c912bf20faa2..c2b63b3d5217 100644
|
|
||||||
--- a/net/sunrpc/xprt.c
|
|
||||||
+++ b/net/sunrpc/xprt.c
|
|
||||||
@@ -48,6 +48,7 @@
|
|
||||||
#include <linux/sunrpc/clnt.h>
|
|
||||||
#include <linux/sunrpc/metrics.h>
|
|
||||||
#include <linux/sunrpc/bc_xprt.h>
|
|
||||||
+#include <linux/sunrpc/sunrpc_enfs_adapter.h>
|
|
||||||
#include <linux/rcupdate.h>
|
|
||||||
|
|
||||||
#include <trace/events/sunrpc.h>
|
|
||||||
@@ -259,6 +260,9 @@ int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task)
|
|
||||||
dprintk("RPC: %5u failed to lock transport %p\n",
|
|
||||||
task->tk_pid, xprt);
|
|
||||||
task->tk_timeout = 0;
|
|
||||||
+
|
|
||||||
+ rpc_multipath_ops_adjust_task_timeout(task, NULL);
|
|
||||||
+
|
|
||||||
task->tk_status = -EAGAIN;
|
|
||||||
if (req == NULL)
|
|
||||||
priority = RPC_PRIORITY_LOW;
|
|
||||||
@@ -560,6 +564,9 @@ void xprt_wait_for_buffer_space(struct rpc_task *task, rpc_action action)
|
|
||||||
struct rpc_xprt *xprt = req->rq_xprt;
|
|
||||||
|
|
||||||
task->tk_timeout = RPC_IS_SOFT(task) ? req->rq_timeout : 0;
|
|
||||||
+
|
|
||||||
+ rpc_multipath_ops_adjust_task_timeout(task, NULL);
|
|
||||||
+
|
|
||||||
rpc_sleep_on(&xprt->pending, task, action);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xprt_wait_for_buffer_space);
|
|
||||||
@@ -1347,6 +1354,9 @@ xprt_request_init(struct rpc_task *task)
|
|
||||||
req->rq_rcv_buf.buflen = 0;
|
|
||||||
req->rq_release_snd_buf = NULL;
|
|
||||||
xprt_reset_majortimeo(req);
|
|
||||||
+
|
|
||||||
+ rpc_multipath_ops_init_task_req(task, req);
|
|
||||||
+
|
|
||||||
dprintk("RPC: %5u reserved req %p xid %08x\n", task->tk_pid,
|
|
||||||
req, ntohl(req->rq_xid));
|
|
||||||
}
|
|
||||||
@@ -1427,6 +1437,9 @@ void xprt_release(struct rpc_task *task)
|
|
||||||
task->tk_ops->rpc_count_stats(task, task->tk_calldata);
|
|
||||||
else if (task->tk_client)
|
|
||||||
rpc_count_iostats(task, task->tk_client->cl_metrics);
|
|
||||||
+
|
|
||||||
+ rpc_multipath_ops_xprt_iostat(task);
|
|
||||||
+
|
|
||||||
spin_lock(&xprt->recv_lock);
|
|
||||||
if (!list_empty(&req->rq_list)) {
|
|
||||||
list_del_init(&req->rq_list);
|
|
||||||
@@ -1455,6 +1468,7 @@ void xprt_release(struct rpc_task *task)
|
|
||||||
else
|
|
||||||
xprt_free_bc_request(req);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL_GPL(xprt_release);
|
|
||||||
|
|
||||||
static void xprt_init(struct rpc_xprt *xprt, struct net *net)
|
|
||||||
{
|
|
||||||
@@ -1528,6 +1542,10 @@ struct rpc_xprt *xprt_create_transport(struct xprt_create *args)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
+if (rpc_multipath_ops_create_xprt(xprt)) {
|
|
||||||
+ xprt_destroy(xprt);
|
|
||||||
+ return ERR_PTR(-ENOMEM);
|
|
||||||
+}
|
|
||||||
rpc_xprt_debugfs_register(xprt);
|
|
||||||
|
|
||||||
dprintk("RPC: created transport %p with %u slots\n", xprt,
|
|
||||||
@@ -1547,6 +1565,9 @@ static void xprt_destroy_cb(struct work_struct *work)
|
|
||||||
rpc_destroy_wait_queue(&xprt->sending);
|
|
||||||
rpc_destroy_wait_queue(&xprt->backlog);
|
|
||||||
kfree(xprt->servername);
|
|
||||||
+
|
|
||||||
+ rpc_multipath_ops_destroy_xprt(xprt);
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* Tear down transport state and free the rpc_xprt
|
|
||||||
*/
|
|
||||||
diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c
|
|
||||||
index c0a0e2346cfb..6b3709d5ed6e 100644
|
|
||||||
--- a/net/sunrpc/xprtmultipath.c
|
|
||||||
+++ b/net/sunrpc/xprtmultipath.c
|
|
||||||
@@ -18,6 +18,7 @@
|
|
||||||
#include <linux/sunrpc/xprt.h>
|
|
||||||
#include <linux/sunrpc/addr.h>
|
|
||||||
#include <linux/sunrpc/xprtmultipath.h>
|
|
||||||
+#include <linux/sunrpc/sunrpc_enfs_adapter.h>
|
|
||||||
|
|
||||||
typedef struct rpc_xprt *(*xprt_switch_find_xprt_t)(struct list_head *head,
|
|
||||||
const struct rpc_xprt *cur);
|
|
||||||
@@ -26,8 +27,8 @@ static const struct rpc_xprt_iter_ops rpc_xprt_iter_singular;
|
|
||||||
static const struct rpc_xprt_iter_ops rpc_xprt_iter_roundrobin;
|
|
||||||
static const struct rpc_xprt_iter_ops rpc_xprt_iter_listall;
|
|
||||||
|
|
||||||
-static void xprt_switch_add_xprt_locked(struct rpc_xprt_switch *xps,
|
|
||||||
- struct rpc_xprt *xprt)
|
|
||||||
+void xprt_switch_add_xprt_locked(struct rpc_xprt_switch *xps,
|
|
||||||
+ struct rpc_xprt *xprt)
|
|
||||||
{
|
|
||||||
if (unlikely(xprt_get(xprt) == NULL))
|
|
||||||
return;
|
|
||||||
@@ -36,7 +37,9 @@ static void xprt_switch_add_xprt_locked(struct rpc_xprt_switch *xps,
|
|
||||||
if (xps->xps_nxprts == 0)
|
|
||||||
xps->xps_net = xprt->xprt_net;
|
|
||||||
xps->xps_nxprts++;
|
|
||||||
+ rpc_xps_nactive_add_one(xps);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL(xprt_switch_add_xprt_locked);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rpc_xprt_switch_add_xprt - Add a new rpc_xprt to an rpc_xprt_switch
|
|
||||||
@@ -63,6 +66,7 @@ static void xprt_switch_remove_xprt_locked(struct rpc_xprt_switch *xps,
|
|
||||||
if (unlikely(xprt == NULL))
|
|
||||||
return;
|
|
||||||
xps->xps_nxprts--;
|
|
||||||
+ rpc_xps_nactive_sub_one(xps);
|
|
||||||
if (xps->xps_nxprts == 0)
|
|
||||||
xps->xps_net = NULL;
|
|
||||||
smp_wmb();
|
|
||||||
@@ -84,7 +88,7 @@ void rpc_xprt_switch_remove_xprt(struct rpc_xprt_switch *xps,
|
|
||||||
spin_unlock(&xps->xps_lock);
|
|
||||||
xprt_put(xprt);
|
|
||||||
}
|
|
||||||
-
|
|
||||||
+EXPORT_SYMBOL(rpc_xprt_switch_remove_xprt);
|
|
||||||
/**
|
|
||||||
* xprt_switch_alloc - Allocate a new struct rpc_xprt_switch
|
|
||||||
* @xprt: pointer to struct rpc_xprt
|
|
||||||
@@ -103,6 +107,10 @@ struct rpc_xprt_switch *xprt_switch_alloc(struct rpc_xprt *xprt,
|
|
||||||
spin_lock_init(&xps->xps_lock);
|
|
||||||
kref_init(&xps->xps_kref);
|
|
||||||
xps->xps_nxprts = 0;
|
|
||||||
+#if IS_ENABLED(CONFIG_ENFS)
|
|
||||||
+ xps->xps_nactive = 0;
|
|
||||||
+ atomic_long_set(&xps->xps_queuelen, 0);
|
|
||||||
+#endif
|
|
||||||
INIT_LIST_HEAD(&xps->xps_xprt_list);
|
|
||||||
xps->xps_iter_ops = &rpc_xprt_iter_singular;
|
|
||||||
xprt_switch_add_xprt_locked(xps, xprt);
|
|
||||||
@@ -148,6 +156,7 @@ struct rpc_xprt_switch *xprt_switch_get(struct rpc_xprt_switch *xps)
|
|
||||||
return xps;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL(xprt_switch_get);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* xprt_switch_put - Release a reference to a rpc_xprt_switch
|
|
||||||
@@ -160,6 +169,7 @@ void xprt_switch_put(struct rpc_xprt_switch *xps)
|
|
||||||
if (xps != NULL)
|
|
||||||
kref_put(&xps->xps_kref, xprt_switch_free);
|
|
||||||
}
|
|
||||||
+EXPORT_SYMBOL(xprt_switch_put);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* rpc_xprt_switch_set_roundrobin - Set a round-robin policy on rpc_xprt_switch
|
|
||||||
File diff suppressed because it is too large
Load Diff
22
0003-fedora-standalone.patch
Normal file
22
0003-fedora-standalone.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From 0ef68aab2b08915b9144ffa67b3319e3e8332445 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Nikita Popov <npopov@redhat.com>
|
||||||
|
Date: Thu, 4 Aug 2022 12:44:15 +0200
|
||||||
|
Subject: [PATCH] Fix standalone build
|
||||||
|
|
||||||
|
---
|
||||||
|
libunwind/docs/CMakeLists.txt | 1 +
|
||||||
|
1 files changed, 1 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/libunwind/docs/CMakeLists.txt b/libunwind/docs/CMakeLists.txt
|
||||||
|
index 79b87eb03b44..eaf6f3db5223 100644
|
||||||
|
--- a/libunwind/docs/CMakeLists.txt
|
||||||
|
+++ b/libunwind/docs/CMakeLists.txt
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
include(FindSphinx)
|
||||||
|
if (SPHINX_FOUND AND LLVM_ENABLE_SPHINX)
|
||||||
|
+ include(AddLLVM)
|
||||||
|
include(AddSphinxTarget)
|
||||||
|
if (${SPHINX_OUTPUT_HTML})
|
||||||
|
add_sphinx_target(html libunwind)
|
||||||
|
--
|
||||||
|
2.37.1
|
||||||
File diff suppressed because it is too large
Load Diff
343
0004-remove-cmake_minimum_required.patch
Normal file
343
0004-remove-cmake_minimum_required.patch
Normal file
@ -0,0 +1,343 @@
|
|||||||
|
From 17621e9cc5dea359fbf2aaa0e20e4f2a67d41fa6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: liyunfei <liyunfei33@huawei.com>
|
||||||
|
Date: Thu, 6 Mar 2025 12:48:04 +0800
|
||||||
|
Subject: [PATCH] remove cmake_minimum_required
|
||||||
|
|
||||||
|
---
|
||||||
|
bolt/runtime/CMakeLists.txt | 2 +-
|
||||||
|
clang/CMakeLists.txt | 2 +-
|
||||||
|
clang/tools/scan-build-py/tests/functional/exec/CMakeLists.txt | 2 +-
|
||||||
|
compiler-rt/CMakeLists.txt | 2 +-
|
||||||
|
compiler-rt/lib/builtins/CMakeLists.txt | 2 +-
|
||||||
|
flang/CMakeLists.txt | 2 +-
|
||||||
|
flang/lib/Decimal/CMakeLists.txt | 2 +-
|
||||||
|
flang/runtime/CMakeLists.txt | 2 +-
|
||||||
|
libc/CMakeLists.txt | 2 +-
|
||||||
|
libc/examples/hello_world/CMakeLists.txt | 2 +-
|
||||||
|
libclc/CMakeLists.txt | 2 +-
|
||||||
|
libcxx/CMakeLists.txt | 2 +-
|
||||||
|
libcxxabi/CMakeLists.txt | 2 +-
|
||||||
|
libunwind/CMakeLists.txt | 2 +-
|
||||||
|
lld/CMakeLists.txt | 2 +-
|
||||||
|
lldb/CMakeLists.txt | 2 +-
|
||||||
|
lldb/tools/debugserver/CMakeLists.txt | 2 +-
|
||||||
|
llvm-libgcc/CMakeLists.txt | 2 +-
|
||||||
|
llvm/CMakeLists.txt | 2 +-
|
||||||
|
mlir/CMakeLists.txt | 2 +-
|
||||||
|
mlir/examples/standalone/CMakeLists.txt | 2 +-
|
||||||
|
openmp/CMakeLists.txt | 2 +-
|
||||||
|
openmp/cmake/DetectTestCompiler/CMakeLists.txt | 2 +-
|
||||||
|
openmp/libompd/src/CMakeLists.txt | 2 +-
|
||||||
|
polly/CMakeLists.txt | 2 +-
|
||||||
|
pstl/CMakeLists.txt | 2 +-
|
||||||
|
runtimes/CMakeLists.txt | 2 +-
|
||||||
|
27 files changed, 27 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/bolt/runtime/CMakeLists.txt b/bolt/runtime/CMakeLists.txt
|
||||||
|
index 8472ce00b413..3ddfd2b1743b 100644
|
||||||
|
--- a/bolt/runtime/CMakeLists.txt
|
||||||
|
+++ b/bolt/runtime/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
include(CheckIncludeFiles)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt
|
||||||
|
index 98fcb6ea1a07..18936e79a24c 100644
|
||||||
|
--- a/clang/CMakeLists.txt
|
||||||
|
+++ b/clang/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS)
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
|
||||||
|
diff --git a/clang/tools/scan-build-py/tests/functional/exec/CMakeLists.txt b/clang/tools/scan-build-py/tests/functional/exec/CMakeLists.txt
|
||||||
|
index 95c6fdb610e0..1d1d2a40050e 100644
|
||||||
|
--- a/clang/tools/scan-build-py/tests/functional/exec/CMakeLists.txt
|
||||||
|
+++ b/clang/tools/scan-build-py/tests/functional/exec/CMakeLists.txt
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
project(exec C)
|
||||||
|
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
include(CheckCCompilerFlag)
|
||||||
|
check_c_compiler_flag("-std=c99" C99_SUPPORTED)
|
||||||
|
diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt
|
||||||
|
index cfa97023d281..5f20a92155e3 100644
|
||||||
|
--- a/compiler-rt/CMakeLists.txt
|
||||||
|
+++ b/compiler-rt/CMakeLists.txt
|
||||||
|
@@ -3,7 +3,7 @@
|
||||||
|
# An important constraint of the build is that it only produces libraries
|
||||||
|
# based on the ability of the host toolchain to target various platforms.
|
||||||
|
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
||||||
|
include(${LLVM_COMMON_CMAKE_UTILS}/Modules/CMakePolicy.cmake
|
||||||
|
diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt
|
||||||
|
index d62fa0432e2a..1b5028472ddc 100644
|
||||||
|
--- a/compiler-rt/lib/builtins/CMakeLists.txt
|
||||||
|
+++ b/compiler-rt/lib/builtins/CMakeLists.txt
|
||||||
|
@@ -3,7 +3,7 @@
|
||||||
|
# architecture-specific code in various subdirectories.
|
||||||
|
|
||||||
|
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||||
|
- cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+ cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
|
||||||
|
project(CompilerRTBuiltins C ASM)
|
||||||
|
diff --git a/flang/CMakeLists.txt b/flang/CMakeLists.txt
|
||||||
|
index ac30da89995e..2b778265b432 100644
|
||||||
|
--- a/flang/CMakeLists.txt
|
||||||
|
+++ b/flang/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS)
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
|
||||||
|
diff --git a/flang/lib/Decimal/CMakeLists.txt b/flang/lib/Decimal/CMakeLists.txt
|
||||||
|
index 3116ff68ea26..319c75957e89 100644
|
||||||
|
--- a/flang/lib/Decimal/CMakeLists.txt
|
||||||
|
+++ b/flang/lib/Decimal/CMakeLists.txt
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||||
|
- cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+ cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
project(FortranDecimal C CXX)
|
||||||
|
|
||||||
|
diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt
|
||||||
|
index 5b23065a32d1..22ef3984110a 100644
|
||||||
|
--- a/flang/runtime/CMakeLists.txt
|
||||||
|
+++ b/flang/runtime/CMakeLists.txt
|
||||||
|
@@ -7,7 +7,7 @@
|
||||||
|
#===------------------------------------------------------------------------===#
|
||||||
|
|
||||||
|
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||||
|
- cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+ cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
project(FlangRuntime C CXX)
|
||||||
|
|
||||||
|
diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt
|
||||||
|
index 4be92ba1380c..9ac479b1c01d 100644
|
||||||
|
--- a/libc/CMakeLists.txt
|
||||||
|
+++ b/libc/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
# Include LLVM's cmake policies.
|
||||||
|
if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS)
|
||||||
|
diff --git a/libc/examples/hello_world/CMakeLists.txt b/libc/examples/hello_world/CMakeLists.txt
|
||||||
|
index 1561cdc1c3bf..64062f522a11 100644
|
||||||
|
--- a/libc/examples/hello_world/CMakeLists.txt
|
||||||
|
+++ b/libc/examples/hello_world/CMakeLists.txt
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
project(hello_world)
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
include(../examples.cmake)
|
||||||
|
|
||||||
|
add_example(
|
||||||
|
diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt
|
||||||
|
index 9daef8265c16..2b4c32e235f6 100644
|
||||||
|
--- a/libclc/CMakeLists.txt
|
||||||
|
+++ b/libclc/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
project( libclc VERSION 0.2.0 LANGUAGES CXX C)
|
||||||
|
|
||||||
|
diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt
|
||||||
|
index b8ac536588d3..4d8ba59e9a14 100644
|
||||||
|
--- a/libcxx/CMakeLists.txt
|
||||||
|
+++ b/libcxx/CMakeLists.txt
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
#===============================================================================
|
||||||
|
# Setup Project
|
||||||
|
#===============================================================================
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
||||||
|
|
||||||
|
diff --git a/libcxxabi/CMakeLists.txt b/libcxxabi/CMakeLists.txt
|
||||||
|
index f380fe6b6b92..12a8686fe429 100644
|
||||||
|
--- a/libcxxabi/CMakeLists.txt
|
||||||
|
+++ b/libcxxabi/CMakeLists.txt
|
||||||
|
@@ -4,7 +4,7 @@
|
||||||
|
# Setup Project
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
||||||
|
|
||||||
|
diff --git a/libunwind/CMakeLists.txt b/libunwind/CMakeLists.txt
|
||||||
|
index bc2a820fe98e..ac5b67357152 100644
|
||||||
|
--- a/libunwind/CMakeLists.txt
|
||||||
|
+++ b/libunwind/CMakeLists.txt
|
||||||
|
@@ -2,7 +2,7 @@
|
||||||
|
# Setup Project
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
||||||
|
|
||||||
|
diff --git a/lld/CMakeLists.txt b/lld/CMakeLists.txt
|
||||||
|
index 595c286abd91..2ecd15275929 100644
|
||||||
|
--- a/lld/CMakeLists.txt
|
||||||
|
+++ b/lld/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS)
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
|
||||||
|
diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt
|
||||||
|
index 4a53d7ef3d0d..c643ee9654f3 100644
|
||||||
|
--- a/lldb/CMakeLists.txt
|
||||||
|
+++ b/lldb/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS)
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
|
||||||
|
diff --git a/lldb/tools/debugserver/CMakeLists.txt b/lldb/tools/debugserver/CMakeLists.txt
|
||||||
|
index 74afea804598..9274870fe830 100644
|
||||||
|
--- a/lldb/tools/debugserver/CMakeLists.txt
|
||||||
|
+++ b/lldb/tools/debugserver/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
project(Debugserver LANGUAGES C CXX ASM-ATT)
|
||||||
|
|
||||||
|
diff --git a/llvm-libgcc/CMakeLists.txt b/llvm-libgcc/CMakeLists.txt
|
||||||
|
index de42d908c371..cd825172274b 100644
|
||||||
|
--- a/llvm-libgcc/CMakeLists.txt
|
||||||
|
+++ b/llvm-libgcc/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
if (NOT IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../libunwind")
|
||||||
|
message(FATAL_ERROR "llvm-libgcc requires being built in a monorepo layout with libunwind available")
|
||||||
|
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
|
||||||
|
index b0afb47a7243..1885b9450ae5 100644
|
||||||
|
--- a/llvm/CMakeLists.txt
|
||||||
|
+++ b/llvm/CMakeLists.txt
|
||||||
|
@@ -1,6 +1,6 @@
|
||||||
|
# See docs/CMake.html for instructions about how to build LLVM with CMake.
|
||||||
|
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
|
||||||
|
include(${LLVM_COMMON_CMAKE_UTILS}/Modules/CMakePolicy.cmake
|
||||||
|
diff --git a/mlir/CMakeLists.txt b/mlir/CMakeLists.txt
|
||||||
|
index c91e9cd93dc8..beacaf45721f 100644
|
||||||
|
--- a/mlir/CMakeLists.txt
|
||||||
|
+++ b/mlir/CMakeLists.txt
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# MLIR project.
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS)
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
|
||||||
|
diff --git a/mlir/examples/standalone/CMakeLists.txt b/mlir/examples/standalone/CMakeLists.txt
|
||||||
|
index 038242ba1437..c143d373fa6b 100644
|
||||||
|
--- a/mlir/examples/standalone/CMakeLists.txt
|
||||||
|
+++ b/mlir/examples/standalone/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
project(standalone-dialect LANGUAGES CXX C)
|
||||||
|
|
||||||
|
set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON)
|
||||||
|
diff --git a/openmp/CMakeLists.txt b/openmp/CMakeLists.txt
|
||||||
|
index c1efcaf80b54..e82b81aa3052 100644
|
||||||
|
--- a/openmp/CMakeLists.txt
|
||||||
|
+++ b/openmp/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake)
|
||||||
|
|
||||||
|
diff --git a/openmp/cmake/DetectTestCompiler/CMakeLists.txt b/openmp/cmake/DetectTestCompiler/CMakeLists.txt
|
||||||
|
index 8ea7ab8d45ba..56ffd3c51a7f 100644
|
||||||
|
--- a/openmp/cmake/DetectTestCompiler/CMakeLists.txt
|
||||||
|
+++ b/openmp/cmake/DetectTestCompiler/CMakeLists.txt
|
||||||
|
@@ -1,4 +1,4 @@
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
project(DetectTestCompiler C CXX)
|
||||||
|
|
||||||
|
include(CheckCCompilerFlag)
|
||||||
|
diff --git a/openmp/libompd/src/CMakeLists.txt b/openmp/libompd/src/CMakeLists.txt
|
||||||
|
index 0402a0177201..f9955c02b545 100644
|
||||||
|
--- a/openmp/libompd/src/CMakeLists.txt
|
||||||
|
+++ b/openmp/libompd/src/CMakeLists.txt
|
||||||
|
@@ -9,7 +9,7 @@
|
||||||
|
#
|
||||||
|
|
||||||
|
project (libompd)
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
add_library (ompd SHARED TargetValue.cpp omp-debug.cpp omp-state.cpp omp-icv.cpp)
|
||||||
|
|
||||||
|
diff --git a/polly/CMakeLists.txt b/polly/CMakeLists.txt
|
||||||
|
index 5d0f2cd7f00e..28f7c580f6a4 100644
|
||||||
|
--- a/polly/CMakeLists.txt
|
||||||
|
+++ b/polly/CMakeLists.txt
|
||||||
|
@@ -1,7 +1,7 @@
|
||||||
|
# Check if this is a in tree build.
|
||||||
|
if (NOT DEFINED LLVM_MAIN_SRC_DIR)
|
||||||
|
project(Polly)
|
||||||
|
- cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+ cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
set(POLLY_STANDALONE_BUILD TRUE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
diff --git a/pstl/CMakeLists.txt b/pstl/CMakeLists.txt
|
||||||
|
index 255e22af9a26..1364d451224a 100644
|
||||||
|
--- a/pstl/CMakeLists.txt
|
||||||
|
+++ b/pstl/CMakeLists.txt
|
||||||
|
@@ -5,7 +5,7 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
#
|
||||||
|
#===----------------------------------------------------------------------===##
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
set(PARALLELSTL_VERSION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/include/pstl/internal/pstl_config.h")
|
||||||
|
file(STRINGS "${PARALLELSTL_VERSION_FILE}" PARALLELSTL_VERSION_SOURCE REGEX "#define _PSTL_VERSION .*$")
|
||||||
|
diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt
|
||||||
|
index 599529852688..918e7a9c1c7e 100644
|
||||||
|
--- a/runtimes/CMakeLists.txt
|
||||||
|
+++ b/runtimes/CMakeLists.txt
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
# This file handles building LLVM runtime sub-projects.
|
||||||
|
-cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
+cmake_minimum_required(VERSION 3.16.0)
|
||||||
|
|
||||||
|
# Add path for custom and the LLVM build's modules to the CMake module path.
|
||||||
|
set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
||||||
|
--
|
||||||
|
2.42.0.windows.2
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,70 +0,0 @@
|
|||||||
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
|
|
||||||
index b04256636d4b..ae53510c0627 100644
|
|
||||||
--- a/arch/arm64/configs/openeuler_defconfig
|
|
||||||
+++ b/arch/arm64/configs/openeuler_defconfig
|
|
||||||
@@ -5344,6 +5344,7 @@ CONFIG_LOCKD=m
|
|
||||||
CONFIG_LOCKD_V4=y
|
|
||||||
CONFIG_NFS_ACL_SUPPORT=m
|
|
||||||
CONFIG_NFS_COMMON=y
|
|
||||||
+# CONFIG_ENFS is not set
|
|
||||||
CONFIG_SUNRPC=m
|
|
||||||
CONFIG_SUNRPC_GSS=m
|
|
||||||
CONFIG_SUNRPC_BACKCHANNEL=y
|
|
||||||
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
|
|
||||||
index 59baeb2973af..ccc317f7fdb2 100644
|
|
||||||
--- a/arch/x86/configs/openeuler_defconfig
|
|
||||||
+++ b/arch/x86/configs/openeuler_defconfig
|
|
||||||
@@ -6825,6 +6825,7 @@ CONFIG_LOCKD=m
|
|
||||||
CONFIG_LOCKD_V4=y
|
|
||||||
CONFIG_NFS_ACL_SUPPORT=m
|
|
||||||
CONFIG_NFS_COMMON=y
|
|
||||||
+# CONFIG_ENFS is not set
|
|
||||||
CONFIG_SUNRPC=m
|
|
||||||
CONFIG_SUNRPC_GSS=m
|
|
||||||
CONFIG_SUNRPC_BACKCHANNEL=y
|
|
||||||
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
|
|
||||||
index e55f86713948..872c9b7671b1 100644
|
|
||||||
--- a/fs/nfs/Kconfig
|
|
||||||
+++ b/fs/nfs/Kconfig
|
|
||||||
@@ -196,3 +196,14 @@ config NFS_DEBUG
|
|
||||||
depends on NFS_FS && SUNRPC_DEBUG
|
|
||||||
select CRC32
|
|
||||||
default y
|
|
||||||
+
|
|
||||||
+config ENFS
|
|
||||||
+ tristate "NFS client support for ENFS"
|
|
||||||
+ depends on NFS_FS
|
|
||||||
+ default n
|
|
||||||
+ help
|
|
||||||
+ This option enables support multipath of the NFS protocol
|
|
||||||
+ in the kernel's NFS client.
|
|
||||||
+ This feature will improve performance and reliability.
|
|
||||||
+
|
|
||||||
+ If sure, say Y.
|
|
||||||
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
|
|
||||||
index c587e3c4c6a6..19d0ac2ba3b8 100644
|
|
||||||
--- a/fs/nfs/Makefile
|
|
||||||
+++ b/fs/nfs/Makefile
|
|
||||||
@@ -12,6 +12,7 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
|
|
||||||
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
|
|
||||||
nfs-$(CONFIG_SYSCTL) += sysctl.o
|
|
||||||
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
|
|
||||||
+nfs-$(CONFIG_ENFS) += enfs_adapter.o
|
|
||||||
|
|
||||||
obj-$(CONFIG_NFS_V2) += nfsv2.o
|
|
||||||
nfsv2-y := nfs2super.o proc.o nfs2xdr.o
|
|
||||||
@@ -34,3 +35,5 @@ nfsv4-$(CONFIG_NFS_V4_2) += nfs42proc.o
|
|
||||||
obj-$(CONFIG_PNFS_FILE_LAYOUT) += filelayout/
|
|
||||||
obj-$(CONFIG_PNFS_BLOCK) += blocklayout/
|
|
||||||
obj-$(CONFIG_PNFS_FLEXFILE_LAYOUT) += flexfilelayout/
|
|
||||||
+
|
|
||||||
+obj-$(CONFIG_ENFS) += enfs/
|
|
||||||
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile
|
|
||||||
index 090658c3da12..fe4e3b28c5d1 100644
|
|
||||||
--- a/net/sunrpc/Makefile
|
|
||||||
+++ b/net/sunrpc/Makefile
|
|
||||||
@@ -19,3 +19,4 @@ sunrpc-$(CONFIG_SUNRPC_DEBUG) += debugfs.o
|
|
||||||
sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o
|
|
||||||
sunrpc-$(CONFIG_PROC_FS) += stats.o
|
|
||||||
sunrpc-$(CONFIG_SYSCTL) += sysctl.o
|
|
||||||
+sunrpc-$(CONFIG_ENFS) += sunrpc_enfs_adapter.o
|
|
||||||
5
CMakeLists.txt
Normal file
5
CMakeLists.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.13.4)
|
||||||
|
project(Runtimes C CXX ASM)
|
||||||
|
add_subdirectory(libcxxabi)
|
||||||
|
add_subdirectory(libcxx)
|
||||||
|
add_subdirectory(libunwind)
|
||||||
2463
Module.kabi_aarch64
2463
Module.kabi_aarch64
File diff suppressed because it is too large
Load Diff
2777
Module.kabi_x86_64
2777
Module.kabi_x86_64
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
# kernel
|
# llvm-toolset-17
|
||||||
|
|
||||||
#### Description
|
#### Description
|
||||||
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
|
The LLVM Compiler Infrastructure
|
||||||
|
|
||||||
#### Software Architecture
|
#### Software Architecture
|
||||||
Software architecture description
|
Software architecture description
|
||||||
|
|||||||
38
README.md
38
README.md
@ -1,5 +1,37 @@
|
|||||||
hulk-4.19
|
# llvm-toolset-17
|
||||||
|
|
||||||
[config]:
|
#### 介绍
|
||||||
kernel-kernelVersion-arch.config
|
The LLVM Compiler Infrastructure
|
||||||
|
|
||||||
|
#### 软件架构
|
||||||
|
软件架构说明
|
||||||
|
|
||||||
|
|
||||||
|
#### 安装教程
|
||||||
|
|
||||||
|
1. xxxx
|
||||||
|
2. xxxx
|
||||||
|
3. xxxx
|
||||||
|
|
||||||
|
#### 使用说明
|
||||||
|
|
||||||
|
1. xxxx
|
||||||
|
2. xxxx
|
||||||
|
3. xxxx
|
||||||
|
|
||||||
|
#### 参与贡献
|
||||||
|
|
||||||
|
1. Fork 本仓库
|
||||||
|
2. 新建 Feat_xxx 分支
|
||||||
|
3. 提交代码
|
||||||
|
4. 新建 Pull Request
|
||||||
|
|
||||||
|
|
||||||
|
#### 特技
|
||||||
|
|
||||||
|
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
||||||
|
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
||||||
|
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
||||||
|
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
||||||
|
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||||
|
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
<multibuild>
|
|
||||||
<flavor>raspberrypi-kernel</flavor>
|
|
||||||
<flavor>kernel-rt</flavor>
|
|
||||||
</multibuild>
|
|
||||||
@ -1,49 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Given a series.conf file and a directory with patches, applies them to the
|
|
||||||
# current directory.
|
|
||||||
# Used by kernel-source.spec.in and kernel-binary.spec.in
|
|
||||||
|
|
||||||
USAGE="$0 [--vanilla] <series.conf> <patchdir> [symbol ...]"
|
|
||||||
|
|
||||||
set -e
|
|
||||||
set -o pipefail
|
|
||||||
vanilla=false
|
|
||||||
if test "$1" == "--vanilla"; then
|
|
||||||
vanilla=true
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
if test $# -lt 2; then
|
|
||||||
echo "$USAGE" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
DIR="${0%/*}"
|
|
||||||
SERIES_CONF=$1
|
|
||||||
PATCH_DIR=$2
|
|
||||||
shift 2
|
|
||||||
|
|
||||||
trap 'rm -f "$series"' EXIT
|
|
||||||
series=$(mktemp)
|
|
||||||
# support for patches in patches.addon/series
|
|
||||||
cp "$SERIES_CONF" "$series"
|
|
||||||
if ! $vanilla && test -e "$PATCH_DIR/patches.addon/series"; then
|
|
||||||
# make it user-friendly and automatically prepend "patches.addon/"
|
|
||||||
# if there is no "/"
|
|
||||||
sed -r 's|^([[:space:]]*)([^#[:space:]][^/]*)$|\1patches.addon/\2|' \
|
|
||||||
"$PATCH_DIR/patches.addon/series" >>"$series"
|
|
||||||
fi
|
|
||||||
|
|
||||||
(
|
|
||||||
echo "trap 'echo \"*** patch \$_ failed ***\"' ERR"
|
|
||||||
echo "set -ex"
|
|
||||||
"$DIR"/guards "$@" <"$series" | \
|
|
||||||
if $vanilla; then
|
|
||||||
egrep '^patches\.(kernel\.org|rpmify)/'
|
|
||||||
else
|
|
||||||
cat
|
|
||||||
fi |\
|
|
||||||
sed "s|^|patch -s -F0 -E -p1 --no-backup-if-mismatch -i $PATCH_DIR/|"
|
|
||||||
) | sh
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
164
check-kabi
164
check-kabi
@ -1,164 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
#
|
|
||||||
# check-kabi - Red Hat kABI reference checking tool
|
|
||||||
#
|
|
||||||
# We use this script to check against reference Module.kabi files.
|
|
||||||
#
|
|
||||||
# Author: Jon Masters <jcm@redhat.com>
|
|
||||||
# Copyright (C) 2007-2009 Red Hat, Inc.
|
|
||||||
#
|
|
||||||
# This software may be freely redistributed under the terms of the GNU
|
|
||||||
# General Public License (GPL).
|
|
||||||
|
|
||||||
# Changelog:
|
|
||||||
#
|
|
||||||
# 2009/08/15 - Updated for use in RHEL6.
|
|
||||||
# 2007/06/13 - Initial rewrite in python by Jon Masters.
|
|
||||||
|
|
||||||
__author__ = "Jon Masters <jcm@redhat.com>"
|
|
||||||
__version__ = "2.0"
|
|
||||||
__date__ = "2009/08/15"
|
|
||||||
__copyright__ = "Copyright (C) 2007-2009 Red Hat, Inc"
|
|
||||||
__license__ = "GPL"
|
|
||||||
|
|
||||||
import getopt
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import string
|
|
||||||
import sys
|
|
||||||
|
|
||||||
true = 1
|
|
||||||
false = 0
|
|
||||||
|
|
||||||
def load_symvers(symvers,filename):
|
|
||||||
"""Load a Module.symvers file."""
|
|
||||||
|
|
||||||
symvers_file = open(filename,"r")
|
|
||||||
|
|
||||||
while true:
|
|
||||||
in_line = symvers_file.readline()
|
|
||||||
if in_line == "":
|
|
||||||
break
|
|
||||||
if in_line == "\n":
|
|
||||||
continue
|
|
||||||
checksum,symbol,directory,type = in_line.split('\t')
|
|
||||||
|
|
||||||
symvers[symbol] = in_line[0:-1]
|
|
||||||
|
|
||||||
def load_kabi(kabi,filename):
|
|
||||||
"""Load a Module.kabi file."""
|
|
||||||
|
|
||||||
kabi_file = open(filename,"r")
|
|
||||||
|
|
||||||
while true:
|
|
||||||
in_line = kabi_file.readline()
|
|
||||||
if in_line == "":
|
|
||||||
break
|
|
||||||
if in_line == "\n":
|
|
||||||
continue
|
|
||||||
checksum,symbol,directory,type = in_line.split('\t')
|
|
||||||
|
|
||||||
kabi[symbol] = in_line[0:-1]
|
|
||||||
|
|
||||||
def check_kabi(symvers,kabi):
|
|
||||||
"""Check Module.kabi and Module.symvers files."""
|
|
||||||
|
|
||||||
fail=0
|
|
||||||
warn=0
|
|
||||||
lost=0
|
|
||||||
changed_symbols=[]
|
|
||||||
moved_symbols=[]
|
|
||||||
losted_symbols=[]
|
|
||||||
|
|
||||||
for symbol in kabi:
|
|
||||||
abi_hash,abi_sym,abi_dir,abi_type = kabi[symbol].split('\t')
|
|
||||||
if symbol in symvers:
|
|
||||||
sym_hash,sym_sym,sym_dir,sym_type = symvers[symbol].split('\t')
|
|
||||||
if abi_hash != sym_hash:
|
|
||||||
fail=1
|
|
||||||
changed_symbols.append(symbol)
|
|
||||||
|
|
||||||
if abi_dir != sym_dir:
|
|
||||||
warn=1
|
|
||||||
moved_symbols.append(symbol)
|
|
||||||
else:
|
|
||||||
lost=1
|
|
||||||
losted_symbols.append(symbol)
|
|
||||||
|
|
||||||
if fail:
|
|
||||||
print ("*** ERROR - ABI BREAKAGE WAS DETECTED ***")
|
|
||||||
print ("")
|
|
||||||
print ("The following symbols have been changed (this will cause an ABI breakage):")
|
|
||||||
print ("new kabi:")
|
|
||||||
for symbol in changed_symbols:
|
|
||||||
print (symvers[symbol])
|
|
||||||
print ("old kabi:")
|
|
||||||
for symbol in changed_symbols:
|
|
||||||
print (kabi[symbol])
|
|
||||||
print ("")
|
|
||||||
|
|
||||||
if lost:
|
|
||||||
print ("*** ERROR - ABI BREAKAGE WAS DETECTED ***")
|
|
||||||
print ("")
|
|
||||||
print ("The following symbols have been losted (this will cause an ABI breakage):")
|
|
||||||
print ("old kabi:")
|
|
||||||
for symbol in losted_symbols:
|
|
||||||
print (kabi[symbol])
|
|
||||||
print ("")
|
|
||||||
|
|
||||||
if warn:
|
|
||||||
print ("*** WARNING - ABI SYMBOLS MOVED ***")
|
|
||||||
print ("")
|
|
||||||
print ("The following symbols moved (typically caused by moving a symbol from being")
|
|
||||||
print ("provided by the kernel vmlinux out to a loadable module):")
|
|
||||||
print ("new kabi:")
|
|
||||||
for symbol in moved_symbols:
|
|
||||||
print (symvers[symbol])
|
|
||||||
print ("old kabi")
|
|
||||||
for symbol in moved_symbols:
|
|
||||||
print (kabi[symbol])
|
|
||||||
|
|
||||||
print ("")
|
|
||||||
|
|
||||||
"""Halt the build, if we got errors and/or warnings. In either case,
|
|
||||||
double-checkig is required to avoid introducing / concealing
|
|
||||||
KABI inconsistencies."""
|
|
||||||
if fail or warn or lost:
|
|
||||||
sys.exit(1)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
def usage():
|
|
||||||
print ("""
|
|
||||||
check-kabi: check Module.kabi and Module.symvers files.
|
|
||||||
|
|
||||||
check-kabi [ -k Module.kabi ] [ -s Module.symvers ]
|
|
||||||
|
|
||||||
""")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
symvers_file = ""
|
|
||||||
kabi_file = ""
|
|
||||||
|
|
||||||
opts, args = getopt.getopt(sys.argv[1:], 'hk:s:')
|
|
||||||
|
|
||||||
for o, v in opts:
|
|
||||||
if o == "-s":
|
|
||||||
symvers_file = v
|
|
||||||
if o == "-h":
|
|
||||||
usage()
|
|
||||||
sys.exit(0)
|
|
||||||
if o == "-k":
|
|
||||||
kabi_file = v
|
|
||||||
|
|
||||||
if (symvers_file == "") or (kabi_file == ""):
|
|
||||||
usage()
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
symvers={}
|
|
||||||
kabi={}
|
|
||||||
|
|
||||||
load_symvers(symvers,symvers_file)
|
|
||||||
load_kabi(kabi,kabi_file)
|
|
||||||
check_kabi(symvers,kabi)
|
|
||||||
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
# See 'cpupower help' and cpupower(1) for more info
|
|
||||||
CPUPOWER_START_OPTS="frequency-set -g performance"
|
|
||||||
CPUPOWER_STOP_OPTS="frequency-set -g ondemand"
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Configure CPU power related settings
|
|
||||||
After=syslog.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
RemainAfterExit=yes
|
|
||||||
EnvironmentFile=/etc/sysconfig/cpupower
|
|
||||||
ExecStart=/usr/bin/cpupower $CPUPOWER_START_OPTS
|
|
||||||
ExecStop=/usr/bin/cpupower $CPUPOWER_STOP_OPTS
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
@ -1,89 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# this scripts is used to patch functions for GCov in the following way
|
|
||||||
# This is style style_a
|
|
||||||
# //LCOV_EXCL_START
|
|
||||||
# void foo(void )
|
|
||||||
# {
|
|
||||||
# .......
|
|
||||||
# }
|
|
||||||
# //LCOV_EXCL_STOP
|
|
||||||
# This is style_b
|
|
||||||
# //LCOV_EXCL_START
|
|
||||||
# void
|
|
||||||
# foo(void )
|
|
||||||
# {
|
|
||||||
# ....
|
|
||||||
# }
|
|
||||||
# //LCOV_EXCL_STOP
|
|
||||||
|
|
||||||
|
|
||||||
FUNC_MAX_LINE=500
|
|
||||||
tags_file=./tags
|
|
||||||
func_records=./funcs
|
|
||||||
function_file=$1
|
|
||||||
|
|
||||||
function usage()
|
|
||||||
{
|
|
||||||
echo "Usage: sh gcov_blacklist.sh function_list_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
function func_style()
|
|
||||||
{
|
|
||||||
func="$*"
|
|
||||||
word=`echo "$func" | grep -P -o "\b.*\(" | sed "s/(//" | wc -w`
|
|
||||||
if [[ "$word" > "1" ]]; then
|
|
||||||
return 1
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# check args
|
|
||||||
[ $# != 1 ] && usage && exit
|
|
||||||
[ ! -f $function_file ] && echo "error:$function_file does not exit" && exit
|
|
||||||
[ -f $func_records ] && rm $func_records
|
|
||||||
|
|
||||||
# create tags file
|
|
||||||
[ -f $tags_file ] && rm $tags_file
|
|
||||||
ctags -R * > /dev/null
|
|
||||||
|
|
||||||
# create func regx file
|
|
||||||
count=0
|
|
||||||
while read line;
|
|
||||||
do
|
|
||||||
# line start with '#' and empty line are ignored
|
|
||||||
echo $line | grep "#" > /dev/null && continue
|
|
||||||
echo $line | grep -E "^\s?$" > /dev/null && continue
|
|
||||||
func_name=`echo "$line" | awk '{print $1}'`
|
|
||||||
grep -w $func_name $tags_file | sed -n "/;\"\tf/"p | awk -F"\t" '{print $2,$3}' | tee -a $func_records | tee > /dev/null && count=$(expr $count + 1)
|
|
||||||
done < $function_file
|
|
||||||
|
|
||||||
# add LCOV_EXCL
|
|
||||||
count=0
|
|
||||||
while read line;
|
|
||||||
do
|
|
||||||
func=`echo "$line" | cut -d " " -f1 --complement | cut -d "/" -f2`
|
|
||||||
func_style ${func}
|
|
||||||
[ $? -eq "1" ] && style="style_a" || style="style_b"
|
|
||||||
func=${func//\*/\\*}
|
|
||||||
filename=`echo "$line" | awk '{print $1}'`
|
|
||||||
# check filename
|
|
||||||
echo $filename | grep -vE "\.c$|\.h$" > /dev/null && continue
|
|
||||||
linenum=`sed -n "/${func}/,/{/=" $filename | head -n 1`
|
|
||||||
if [[ "$style" == "style_a" ]]; then
|
|
||||||
linenum=$(expr $linenum - 1)
|
|
||||||
else
|
|
||||||
linenum=$(expr $linenum - 2)
|
|
||||||
fi
|
|
||||||
sed -n ${linenum}p $filename | grep "LCOV_EXCL_START" > /dev/null || sed -i "${linenum}a\//LCOV_EXCL_START" $filename
|
|
||||||
offset=$(grep "$func" -A $FUNC_MAX_LINE $filename | grep -n -m 1 "^}" | cut -d ":" -f 1)
|
|
||||||
if [[ "$style" == "style_a" ]]; then
|
|
||||||
linenum=`expr $linenum + $offset + 1`
|
|
||||||
else
|
|
||||||
linenum=`expr $linenum + $offset + 2`
|
|
||||||
fi
|
|
||||||
sed -n ${linenum}p $filename | grep "LCOV_EXCL_STOP" > /dev/null || sed -i "${linenum}a\//LCOV_EXCL_STOP" $filename
|
|
||||||
[ $? == 0 ] && count=$(expr $count + 1)
|
|
||||||
done < $func_records
|
|
||||||
|
|
||||||
echo "done"
|
|
||||||
307
guards
307
guards
@ -1,307 +0,0 @@
|
|||||||
#!/usr/bin/perl -w
|
|
||||||
#############################################################################
|
|
||||||
# Copyright (c) 2003-2007,2009 Novell, Inc.
|
|
||||||
# All Rights Reserved.
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of version 2 of the GNU General Public License as
|
|
||||||
# published by the Free Software Foundation.
|
|
||||||
#
|
|
||||||
# This program is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
# GNU General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU General Public License
|
|
||||||
# along with this program; if not, contact Novell, Inc.
|
|
||||||
#
|
|
||||||
# To contact Novell about this file by physical or electronic mail,
|
|
||||||
# you may find current contact information at www.novell.com
|
|
||||||
#############################################################################
|
|
||||||
#
|
|
||||||
# Guards:
|
|
||||||
#
|
|
||||||
# +xxx include if xxx is defined
|
|
||||||
# -xxx exclude if xxx is defined
|
|
||||||
# +!xxx include if xxx is not defined
|
|
||||||
# -!xxx exclude if xxx is not defined
|
|
||||||
#
|
|
||||||
|
|
||||||
use FileHandle;
|
|
||||||
use Getopt::Long;
|
|
||||||
use strict;
|
|
||||||
|
|
||||||
# Prototypes
|
|
||||||
sub files_in($$);
|
|
||||||
sub parse($$);
|
|
||||||
sub help();
|
|
||||||
|
|
||||||
#sub strip_ext($) {
|
|
||||||
# local ($_) = @_;
|
|
||||||
# s/\.(diff?|patch)$//;
|
|
||||||
#}
|
|
||||||
|
|
||||||
#sub try_ext($) {
|
|
||||||
# my ($path) = @_;
|
|
||||||
# for my $p in (($path, "$path.diff", "$path.dif", "$path.patch")) {
|
|
||||||
# return $p
|
|
||||||
# if (-f $p);
|
|
||||||
# }
|
|
||||||
# return undef;
|
|
||||||
#}
|
|
||||||
|
|
||||||
sub slashme($) {
|
|
||||||
my ($dir) = @_;
|
|
||||||
$dir =~ s#([^/])$#$&/#; # append a slash if necessary
|
|
||||||
if ($dir eq './') {
|
|
||||||
return '';
|
|
||||||
} else {
|
|
||||||
return $dir;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Generate a list of files in a directory
|
|
||||||
#
|
|
||||||
sub files_in($$) {
|
|
||||||
my ($dir, $path) = @_;
|
|
||||||
my $dh = new FileHandle;
|
|
||||||
my (@files, $file);
|
|
||||||
|
|
||||||
|
|
||||||
opendir $dh, length("$dir$path") ? "$dir$path" : '.'
|
|
||||||
or die "$dir$path: $!\n";
|
|
||||||
while ($file = readdir($dh)) {
|
|
||||||
next if $file =~ /^(\.|\.\.|\.#.*|CVS|.*~)$/;
|
|
||||||
if (-d "$dir$path$file") {
|
|
||||||
@files = (@files, files_in($dir, "$path$file/"));
|
|
||||||
} else {
|
|
||||||
#print "[$path$file]\n";
|
|
||||||
push @files, "$path$file";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closedir $dh;
|
|
||||||
return @files;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse a configuration file
|
|
||||||
# Callback called with ($patch, @guards) arguments
|
|
||||||
#
|
|
||||||
sub parse($$) {
|
|
||||||
my ($fh, $callback) = @_;
|
|
||||||
|
|
||||||
my $line = "";
|
|
||||||
|
|
||||||
while (<$fh>) {
|
|
||||||
chomp;
|
|
||||||
s/(^|\s+)#.*//;
|
|
||||||
if (s/\\$/ /) {
|
|
||||||
$line .= $_;
|
|
||||||
next;
|
|
||||||
}
|
|
||||||
$line .= $_;
|
|
||||||
my @guards = ();
|
|
||||||
foreach my $token (split /[\s\t\n]+/, $line) {
|
|
||||||
next if $token eq "";
|
|
||||||
if ($token =~ /^[-+]/) {
|
|
||||||
push @guards, $token;
|
|
||||||
} else {
|
|
||||||
#print "[" . join(",", @guards) . "] $token\n";
|
|
||||||
&$callback($token, @guards);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$line = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Command line options
|
|
||||||
#
|
|
||||||
my ($dir, $config, $default, $check, $list, $invert_match, $with_guards) =
|
|
||||||
( '', '-', 1, 0, 0, 0, 0);
|
|
||||||
my @path;
|
|
||||||
|
|
||||||
# Help text
|
|
||||||
#
|
|
||||||
sub help() {
|
|
||||||
print "$0 - select from a list of files guarded by conditions\n";
|
|
||||||
print "SYNOPSIS: $0 [--prefix=dir] [--path=dir1:dir2:...]\n" .
|
|
||||||
" [--default=0|1] [--check|--list] [--invert-match]\n" .
|
|
||||||
" [--with-guards] [--config=file] symbol ...\n\n" .
|
|
||||||
" (Default values: --path='" . join(':', @path) . "', " .
|
|
||||||
"--default=$default)\n";
|
|
||||||
exit 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse command line options
|
|
||||||
#
|
|
||||||
Getopt::Long::Configure ("bundling");
|
|
||||||
eval {
|
|
||||||
unless (GetOptions (
|
|
||||||
'd|prefix=s' => \$dir,
|
|
||||||
'c|config=s' => \$config,
|
|
||||||
'C|check' => \$check,
|
|
||||||
'l|list' => \$list,
|
|
||||||
'w|with-guards' => \$with_guards,
|
|
||||||
'p|path=s' => \@path,
|
|
||||||
'D|default=i' => \$default,
|
|
||||||
'v|invert-match' => \$invert_match,
|
|
||||||
'h|help' => sub { help(); exit 0; })) {
|
|
||||||
help();
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if ($@) {
|
|
||||||
print "$@";
|
|
||||||
help();
|
|
||||||
exit 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@path = ('.')
|
|
||||||
unless (@path);
|
|
||||||
@path = split(/:/, join(':', @path));
|
|
||||||
|
|
||||||
my $fh = ($config eq '-') ? \*STDIN : new FileHandle($config)
|
|
||||||
or die "$config: $!\n";
|
|
||||||
|
|
||||||
$dir = slashme($dir);
|
|
||||||
|
|
||||||
if ($check) {
|
|
||||||
# Check for duplicate files, or for files that are not referenced by
|
|
||||||
# the specification.
|
|
||||||
|
|
||||||
my $problems = 0;
|
|
||||||
my @files;
|
|
||||||
|
|
||||||
foreach (@path) {
|
|
||||||
@files = (@files, files_in($dir, slashme($_)));
|
|
||||||
}
|
|
||||||
my %files = map { $_ => 0 } @files;
|
|
||||||
|
|
||||||
parse($fh, sub {
|
|
||||||
my ($patch, @guards) = @_;
|
|
||||||
if (exists $files{$patch}) {
|
|
||||||
$files{$patch}++;
|
|
||||||
} else {
|
|
||||||
print "Not found: $dir$patch\n";
|
|
||||||
$problems++;
|
|
||||||
}});
|
|
||||||
|
|
||||||
$fh->close();
|
|
||||||
|
|
||||||
my ($file, $ref);
|
|
||||||
while (($file, $ref) = each %files) {
|
|
||||||
next if $ref == 1;
|
|
||||||
|
|
||||||
if ($ref == 0) {
|
|
||||||
print "Unused: $file\n" if $ref == 0;
|
|
||||||
$problems++;
|
|
||||||
}
|
|
||||||
if ($ref > 1) {
|
|
||||||
print "Warning: multiple uses: $file\n" if $ref > 1;
|
|
||||||
# This is not an error if the entries are mutually exclusive...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exit $problems ? 1 : 0;
|
|
||||||
|
|
||||||
} elsif ($list) {
|
|
||||||
parse($fh, sub {
|
|
||||||
my ($patch, @guards) = @_;
|
|
||||||
print join(' ', @guards), ' '
|
|
||||||
if (@guards && $with_guards);
|
|
||||||
print "$dir$patch\n";
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
# Generate a list of patches to apply.
|
|
||||||
|
|
||||||
my %symbols = map { $_ => 1 } @ARGV;
|
|
||||||
|
|
||||||
parse($fh, sub {
|
|
||||||
my ($patch, @guards) = @_;
|
|
||||||
|
|
||||||
my $selected;
|
|
||||||
if (@guards) {
|
|
||||||
# If the first guard is -xxx, the patch is included by default;
|
|
||||||
# if it is +xxx, the patch is excluded by default.
|
|
||||||
$selected = ($guards[0] =~ /^-/);
|
|
||||||
|
|
||||||
foreach (@guards) {
|
|
||||||
/^([-+])(!?)(.*)?/
|
|
||||||
or die "Bad guard '$_'\n";
|
|
||||||
|
|
||||||
# Check if the guard matches
|
|
||||||
if (($2 eq '!' && !exists $symbols{$3}) ||
|
|
||||||
($2 eq '' && ( $3 eq '' || exists $symbols{$3}))) {
|
|
||||||
# Include or exclude
|
|
||||||
$selected = ($1 eq '+');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
# If there are no guards, use the specified default result.
|
|
||||||
$selected = $default;
|
|
||||||
}
|
|
||||||
|
|
||||||
print "$dir$patch\n"
|
|
||||||
if $selected ^ $invert_match;
|
|
||||||
});
|
|
||||||
|
|
||||||
$fh->close();
|
|
||||||
|
|
||||||
exit 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
__END__
|
|
||||||
|
|
||||||
=head1 NAME
|
|
||||||
|
|
||||||
guards - select from a list of files guarded by conditions
|
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
|
||||||
|
|
||||||
F<guards> [--prefix=F<dir>] [--path=F<dir1:dir2:...>] [--default=<0|1>]
|
|
||||||
[--check|--list] [--invert-match] [--with-guards] [--config=<file>]
|
|
||||||
I<symbol> ...
|
|
||||||
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
The script reads a configuration file that may contain so-called guards, file
|
|
||||||
names, and comments, and writes those file names that satisfy all guards to
|
|
||||||
standard output. The script takes a list of symbols as its arguments. Each line
|
|
||||||
in the configuration file is processed separately. Lines may start with a
|
|
||||||
number of guards. The following guards are defined:
|
|
||||||
|
|
||||||
=over
|
|
||||||
|
|
||||||
+I<xxx> Include the file(s) on this line if the symbol I<xxx> is defined.
|
|
||||||
|
|
||||||
-I<xxx> Exclude the file(s) on this line if the symbol I<xxx> is defined.
|
|
||||||
|
|
||||||
+!I<xxx> Include the file(s) on this line if the symbol I<xxx> is not defined.
|
|
||||||
|
|
||||||
-!I<xxx> Exclude the file(s) on this line if the symbol I<xxx> is not defined.
|
|
||||||
|
|
||||||
- Exclude this file. Used to avoid spurious I<--check> messages.
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
The guards are processed left to right. The last guard that matches determines
|
|
||||||
if the file is included. If no guard is specified, the I<--default>
|
|
||||||
setting determines if the file is included.
|
|
||||||
|
|
||||||
If no configuration file is specified, the script reads from standard input.
|
|
||||||
|
|
||||||
The I<--check> option is used to compare the specification file against the
|
|
||||||
file system. If files are referenced in the specification that do not exist, or
|
|
||||||
if files are not enlisted in the specification file warnings are printed. The
|
|
||||||
I<--path> option can be used to specify which directory or directories to scan.
|
|
||||||
Multiple directories are eparated by a colon (C<:>) character. The
|
|
||||||
I<--prefix> option specifies the location of the files.
|
|
||||||
|
|
||||||
Use I<--list> to list all files independend of any rules. Use I<--invert-match>
|
|
||||||
to list only the excluded patches. Use I<--with-guards> to also include all
|
|
||||||
inclusion and exclusion rules.
|
|
||||||
|
|
||||||
=head1 AUTHOR
|
|
||||||
|
|
||||||
Andreas Gruenbacher <agruen@suse.de>, SUSE Labs
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
7904
kernel-rt.spec
7904
kernel-rt.spec
File diff suppressed because it is too large
Load Diff
14586
kernel.spec
14586
kernel.spec
File diff suppressed because it is too large
Load Diff
@ -1,101 +0,0 @@
|
|||||||
# arch/arm64/kvm/guest.c
|
|
||||||
kvm_arch_vcpu_ioctl_get_regs
|
|
||||||
kvm_arch_vcpu_ioctl_set_regs
|
|
||||||
kvm_arch_vcpu_ioctl_get_sregs
|
|
||||||
kvm_arch_vcpu_ioctl_set_sregs
|
|
||||||
kvm_arch_vcpu_ioctl_get_fpu
|
|
||||||
kvm_arch_vcpu_ioctl_set_fpu
|
|
||||||
kvm_arch_vcpu_ioctl_translate
|
|
||||||
kvm_arm_vcpu_arch_get_attr
|
|
||||||
kvm_arch_vcpu_ioctl_set_guest_debug
|
|
||||||
|
|
||||||
# arch/arm64/kvm/inject_fault.c
|
|
||||||
prepare_fault32
|
|
||||||
inject_undef32
|
|
||||||
inject_abt32
|
|
||||||
|
|
||||||
# virt/kvm/eventfd.c
|
|
||||||
irqfd_resampler_ack
|
|
||||||
irqfd_resampler_shutdown
|
|
||||||
kvm_irq_has_notifier
|
|
||||||
kvm_register_irq_ack_notifier
|
|
||||||
kvm_irqfd_exit
|
|
||||||
|
|
||||||
# virt/kvm/kvm_main.c
|
|
||||||
ack_flush
|
|
||||||
kvm_reload_remote_mmus
|
|
||||||
kvm_make_mclock_inprogress_request
|
|
||||||
kvm_make_scan_ioapic_request
|
|
||||||
kvm_get_dirty_log
|
|
||||||
kvm_largepages_enabled
|
|
||||||
kvm_disable_largepages
|
|
||||||
kvm_host_page_size
|
|
||||||
gfn_to_hva
|
|
||||||
kvm_vcpu_gfn_to_hva
|
|
||||||
kvm_vcpu_gfn_to_hva_prot
|
|
||||||
kvm_vcpu_gfn_to_pfn_atomic
|
|
||||||
kvm_vcpu_gfn_to_page
|
|
||||||
kvm_vcpu_gfn_to_pfn
|
|
||||||
kvm_pfn_to_page
|
|
||||||
gfn_to_page
|
|
||||||
gfn_to_pfn
|
|
||||||
kvm_vcpu_gfn_to_pfn_atomic
|
|
||||||
gfn_to_pfn_memslot_atomic
|
|
||||||
gfn_to_pfn_atomic
|
|
||||||
kvm_vcpu_gfn_to_pfn_atomic
|
|
||||||
gfn_to_page_many_atomic
|
|
||||||
kvm_release_page_clean
|
|
||||||
kvm_release_page_dirty
|
|
||||||
kvm_release_pfn_dirty
|
|
||||||
kvm_vcpu_read_guest_page
|
|
||||||
kvm_vcpu_read_guest
|
|
||||||
kvm_read_guest_atomic
|
|
||||||
kvm_vcpu_read_guest_atomic
|
|
||||||
__kvm_read_guest_atomic
|
|
||||||
kvm_vcpu_write_guest
|
|
||||||
kvm_vcpu_write_guest_page
|
|
||||||
kvm_gfn_to_hva_cache_init
|
|
||||||
kvm_write_guest_cached
|
|
||||||
kvm_read_guest_cached
|
|
||||||
kvm_clear_guest_page
|
|
||||||
kvm_clear_guest
|
|
||||||
kvm_vcpu_mark_page_dirty
|
|
||||||
kvm_vcpu_compat_ioctl
|
|
||||||
kvm_device_from_filp
|
|
||||||
kvm_unregister_device_ops
|
|
||||||
kvm_vm_compat_ioctl
|
|
||||||
kvm_reboot
|
|
||||||
kvm_io_bus_write_cookie
|
|
||||||
vm_stat_get_per_vm
|
|
||||||
vm_stat_get_per_vm_open
|
|
||||||
vm_stat_get
|
|
||||||
kvm_suspend
|
|
||||||
kvm_resume
|
|
||||||
kvm_exit
|
|
||||||
|
|
||||||
# virt/kvm/arm/arm.c
|
|
||||||
kvm_arch_vcpu_destroy
|
|
||||||
kvm_arch_vcpu_free
|
|
||||||
kvm_arch_exit
|
|
||||||
kvm_perf_teardown
|
|
||||||
|
|
||||||
# virt/kvm/arm/mmu.c
|
|
||||||
create_hyp_io_mappings
|
|
||||||
|
|
||||||
# virt/kvm/arm/psci.c
|
|
||||||
kvm_psci_0_1_call
|
|
||||||
|
|
||||||
# virt/kvm/arm/vgic/vgic-v2.c
|
|
||||||
vgic_v2_probe
|
|
||||||
vgic_v2_enable
|
|
||||||
vgic_v2_set_vmcr
|
|
||||||
vgic_v2_clear_lr
|
|
||||||
vgic_v2_populate_lr
|
|
||||||
vgic_v2_fold_lr_state
|
|
||||||
vgic_v2_set_underflow
|
|
||||||
vgic_v2_process_maintenance
|
|
||||||
vgic_v2_init_lrs
|
|
||||||
|
|
||||||
# virt/kvm/arm/vgic/vgic.c
|
|
||||||
vgic_irq_release
|
|
||||||
|
|
||||||
@ -1 +0,0 @@
|
|||||||
nil
|
|
||||||
BIN
llvm-for-oE-17.0.6-2503.0.1.tar.gz
Normal file
BIN
llvm-for-oE-17.0.6-2503.0.1.tar.gz
Normal file
Binary file not shown.
2791
llvm-toolset-17.spec
Normal file
2791
llvm-toolset-17.spec
Normal file
File diff suppressed because it is too large
Load Diff
4
llvm-toolset-17.yaml
Normal file
4
llvm-toolset-17.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
version_control: github
|
||||||
|
src_repo: llvm/llvm-project
|
||||||
|
tag_prefix: ^llvmorg-
|
||||||
|
seperator: .
|
||||||
@ -1,98 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#This script is used for creating a new grub menu item when update kernel.
|
|
||||||
#It uses the new version-number as the id and display.
|
|
||||||
|
|
||||||
NEW_KERN_VERSION=$1
|
|
||||||
GRUB_CFG=$2
|
|
||||||
OP_TYPE=$3
|
|
||||||
|
|
||||||
#########################################################
|
|
||||||
# Description: SetupOS_Initrd_for_softraid
|
|
||||||
# Input none
|
|
||||||
# Return: 0: SUCCESS
|
|
||||||
# 1: Internal Error.
|
|
||||||
#########################################################
|
|
||||||
function SoftRaid_Initrd()
|
|
||||||
{
|
|
||||||
SI_INITRD=initramfs-${NEW_KERN_VERSION}.img
|
|
||||||
mkdir -p /initramfs/usr/lib/systemd/system
|
|
||||||
mkdir -p /initramfs/etc/systemd/system/default.target.wants
|
|
||||||
mdadm --detail --scan >> /initramfs/etc/mdadm.conf
|
|
||||||
|
|
||||||
cd /initramfs
|
|
||||||
cat <<EOF > /initramfs/usr/lib/systemd/assemble-md
|
|
||||||
#!/bin/bash
|
|
||||||
declare -i count=5
|
|
||||||
if [ -f /etc/mdadm.conf ];then
|
|
||||||
while (( count > 0 )) ;
|
|
||||||
do
|
|
||||||
sleep 10s
|
|
||||||
let count--;
|
|
||||||
if [ -e "/dev/sda1" ];then
|
|
||||||
mdadm -A -s
|
|
||||||
break;
|
|
||||||
fi
|
|
||||||
echo " waiting harddisk get online .... countdown ${count} "
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
EOF
|
|
||||||
if [ $? -ne 0 ];then
|
|
||||||
g_Log_Error "generate assemble-md failed"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
chmod -R 755 /initramfs/usr/lib/systemd/assemble-md
|
|
||||||
cat << EOF > /initramfs/usr/lib/systemd/system/assemble-md.service
|
|
||||||
[Unit]
|
|
||||||
Description=assemble the md
|
|
||||||
DefaultDependencies=no
|
|
||||||
After=local-fs-pre.target systemd-udev-trigger.service systemd-udevd.service systemd-udevd-control.socket systemd-udevd-kernel.socket
|
|
||||||
Before=local-fs.target diskconf-reload.service
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Type=oneshot
|
|
||||||
RemainAfterExit=yes
|
|
||||||
ExecStart=/usr/lib/systemd/assemble-md
|
|
||||||
StandardOutput=journal+console
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=default.target
|
|
||||||
EOF
|
|
||||||
if [ $? -ne 0 ];then
|
|
||||||
g_Log_Error "generate assemble-md.service failed"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp /initramfs/usr/lib/systemd/system/assemble-md.service /initramfs/etc/systemd/system/default.target.wants/
|
|
||||||
dracut --force --include /initramfs / /boot/${SI_INITRD} ${NEW_KERN_VERSION}
|
|
||||||
rm -r /initramfs
|
|
||||||
cd -
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ "x${NEW_KERN_VERSION}" == "x" ] || [ "x${GRUB_CFG}" == "x" ] || [ "x${OP_TYPE}" == "x" ] ; then
|
|
||||||
echo "There some mkgrub-menu parameter is null,please check "
|
|
||||||
exit 1;
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "update" = "${OP_TYPE}" ]; then
|
|
||||||
|
|
||||||
DEF_VER=`grep -nr "default=" $GRUB_CFG|awk -F = '{print $2}'` ;
|
|
||||||
START_LN=`grep -nr " --id ${DEF_VER}" $GRUB_CFG|awk -F: '{print $1}'` ;
|
|
||||||
/bin/sed -rn "p;${START_LN},/}/H;$ {g;s/^\n//;p}" $GRUB_CFG > tempfile ;
|
|
||||||
/bin/sed -i "$[START_LN+5],/ --id ${DEF_VER}/{s/ --id ${DEF_VER}/ --id linux-${NEW_KERN_VERSION}/}" tempfile ;
|
|
||||||
OLDLABLE=`sed -n "$[START_LN+5],/ --id ${DEF_VER}/p" tempfile |grep menuentry |tail -1 |awk '{print $2}' |sed "s/\"//g" `
|
|
||||||
/bin/sed -i "$[START_LN+5],/ --id ${DEF_VER}/{s/${OLDLABLE}/EulerOS-${NEW_KERN_VERSION}/}" tempfile ;
|
|
||||||
/bin/sed -i "/ --id linux-${NEW_KERN_VERSION}/,/}/{s/`uname -r`/${NEW_KERN_VERSION}/} " tempfile ;
|
|
||||||
/bin/sed -i "s/default=${DEF_VER}/default=linux-${NEW_KERN_VERSION}/" tempfile ;
|
|
||||||
mv tempfile $GRUB_CFG
|
|
||||||
|
|
||||||
if [ `cat /proc/mdstat |wc -l ` -gt 2 ]; then
|
|
||||||
SoftRaid_Initrd > /dev/null 2>&1
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "remove" = "${OP_TYPE}" ]; then
|
|
||||||
/bin/sed -i "/ --id linux-${NEW_KERN_VERSION}/,/}/d" $GRUB_CFG
|
|
||||||
DEF_VER=`grep -nr "menuentry" $GRUB_CFG |head -1 |awk '{print $4}' |sed "s/{//g" `
|
|
||||||
/bin/sed -i "s/default=linux-${NEW_KERN_VERSION}/default=${DEF_VER}/" $GRUB_CFG
|
|
||||||
fi
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
|
|
||||||
index 8717ffe01..7086ed5b1 100644
|
|
||||||
--- a/arch/arm64/configs/openeuler_defconfig
|
|
||||||
+++ b/arch/arm64/configs/openeuler_defconfig
|
|
||||||
@@ -73,8 +73,9 @@ CONFIG_NO_HZ_FULL=y
|
|
||||||
CONFIG_NO_HZ=y
|
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
|
||||||
# CONFIG_PREEMPT_NONE is not set
|
|
||||||
-CONFIG_PREEMPT_VOLUNTARY=y
|
|
||||||
+# CONFIG_PREEMPT_VOLUNTARY is not set
|
|
||||||
# CONFIG_PREEMPT is not set
|
|
||||||
+CONFIG_PREEMPT_RT_FULL=y
|
|
||||||
|
|
||||||
#
|
|
||||||
# CPU/Task time and stats accounting
|
|
||||||
@@ -988,7 +989,7 @@ CONFIG_FRAME_VECTOR=y
|
|
||||||
# CONFIG_PERCPU_STATS is not set
|
|
||||||
# CONFIG_GUP_BENCHMARK is not set
|
|
||||||
CONFIG_ARCH_HAS_PTE_SPECIAL=y
|
|
||||||
-CONFIG_PIN_MEMORY=y
|
|
||||||
+# CONFIG_PIN_MEMORY is not set
|
|
||||||
CONFIG_PID_RESERVE=y
|
|
||||||
CONFIG_NET=y
|
|
||||||
CONFIG_COMPAT_NETLINK_MESSAGES=y
|
|
||||||
diff --git a/arch/x86/configs/openeuler_defconfig b/arch/x86/configs/openeuler_defconfig
|
|
||||||
index 64f0805a5..a791ac897 100644
|
|
||||||
--- a/arch/x86/configs/openeuler_defconfig
|
|
||||||
+++ b/arch/x86/configs/openeuler_defconfig
|
|
||||||
@@ -78,8 +78,9 @@ CONFIG_NO_HZ_FULL=y
|
|
||||||
CONFIG_NO_HZ=y
|
|
||||||
CONFIG_HIGH_RES_TIMERS=y
|
|
||||||
# CONFIG_PREEMPT_NONE is not set
|
|
||||||
-CONFIG_PREEMPT_VOLUNTARY=y
|
|
||||||
+# CONFIG_PREEMPT_VOLUNTARY is not set
|
|
||||||
# CONFIG_PREEMPT is not set
|
|
||||||
+CONFIG_PREEMPT_RT_FULL=y
|
|
||||||
|
|
||||||
#
|
|
||||||
# CPU/Task time and stats accounting
|
|
||||||
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
|
|
||||||
index 4c90438fc..5d2fc5be5 100644
|
|
||||||
--- a/kernel/printk/printk.c
|
|
||||||
+++ b/kernel/printk/printk.c
|
|
||||||
@@ -1846,6 +1846,8 @@ static int console_trylock_spinning(void)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
+void zap_locks(void) {}
|
|
||||||
+
|
|
||||||
static int console_trylock_spinning(void)
|
|
||||||
{
|
|
||||||
return console_trylock();
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,52 +0,0 @@
|
|||||||
From fc96a37739f1017fb91a0339f7f9b101704ca130 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dongdong Liu <liudongdong3@huawei.com>
|
|
||||||
Date: Tue, 18 Jan 2022 17:21:17 +0800
|
|
||||||
Subject: [PATCH 01/19] PCI: Support BAR sizes up to 8TB
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.18-rc1
|
|
||||||
commit 3dc8a1f6f64481a8a5a669633e880f26dae0d752
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I6XOIU
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3dc8a1f6f64481a8a5a669633e880f26dae0d752
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Current kernel reports that BARs larger than 128GB, e.g., this 4TB BAR, are
|
|
||||||
disabled:
|
|
||||||
|
|
||||||
pci 0000:01:00.0: disabling BAR 4: [mem 0x00000000-0x3ffffffffff 64bit pref] (bad alignment 0x40000000000)
|
|
||||||
|
|
||||||
Increase the maximum BAR size from 128GB to 8TB for future expansion.
|
|
||||||
|
|
||||||
[bhelgaas: commit log]
|
|
||||||
Link: https://lore.kernel.org/r/20220118092117.10089-1-liudongdong3@huawei.com
|
|
||||||
Signed-off-by: Dongdong Liu <liudongdong3@huawei.com>
|
|
||||||
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
|
|
||||||
Signed-off-by: huangfangrun <huangfangrun1@h-partners.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/pci/setup-bus.c
|
|
||||||
---
|
|
||||||
drivers/pci/setup-bus.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
|
|
||||||
index 39d19302f3cb..426d21c1db31 100644
|
|
||||||
--- a/drivers/pci/setup-bus.c
|
|
||||||
+++ b/drivers/pci/setup-bus.c
|
|
||||||
@@ -968,7 +968,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask,
|
|
||||||
{
|
|
||||||
struct pci_dev *dev;
|
|
||||||
resource_size_t min_align, align, size, size0, size1;
|
|
||||||
- resource_size_t aligns[18]; /* Alignments from 1Mb to 128Gb */
|
|
||||||
+ resource_size_t aligns[24]; /* Alignments from 1MB to 8TB */
|
|
||||||
int order, max_order;
|
|
||||||
struct resource *b_res = find_free_bus_resource(bus,
|
|
||||||
mask | IORESOURCE_PREFETCH, type);
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,186 +0,0 @@
|
|||||||
From adb665e7ecae8d4e3f48634e8c0db291d0826aff Mon Sep 17 00:00:00 2001
|
|
||||||
From: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
|
|
||||||
Date: Wed, 29 Apr 2020 15:36:40 +0200
|
|
||||||
Subject: [PATCH 02/19] iommu: Add def_domain_type() callback in iommu_ops
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.8-rc1
|
|
||||||
commit 4cbf38511a007867def958872203ae8adb8e2351
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RP8T
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4cbf38511a007867def958872203ae8adb8e2351
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Some devices are reqired to use a specific type (identity or dma)
|
|
||||||
of default domain when they are used with a vendor iommu. When the
|
|
||||||
system level default domain type is different from it, the vendor
|
|
||||||
iommu driver has to request a new default domain with
|
|
||||||
iommu_request_dma_domain_for_dev() and iommu_request_dm_for_dev()
|
|
||||||
in the add_dev() callback. Unfortunately, these two helpers only
|
|
||||||
work when the group hasn't been assigned to any other devices,
|
|
||||||
hence, some vendor iommu driver has to use a private domain if
|
|
||||||
it fails to request a new default one.
|
|
||||||
|
|
||||||
This adds def_domain_type() callback in the iommu_ops, so that
|
|
||||||
any special requirement of default domain for a device could be
|
|
||||||
aware by the iommu generic layer.
|
|
||||||
|
|
||||||
Signed-off-by: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
|
|
||||||
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
|
|
||||||
[ jroedel@suse.de: Added iommu_get_def_domain_type() function and use
|
|
||||||
it to allocate the default domain ]
|
|
||||||
Co-developed-by: Joerg Roedel <jroedel@suse.de>
|
|
||||||
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
|
||||||
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
|
|
||||||
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
|
|
||||||
Link: https://lore.kernel.org/r/20200429133712.31431-3-joro@8bytes.org
|
|
||||||
Signed-off-by: Joerg Roedel <jroedel@suse.de>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/iommu/iommu.c
|
|
||||||
include/linux/iommu.h
|
|
||||||
---
|
|
||||||
drivers/iommu/arm-smmu-v3.c | 7 ++-----
|
|
||||||
drivers/iommu/arm-smmu.c | 8 +-------
|
|
||||||
drivers/iommu/iommu.c | 22 ++++++++++++++--------
|
|
||||||
include/linux/iommu.h | 2 --
|
|
||||||
4 files changed, 17 insertions(+), 22 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
|
|
||||||
index 05cb92da6836..5029d9af1100 100644
|
|
||||||
--- a/drivers/iommu/arm-smmu-v3.c
|
|
||||||
+++ b/drivers/iommu/arm-smmu-v3.c
|
|
||||||
@@ -3067,9 +3067,9 @@ static void arm_smmu_put_resv_regions(struct device *dev,
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
static int arm_smmu_device_domain_type(struct device *dev, unsigned int *type)
|
|
||||||
{
|
|
||||||
+#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
int i;
|
|
||||||
struct pci_dev *pdev;
|
|
||||||
|
|
||||||
@@ -3086,10 +3086,9 @@ static int arm_smmu_device_domain_type(struct device *dev, unsigned int *type)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-
|
|
||||||
+#endif
|
|
||||||
return -ERANGE;
|
|
||||||
}
|
|
||||||
-#endif
|
|
||||||
|
|
||||||
static struct iommu_ops arm_smmu_ops = {
|
|
||||||
.capable = arm_smmu_capable,
|
|
||||||
@@ -3118,9 +3117,7 @@ static struct iommu_ops arm_smmu_ops = {
|
|
||||||
.get_resv_regions = arm_smmu_get_resv_regions,
|
|
||||||
.put_resv_regions = arm_smmu_put_resv_regions,
|
|
||||||
.pgsize_bitmap = -1UL, /* Restricted during device attach */
|
|
||||||
-#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
.device_domain_type = arm_smmu_device_domain_type,
|
|
||||||
-#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Probing and initialisation functions */
|
|
||||||
diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
|
|
||||||
index d1c00b1dfd2e..01ab7c990a58 100644
|
|
||||||
--- a/drivers/iommu/arm-smmu.c
|
|
||||||
+++ b/drivers/iommu/arm-smmu.c
|
|
||||||
@@ -1632,8 +1632,6 @@ static void arm_smmu_put_resv_regions(struct device *dev,
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
-#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
-
|
|
||||||
#ifdef CONFIG_ARCH_PHYTIUM
|
|
||||||
static int phytium_smmu_def_domain_type(struct device *dev, unsigned int *type)
|
|
||||||
{
|
|
||||||
@@ -1651,8 +1649,6 @@ static inline int phytium_smmu_def_domain_type(struct device *dev, unsigned int
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
static struct iommu_ops arm_smmu_ops = {
|
|
||||||
.capable = arm_smmu_capable,
|
|
||||||
.domain_alloc = arm_smmu_domain_alloc,
|
|
||||||
@@ -1672,9 +1668,7 @@ static struct iommu_ops arm_smmu_ops = {
|
|
||||||
.get_resv_regions = arm_smmu_get_resv_regions,
|
|
||||||
.put_resv_regions = arm_smmu_put_resv_regions,
|
|
||||||
.pgsize_bitmap = -1UL, /* Restricted during device attach */
|
|
||||||
-#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
- .device_domain_type = phytium_smmu_def_domain_type,
|
|
||||||
-#endif
|
|
||||||
+ .device_domain_type = phytium_smmu_def_domain_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
|
|
||||||
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
|
|
||||||
index 1c39d1b8a80a..eb141afbec67 100644
|
|
||||||
--- a/drivers/iommu/iommu.c
|
|
||||||
+++ b/drivers/iommu/iommu.c
|
|
||||||
@@ -1260,6 +1260,17 @@ struct iommu_group *pci_device_group(struct device *dev)
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(pci_device_group);
|
|
||||||
|
|
||||||
+static int iommu_get_def_domain_type(struct device *dev)
|
|
||||||
+{
|
|
||||||
+ const struct iommu_ops *ops = dev->bus->iommu_ops;
|
|
||||||
+ unsigned int type = 0;
|
|
||||||
+
|
|
||||||
+ if (ops->device_domain_type)
|
|
||||||
+ ops->device_domain_type(dev, &type);
|
|
||||||
+
|
|
||||||
+ return (type == 0) ? iommu_def_domain_type : type;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* iommu_group_get_for_dev - Find or create the IOMMU group for a device
|
|
||||||
* @dev: target device
|
|
||||||
@@ -1298,20 +1309,15 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
|
|
||||||
if (!group->default_domain) {
|
|
||||||
struct iommu_domain *dom;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
- /* direct allocate required default domain type for some specific devices. */
|
|
||||||
- if (ops->device_domain_type) {
|
|
||||||
- if (ops->device_domain_type(dev, &type))
|
|
||||||
- type = iommu_def_domain_type;
|
|
||||||
- }
|
|
||||||
-#endif
|
|
||||||
+ type = iommu_get_def_domain_type(dev);
|
|
||||||
+
|
|
||||||
dom = __iommu_domain_alloc(dev->bus, type);
|
|
||||||
if (!dom && type != IOMMU_DOMAIN_DMA) {
|
|
||||||
dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
|
|
||||||
if (dom) {
|
|
||||||
dev_warn(dev,
|
|
||||||
"failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
|
|
||||||
- iommu_def_domain_type);
|
|
||||||
+ type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
|
|
||||||
index d44f3a6762be..790834df8525 100644
|
|
||||||
--- a/include/linux/iommu.h
|
|
||||||
+++ b/include/linux/iommu.h
|
|
||||||
@@ -363,11 +363,9 @@ struct iommu_ops {
|
|
||||||
|
|
||||||
unsigned long pgsize_bitmap;
|
|
||||||
|
|
||||||
-#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
#ifndef __GENKSYMS__
|
|
||||||
int (*device_domain_type)(struct device *dev, unsigned int *type);
|
|
||||||
#endif
|
|
||||||
-#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
From f88b39a83ba13280ccef443533b43b53d8d464dd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Date: Thu, 29 Sep 2022 22:01:00 +0800
|
|
||||||
Subject: [PATCH 03/19] iommu/arm-smmu-v3: Make default domain type of
|
|
||||||
HiSilicon PTT device to identity
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v6.1-rc1
|
|
||||||
commit 24b6c7798a0122012ca848ea0d25e973334266b0
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RP8T
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git/commit/?id=24b6c7798a0122012ca848ea0d25e973334266b0
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The DMA operations of HiSilicon PTT device can only work properly with
|
|
||||||
identical mappings. So add a quirk for the device to force the domain
|
|
||||||
as passthrough.
|
|
||||||
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20220816114414.4092-2-yangyicong@huawei.com
|
|
||||||
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
|
|
||||||
Reviewed-by: Hanjun Guo <guohanjun@huawei.com>
|
|
||||||
Reviewed-by: Jay Fang <f.fangjian@huawei.com>
|
|
||||||
Acked-by: Xie XiuQi <xiexiuqi@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
|
|
||||||
---
|
|
||||||
drivers/iommu/arm-smmu-v3.c | 16 +++++++++++++++-
|
|
||||||
1 file changed, 15 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
|
|
||||||
index 5029d9af1100..a11f5f03fcd0 100644
|
|
||||||
--- a/drivers/iommu/arm-smmu-v3.c
|
|
||||||
+++ b/drivers/iommu/arm-smmu-v3.c
|
|
||||||
@@ -3067,9 +3067,16 @@ static void arm_smmu_put_resv_regions(struct device *dev,
|
|
||||||
kfree(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * HiSilicon PCIe tune and trace device can be used to trace TLP headers on the
|
|
||||||
+ * PCIe link and save the data to memory by DMA. The hardware is restricted to
|
|
||||||
+ * use identity mapping only.
|
|
||||||
+ */
|
|
||||||
+#define IS_HISI_PTT_DEVICE(pdev) ((pdev)->vendor == PCI_VENDOR_ID_HUAWEI && \
|
|
||||||
+ (pdev)->device == 0xa12e)
|
|
||||||
+
|
|
||||||
static int arm_smmu_device_domain_type(struct device *dev, unsigned int *type)
|
|
||||||
{
|
|
||||||
-#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
int i;
|
|
||||||
struct pci_dev *pdev;
|
|
||||||
|
|
||||||
@@ -3077,6 +3084,13 @@ static int arm_smmu_device_domain_type(struct device *dev, unsigned int *type)
|
|
||||||
return -ERANGE;
|
|
||||||
|
|
||||||
pdev = to_pci_dev(dev);
|
|
||||||
+
|
|
||||||
+ if (IS_HISI_PTT_DEVICE(pdev)) {
|
|
||||||
+ *type = IOMMU_DOMAIN_IDENTITY;
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
for (i = 0; i < smmu_bypass_devices_num; i++) {
|
|
||||||
if ((smmu_bypass_devices[i].vendor == pdev->vendor)
|
|
||||||
&& (smmu_bypass_devices[i].device == pdev->device)) {
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
From 6f5496b19beae6c819d9a9d719e71b4af578c936 Mon Sep 17 00:00:00 2001
|
|
||||||
From: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
Date: Tue, 24 Oct 2023 19:41:44 +0800
|
|
||||||
Subject: [PATCH 04/19] iommu/arm-smmu-v3: Integrate the function for obtain
|
|
||||||
the device domain type in bypass mode
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: cleanup
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RP8T
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
|
|
||||||
When the CONFIG_SMMU_BYPASS_DEV macro is enabled, the obtaining of domain
|
|
||||||
type is encapsulated as a function as a step in arm_smmu_device_domian_type
|
|
||||||
function. So that the code is clearer and easier to call later.
|
|
||||||
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/iommu/arm-smmu-v3.c | 31 +++++++++++++++++++++----------
|
|
||||||
1 file changed, 21 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
|
|
||||||
index a11f5f03fcd0..66fab92a3e26 100644
|
|
||||||
--- a/drivers/iommu/arm-smmu-v3.c
|
|
||||||
+++ b/drivers/iommu/arm-smmu-v3.c
|
|
||||||
@@ -3075,9 +3075,27 @@ static void arm_smmu_put_resv_regions(struct device *dev,
|
|
||||||
#define IS_HISI_PTT_DEVICE(pdev) ((pdev)->vendor == PCI_VENDOR_ID_HUAWEI && \
|
|
||||||
(pdev)->device == 0xa12e)
|
|
||||||
|
|
||||||
-static int arm_smmu_device_domain_type(struct device *dev, unsigned int *type)
|
|
||||||
+#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
+static int arm_smmu_bypass_dev_domain_type(struct device *dev)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
+ struct pci_dev *pdev = to_pci_dev(dev);
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < smmu_bypass_devices_num; i++) {
|
|
||||||
+ if ((smmu_bypass_devices[i].vendor == pdev->vendor) &&
|
|
||||||
+ (smmu_bypass_devices[i].device == pdev->device)) {
|
|
||||||
+ dev_info(dev, "device 0x%hx:0x%hx uses identity mapping.",
|
|
||||||
+ pdev->vendor, pdev->device);
|
|
||||||
+ return IOMMU_DOMAIN_IDENTITY;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+static int arm_smmu_device_domain_type(struct device *dev, unsigned int *type)
|
|
||||||
+{
|
|
||||||
struct pci_dev *pdev;
|
|
||||||
|
|
||||||
if (!dev_is_pci(dev))
|
|
||||||
@@ -3091,15 +3109,8 @@ static int arm_smmu_device_domain_type(struct device *dev, unsigned int *type)
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMMU_BYPASS_DEV
|
|
||||||
- for (i = 0; i < smmu_bypass_devices_num; i++) {
|
|
||||||
- if ((smmu_bypass_devices[i].vendor == pdev->vendor)
|
|
||||||
- && (smmu_bypass_devices[i].device == pdev->device)) {
|
|
||||||
- dev_info(dev, "device 0x%hx:0x%hx uses identity mapping.",
|
|
||||||
- pdev->vendor, pdev->device);
|
|
||||||
- *type = IOMMU_DOMAIN_IDENTITY;
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
- }
|
|
||||||
+ *type = arm_smmu_bypass_dev_domain_type(dev);
|
|
||||||
+ return 0;
|
|
||||||
#endif
|
|
||||||
return -ERANGE;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,134 +0,0 @@
|
|||||||
From b5fad44d7353231e773cce3b45f37c4bf932b7de Mon Sep 17 00:00:00 2001
|
|
||||||
From: Thomas Gleixner <tglx@linutronix.de>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:10 +0800
|
|
||||||
Subject: [PATCH 05/19] genirq: Export affinity setter for modules
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.14-rc1
|
|
||||||
commit 4d80d6ca5d77fde9880da8466e5b64f250e5bf82
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RP8T
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4d80d6ca5d77fde9880da8466e5b64f250e5bf82
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Perf modules abuse irq_set_affinity_hint() to set the affinity of system
|
|
||||||
PMU interrupts just because irq_set_affinity() was not exported.
|
|
||||||
|
|
||||||
The fact that irq_set_affinity_hint() actually sets the affinity is a
|
|
||||||
non-documented side effect and the name is clearly saying it's a hint.
|
|
||||||
|
|
||||||
To clean this up, export the real affinity setter.
|
|
||||||
|
|
||||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
||||||
Acked-by: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Link: https://lore.kernel.org/r/20210518093117.968251441@linutronix.de
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
---
|
|
||||||
include/linux/interrupt.h | 35 ++---------------------------------
|
|
||||||
kernel/irq/manage.c | 33 ++++++++++++++++++++++++++++++++-
|
|
||||||
2 files changed, 34 insertions(+), 34 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
|
|
||||||
index 97de36a38770..9c60dc87963a 100644
|
|
||||||
--- a/include/linux/interrupt.h
|
|
||||||
+++ b/include/linux/interrupt.h
|
|
||||||
@@ -277,39 +277,8 @@ struct irq_affinity {
|
|
||||||
|
|
||||||
extern cpumask_var_t irq_default_affinity;
|
|
||||||
|
|
||||||
-/* Internal implementation. Use the helpers below */
|
|
||||||
-extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask,
|
|
||||||
- bool force);
|
|
||||||
-
|
|
||||||
-/**
|
|
||||||
- * irq_set_affinity - Set the irq affinity of a given irq
|
|
||||||
- * @irq: Interrupt to set affinity
|
|
||||||
- * @cpumask: cpumask
|
|
||||||
- *
|
|
||||||
- * Fails if cpumask does not contain an online CPU
|
|
||||||
- */
|
|
||||||
-static inline int
|
|
||||||
-irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
|
||||||
-{
|
|
||||||
- return __irq_set_affinity(irq, cpumask, false);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/**
|
|
||||||
- * irq_force_affinity - Force the irq affinity of a given irq
|
|
||||||
- * @irq: Interrupt to set affinity
|
|
||||||
- * @cpumask: cpumask
|
|
||||||
- *
|
|
||||||
- * Same as irq_set_affinity, but without checking the mask against
|
|
||||||
- * online cpus.
|
|
||||||
- *
|
|
||||||
- * Solely for low level cpu hotplug code, where we need to make per
|
|
||||||
- * cpu interrupts affine before the cpu becomes online.
|
|
||||||
- */
|
|
||||||
-static inline int
|
|
||||||
-irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
|
|
||||||
-{
|
|
||||||
- return __irq_set_affinity(irq, cpumask, true);
|
|
||||||
-}
|
|
||||||
+extern int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask);
|
|
||||||
+extern int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask);
|
|
||||||
|
|
||||||
extern int irq_can_set_affinity(unsigned int irq);
|
|
||||||
extern int irq_select_affinity(unsigned int irq);
|
|
||||||
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
|
|
||||||
index 163712c76520..f4c0e509d74f 100644
|
|
||||||
--- a/kernel/irq/manage.c
|
|
||||||
+++ b/kernel/irq/manage.c
|
|
||||||
@@ -331,7 +331,8 @@ int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask,
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force)
|
|
||||||
+static int __irq_set_affinity(unsigned int irq, const struct cpumask *mask,
|
|
||||||
+ bool force)
|
|
||||||
{
|
|
||||||
struct irq_desc *desc = irq_to_desc(irq);
|
|
||||||
unsigned long flags;
|
|
||||||
@@ -346,6 +347,36 @@ int __irq_set_affinity(unsigned int irq, const struct cpumask *mask, bool force)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * irq_set_affinity - Set the irq affinity of a given irq
|
|
||||||
+ * @irq: Interrupt to set affinity
|
|
||||||
+ * @cpumask: cpumask
|
|
||||||
+ *
|
|
||||||
+ * Fails if cpumask does not contain an online CPU
|
|
||||||
+ */
|
|
||||||
+int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
|
|
||||||
+{
|
|
||||||
+ return __irq_set_affinity(irq, cpumask, false);
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(irq_set_affinity);
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * irq_force_affinity - Force the irq affinity of a given irq
|
|
||||||
+ * @irq: Interrupt to set affinity
|
|
||||||
+ * @cpumask: cpumask
|
|
||||||
+ *
|
|
||||||
+ * Same as irq_set_affinity, but without checking the mask against
|
|
||||||
+ * online cpus.
|
|
||||||
+ *
|
|
||||||
+ * Solely for low level cpu hotplug code, where we need to make per
|
|
||||||
+ * cpu interrupts affine before the cpu becomes online.
|
|
||||||
+ */
|
|
||||||
+int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
|
|
||||||
+{
|
|
||||||
+ return __irq_set_affinity(irq, cpumask, true);
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(irq_force_affinity);
|
|
||||||
+
|
|
||||||
int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
|
|
||||||
{
|
|
||||||
unsigned long flags;
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,272 +0,0 @@
|
|||||||
From 798f3f7cb4d4a6480c90e18ea96e45c8fe7fd30d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Date: Thu, 29 Sep 2022 22:01:02 +0800
|
|
||||||
Subject: [PATCH 07/19] hwtracing: hisi_ptt: Add tune function support for
|
|
||||||
HiSilicon PCIe Tune and Trace device
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v6.1-rc1
|
|
||||||
commit 5ca57b03d8c5de4c59234cc11fe9dd9f13d57f48
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RP8T
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git/commit/?id=5ca57b03d8c5de4c59234cc11fe9dd9f13d57f48
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Add tune function for the HiSilicon Tune and Trace device. The interface
|
|
||||||
of tune is exposed through sysfs attributes of PTT PMU device.
|
|
||||||
|
|
||||||
Acked-by: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Link: https://lore.kernel.org/r/20220816114414.4092-4-yangyicong@huawei.com
|
|
||||||
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
|
|
||||||
Reviewed-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
|
|
||||||
Reviewed-by: Jay Fang <f.fangjian@huawei.com>
|
|
||||||
Acked-by: Xie XiuQi <xiexiuqi@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 131 +++++++++++++++++++++++++++++++
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.h | 23 ++++++
|
|
||||||
2 files changed, 154 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index 0aa99af85f86..cffc625665a2 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -25,6 +25,135 @@
|
|
||||||
/* Dynamic CPU hotplug state used by PTT */
|
|
||||||
static enum cpuhp_state hisi_ptt_pmu_online;
|
|
||||||
|
|
||||||
+static bool hisi_ptt_wait_tuning_finish(struct hisi_ptt *hisi_ptt)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ return !readl_poll_timeout(hisi_ptt->iobase + HISI_PTT_TUNING_INT_STAT,
|
|
||||||
+ val, !(val & HISI_PTT_TUNING_INT_STAT_MASK),
|
|
||||||
+ HISI_PTT_WAIT_POLL_INTERVAL_US,
|
|
||||||
+ HISI_PTT_WAIT_TUNE_TIMEOUT_US);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static ssize_t hisi_ptt_tune_attr_show(struct device *dev,
|
|
||||||
+ struct device_attribute *attr,
|
|
||||||
+ char *buf)
|
|
||||||
+{
|
|
||||||
+ struct hisi_ptt *hisi_ptt = to_hisi_ptt(dev_get_drvdata(dev));
|
|
||||||
+ struct dev_ext_attribute *ext_attr;
|
|
||||||
+ struct hisi_ptt_tune_desc *desc;
|
|
||||||
+ u32 reg;
|
|
||||||
+ u16 val;
|
|
||||||
+
|
|
||||||
+ ext_attr = container_of(attr, struct dev_ext_attribute, attr);
|
|
||||||
+ desc = ext_attr->var;
|
|
||||||
+
|
|
||||||
+ mutex_lock(&hisi_ptt->tune_lock);
|
|
||||||
+
|
|
||||||
+ reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
|
|
||||||
+ reg &= ~(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB);
|
|
||||||
+ reg |= FIELD_PREP(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB,
|
|
||||||
+ desc->event_code);
|
|
||||||
+ writel(reg, hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
|
|
||||||
+
|
|
||||||
+ /* Write all 1 to indicates it's the read process */
|
|
||||||
+ writel(~0U, hisi_ptt->iobase + HISI_PTT_TUNING_DATA);
|
|
||||||
+
|
|
||||||
+ if (!hisi_ptt_wait_tuning_finish(hisi_ptt)) {
|
|
||||||
+ mutex_unlock(&hisi_ptt->tune_lock);
|
|
||||||
+ return -ETIMEDOUT;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_DATA);
|
|
||||||
+ reg &= HISI_PTT_TUNING_DATA_VAL_MASK;
|
|
||||||
+ val = FIELD_GET(HISI_PTT_TUNING_DATA_VAL_MASK, reg);
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&hisi_ptt->tune_lock);
|
|
||||||
+ return sysfs_emit(buf, "%u\n", val);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static ssize_t hisi_ptt_tune_attr_store(struct device *dev,
|
|
||||||
+ struct device_attribute *attr,
|
|
||||||
+ const char *buf, size_t count)
|
|
||||||
+{
|
|
||||||
+ struct hisi_ptt *hisi_ptt = to_hisi_ptt(dev_get_drvdata(dev));
|
|
||||||
+ struct dev_ext_attribute *ext_attr;
|
|
||||||
+ struct hisi_ptt_tune_desc *desc;
|
|
||||||
+ u32 reg;
|
|
||||||
+ u16 val;
|
|
||||||
+
|
|
||||||
+ ext_attr = container_of(attr, struct dev_ext_attribute, attr);
|
|
||||||
+ desc = ext_attr->var;
|
|
||||||
+
|
|
||||||
+ if (kstrtou16(buf, 10, &val))
|
|
||||||
+ return -EINVAL;
|
|
||||||
+
|
|
||||||
+ mutex_lock(&hisi_ptt->tune_lock);
|
|
||||||
+
|
|
||||||
+ reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
|
|
||||||
+ reg &= ~(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB);
|
|
||||||
+ reg |= FIELD_PREP(HISI_PTT_TUNING_CTRL_CODE | HISI_PTT_TUNING_CTRL_SUB,
|
|
||||||
+ desc->event_code);
|
|
||||||
+ writel(reg, hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
|
|
||||||
+ writel(FIELD_PREP(HISI_PTT_TUNING_DATA_VAL_MASK, val),
|
|
||||||
+ hisi_ptt->iobase + HISI_PTT_TUNING_DATA);
|
|
||||||
+
|
|
||||||
+ if (!hisi_ptt_wait_tuning_finish(hisi_ptt)) {
|
|
||||||
+ mutex_unlock(&hisi_ptt->tune_lock);
|
|
||||||
+ return -ETIMEDOUT;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&hisi_ptt->tune_lock);
|
|
||||||
+ return count;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+#define HISI_PTT_TUNE_ATTR(_name, _val, _show, _store) \
|
|
||||||
+ static struct hisi_ptt_tune_desc _name##_desc = { \
|
|
||||||
+ .name = #_name, \
|
|
||||||
+ .event_code = (_val), \
|
|
||||||
+ }; \
|
|
||||||
+ static struct dev_ext_attribute hisi_ptt_##_name##_attr = { \
|
|
||||||
+ .attr = __ATTR(_name, 0600, _show, _store), \
|
|
||||||
+ .var = &_name##_desc, \
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+#define HISI_PTT_TUNE_ATTR_COMMON(_name, _val) \
|
|
||||||
+ HISI_PTT_TUNE_ATTR(_name, _val, \
|
|
||||||
+ hisi_ptt_tune_attr_show, \
|
|
||||||
+ hisi_ptt_tune_attr_store)
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * The value of the tuning event are composed of two parts: main event code
|
|
||||||
+ * in BIT[0,15] and subevent code in BIT[16,23]. For example, qox_tx_cpl is
|
|
||||||
+ * a subevent of 'Tx path QoS control' which for tuning the weight of Tx
|
|
||||||
+ * completion TLPs. See hisi_ptt.rst documentation for more information.
|
|
||||||
+ */
|
|
||||||
+#define HISI_PTT_TUNE_QOS_TX_CPL (0x4 | (3 << 16))
|
|
||||||
+#define HISI_PTT_TUNE_QOS_TX_NP (0x4 | (4 << 16))
|
|
||||||
+#define HISI_PTT_TUNE_QOS_TX_P (0x4 | (5 << 16))
|
|
||||||
+#define HISI_PTT_TUNE_RX_ALLOC_BUF_LEVEL (0x5 | (6 << 16))
|
|
||||||
+#define HISI_PTT_TUNE_TX_ALLOC_BUF_LEVEL (0x5 | (7 << 16))
|
|
||||||
+
|
|
||||||
+HISI_PTT_TUNE_ATTR_COMMON(qos_tx_cpl, HISI_PTT_TUNE_QOS_TX_CPL);
|
|
||||||
+HISI_PTT_TUNE_ATTR_COMMON(qos_tx_np, HISI_PTT_TUNE_QOS_TX_NP);
|
|
||||||
+HISI_PTT_TUNE_ATTR_COMMON(qos_tx_p, HISI_PTT_TUNE_QOS_TX_P);
|
|
||||||
+HISI_PTT_TUNE_ATTR_COMMON(rx_alloc_buf_level, HISI_PTT_TUNE_RX_ALLOC_BUF_LEVEL);
|
|
||||||
+HISI_PTT_TUNE_ATTR_COMMON(tx_alloc_buf_level, HISI_PTT_TUNE_TX_ALLOC_BUF_LEVEL);
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_ptt_tune_attrs[] = {
|
|
||||||
+ &hisi_ptt_qos_tx_cpl_attr.attr.attr,
|
|
||||||
+ &hisi_ptt_qos_tx_np_attr.attr.attr,
|
|
||||||
+ &hisi_ptt_qos_tx_p_attr.attr.attr,
|
|
||||||
+ &hisi_ptt_rx_alloc_buf_level_attr.attr.attr,
|
|
||||||
+ &hisi_ptt_tx_alloc_buf_level_attr.attr.attr,
|
|
||||||
+ NULL,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute_group hisi_ptt_tune_group = {
|
|
||||||
+ .name = "tune",
|
|
||||||
+ .attrs = hisi_ptt_tune_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static u16 hisi_ptt_get_filter_val(u16 devid, bool is_port)
|
|
||||||
{
|
|
||||||
if (is_port)
|
|
||||||
@@ -407,6 +536,7 @@ static struct attribute_group hisi_ptt_pmu_format_group = {
|
|
||||||
static const struct attribute_group *hisi_ptt_pmu_groups[] = {
|
|
||||||
&hisi_ptt_cpumask_attr_group,
|
|
||||||
&hisi_ptt_pmu_format_group,
|
|
||||||
+ &hisi_ptt_tune_group,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -748,6 +878,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt)
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
+ mutex_init(&hisi_ptt->tune_lock);
|
|
||||||
spin_lock_init(&hisi_ptt->pmu_lock);
|
|
||||||
|
|
||||||
hisi_ptt->hisi_ptt_pmu = (struct pmu) {
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.h b/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
index c9b635b3bfe9..ae99e5c78102 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
@@ -12,6 +12,7 @@
|
|
||||||
#include <linux/bits.h>
|
|
||||||
#include <linux/cpumask.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
+#include <linux/mutex.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/perf_event.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
@@ -22,6 +23,11 @@
|
|
||||||
/*
|
|
||||||
* The definition of the device registers and register fields.
|
|
||||||
*/
|
|
||||||
+#define HISI_PTT_TUNING_CTRL 0x0000
|
|
||||||
+#define HISI_PTT_TUNING_CTRL_CODE GENMASK(15, 0)
|
|
||||||
+#define HISI_PTT_TUNING_CTRL_SUB GENMASK(23, 16)
|
|
||||||
+#define HISI_PTT_TUNING_DATA 0x0004
|
|
||||||
+#define HISI_PTT_TUNING_DATA_VAL_MASK GENMASK(15, 0)
|
|
||||||
#define HISI_PTT_TRACE_ADDR_SIZE 0x0800
|
|
||||||
#define HISI_PTT_TRACE_ADDR_BASE_LO_0 0x0810
|
|
||||||
#define HISI_PTT_TRACE_ADDR_BASE_HI_0 0x0814
|
|
||||||
@@ -37,6 +43,8 @@
|
|
||||||
#define HISI_PTT_TRACE_INT_STAT 0x0890
|
|
||||||
#define HISI_PTT_TRACE_INT_STAT_MASK GENMASK(3, 0)
|
|
||||||
#define HISI_PTT_TRACE_INT_MASK 0x0894
|
|
||||||
+#define HISI_PTT_TUNING_INT_STAT 0x0898
|
|
||||||
+#define HISI_PTT_TUNING_INT_STAT_MASK BIT(0)
|
|
||||||
#define HISI_PTT_TRACE_WR_STS 0x08a0
|
|
||||||
#define HISI_PTT_TRACE_WR_STS_WRITE GENMASK(27, 0)
|
|
||||||
#define HISI_PTT_TRACE_WR_STS_BUFFER GENMASK(29, 28)
|
|
||||||
@@ -59,6 +67,7 @@
|
|
||||||
#define HISI_PTT_RESET_TIMEOUT_US 10UL
|
|
||||||
#define HISI_PTT_RESET_POLL_INTERVAL_US 1UL
|
|
||||||
/* Poll timeout and interval for waiting hardware work to finish */
|
|
||||||
+#define HISI_PTT_WAIT_TUNE_TIMEOUT_US 1000000UL
|
|
||||||
#define HISI_PTT_WAIT_TRACE_TIMEOUT_US 100UL
|
|
||||||
#define HISI_PTT_WAIT_POLL_INTERVAL_US 10UL
|
|
||||||
|
|
||||||
@@ -71,6 +80,18 @@
|
|
||||||
#define HISI_PTT_PMU_TYPE_MASK GENMASK(31, 24)
|
|
||||||
#define HISI_PTT_PMU_FORMAT_MASK GENMASK(35, 32)
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * struct hisi_ptt_tune_desc - Describe tune event for PTT tune
|
|
||||||
+ * @hisi_ptt: PTT device this tune event belongs to
|
|
||||||
+ * @name: name of this event
|
|
||||||
+ * @event_code: code of the event
|
|
||||||
+ */
|
|
||||||
+struct hisi_ptt_tune_desc {
|
|
||||||
+ struct hisi_ptt *hisi_ptt;
|
|
||||||
+ const char *name;
|
|
||||||
+ u32 event_code;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* struct hisi_ptt_dma_buffer - Describe a single trace buffer of PTT trace.
|
|
||||||
* The detail of the data format is described
|
|
||||||
@@ -143,6 +164,7 @@ struct hisi_ptt_pmu_buf {
|
|
||||||
* @hisi_ptt_pmu: the pum device of trace
|
|
||||||
* @iobase: base IO address of the device
|
|
||||||
* @pdev: pci_dev of this PTT device
|
|
||||||
+ * @tune_lock: lock to serialize the tune process
|
|
||||||
* @pmu_lock: lock to serialize the perf process
|
|
||||||
* @upper_bdf: the upper BDF range of the PCI devices
|
|
||||||
* managed by this PTT device
|
|
||||||
@@ -158,6 +180,7 @@ struct hisi_ptt {
|
|
||||||
struct pmu hisi_ptt_pmu;
|
|
||||||
void __iomem *iobase;
|
|
||||||
struct pci_dev *pdev;
|
|
||||||
+ struct mutex tune_lock;
|
|
||||||
spinlock_t pmu_lock;
|
|
||||||
u32 upper_bdf;
|
|
||||||
u32 lower_bdf;
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,426 +0,0 @@
|
|||||||
From ae4cbc7ea0d6805d222dd67083678a5c95825c1d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Date: Thu, 29 Sep 2022 22:01:03 +0800
|
|
||||||
Subject: [PATCH 08/19] docs: trace: Add HiSilicon PTT device driver
|
|
||||||
documentation
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v6.1-rc1
|
|
||||||
commit a7112b747c324dda8937d4f47b14dc0af0b465d1
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RP8T
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git/commit/?id=a7112b747c324dda8937d4f47b14dc0af0b465d1
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Document the introduction and usage of HiSilicon PTT device driver as well
|
|
||||||
as the sysfs attributes description provided by the driver.
|
|
||||||
|
|
||||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Reviewed-by: Bagas Sanjaya <bagasdotme@gmail.com>
|
|
||||||
[Fixed month and kernel version]
|
|
||||||
Link: https://lore.kernel.org/r/20220816114414.4092-5-yangyicong@huawei.com
|
|
||||||
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
|
|
||||||
Reviewed-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
|
|
||||||
Reviewed-by: Jay Fang <f.fangjian@huawei.com>
|
|
||||||
Acked-by: Xie XiuQi <xiexiuqi@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
Documentation/trace/index.rst
|
|
||||||
---
|
|
||||||
.../ABI/testing/sysfs-devices-hisi_ptt | 61 ++++
|
|
||||||
Documentation/trace/hisi-ptt.rst | 298 ++++++++++++++++++
|
|
||||||
Documentation/trace/index.rst | 1 +
|
|
||||||
3 files changed, 360 insertions(+)
|
|
||||||
create mode 100644 Documentation/ABI/testing/sysfs-devices-hisi_ptt
|
|
||||||
create mode 100644 Documentation/trace/hisi-ptt.rst
|
|
||||||
|
|
||||||
diff --git a/Documentation/ABI/testing/sysfs-devices-hisi_ptt b/Documentation/ABI/testing/sysfs-devices-hisi_ptt
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..82de6d710266
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/Documentation/ABI/testing/sysfs-devices-hisi_ptt
|
|
||||||
@@ -0,0 +1,61 @@
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune
|
|
||||||
+Date: October 2022
|
|
||||||
+KernelVersion: 6.1
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: This directory contains files for tuning the PCIe link
|
|
||||||
+ parameters(events). Each file is named after the event
|
|
||||||
+ of the PCIe link.
|
|
||||||
+
|
|
||||||
+ See Documentation/trace/hisi-ptt.rst for more information.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_cpl
|
|
||||||
+Date: October 2022
|
|
||||||
+KernelVersion: 6.1
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: (RW) Controls the weight of Tx completion TLPs, which influence
|
|
||||||
+ the proportion of outbound completion TLPs on the PCIe link.
|
|
||||||
+ The available tune data is [0, 1, 2]. Writing a negative value
|
|
||||||
+ will return an error, and out of range values will be converted
|
|
||||||
+ to 2. The value indicates a probable level of the event.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_np
|
|
||||||
+Date: October 2022
|
|
||||||
+KernelVersion: 6.1
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: (RW) Controls the weight of Tx non-posted TLPs, which influence
|
|
||||||
+ the proportion of outbound non-posted TLPs on the PCIe link.
|
|
||||||
+ The available tune data is [0, 1, 2]. Writing a negative value
|
|
||||||
+ will return an error, and out of range values will be converted
|
|
||||||
+ to 2. The value indicates a probable level of the event.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/qos_tx_p
|
|
||||||
+Date: October 2022
|
|
||||||
+KernelVersion: 6.1
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: (RW) Controls the weight of Tx posted TLPs, which influence the
|
|
||||||
+ proportion of outbound posted TLPs on the PCIe link.
|
|
||||||
+ The available tune data is [0, 1, 2]. Writing a negative value
|
|
||||||
+ will return an error, and out of range values will be converted
|
|
||||||
+ to 2. The value indicates a probable level of the event.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/rx_alloc_buf_level
|
|
||||||
+Date: October 2022
|
|
||||||
+KernelVersion: 6.1
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: (RW) Control the allocated buffer watermark for inbound packets.
|
|
||||||
+ The packets will be stored in the buffer first and then transmitted
|
|
||||||
+ either when the watermark reached or when timed out.
|
|
||||||
+ The available tune data is [0, 1, 2]. Writing a negative value
|
|
||||||
+ will return an error, and out of range values will be converted
|
|
||||||
+ to 2. The value indicates a probable level of the event.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune/tx_alloc_buf_level
|
|
||||||
+Date: October 2022
|
|
||||||
+KernelVersion: 6.1
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: (RW) Control the allocated buffer watermark of outbound packets.
|
|
||||||
+ The packets will be stored in the buffer first and then transmitted
|
|
||||||
+ either when the watermark reached or when timed out.
|
|
||||||
+ The available tune data is [0, 1, 2]. Writing a negative value
|
|
||||||
+ will return an error, and out of range values will be converted
|
|
||||||
+ to 2. The value indicates a probable level of the event.
|
|
||||||
diff --git a/Documentation/trace/hisi-ptt.rst b/Documentation/trace/hisi-ptt.rst
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..4f87d8e21065
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/Documentation/trace/hisi-ptt.rst
|
|
||||||
@@ -0,0 +1,298 @@
|
|
||||||
+.. SPDX-License-Identifier: GPL-2.0
|
|
||||||
+
|
|
||||||
+======================================
|
|
||||||
+HiSilicon PCIe Tune and Trace device
|
|
||||||
+======================================
|
|
||||||
+
|
|
||||||
+Introduction
|
|
||||||
+============
|
|
||||||
+
|
|
||||||
+HiSilicon PCIe tune and trace device (PTT) is a PCIe Root Complex
|
|
||||||
+integrated Endpoint (RCiEP) device, providing the capability
|
|
||||||
+to dynamically monitor and tune the PCIe link's events (tune),
|
|
||||||
+and trace the TLP headers (trace). The two functions are independent,
|
|
||||||
+but is recommended to use them together to analyze and enhance the
|
|
||||||
+PCIe link's performance.
|
|
||||||
+
|
|
||||||
+On Kunpeng 930 SoC, the PCIe Root Complex is composed of several
|
|
||||||
+PCIe cores. Each PCIe core includes several Root Ports and a PTT
|
|
||||||
+RCiEP, like below. The PTT device is capable of tuning and
|
|
||||||
+tracing the links of the PCIe core.
|
|
||||||
+::
|
|
||||||
+
|
|
||||||
+ +--------------Core 0-------+
|
|
||||||
+ | | [ PTT ] |
|
|
||||||
+ | | [Root Port]---[Endpoint]
|
|
||||||
+ | | [Root Port]---[Endpoint]
|
|
||||||
+ | | [Root Port]---[Endpoint]
|
|
||||||
+ Root Complex |------Core 1-------+
|
|
||||||
+ | | [ PTT ] |
|
|
||||||
+ | | [Root Port]---[ Switch ]---[Endpoint]
|
|
||||||
+ | | [Root Port]---[Endpoint] `-[Endpoint]
|
|
||||||
+ | | [Root Port]---[Endpoint]
|
|
||||||
+ +---------------------------+
|
|
||||||
+
|
|
||||||
+The PTT device driver registers one PMU device for each PTT device.
|
|
||||||
+The name of each PTT device is composed of 'hisi_ptt' prefix with
|
|
||||||
+the id of the SICL and the Core where it locates. The Kunpeng 930
|
|
||||||
+SoC encapsulates multiple CPU dies (SCCL, Super CPU Cluster) and
|
|
||||||
+IO dies (SICL, Super I/O Cluster), where there's one PCIe Root
|
|
||||||
+Complex for each SICL.
|
|
||||||
+::
|
|
||||||
+
|
|
||||||
+ /sys/devices/hisi_ptt<sicl_id>_<core_id>
|
|
||||||
+
|
|
||||||
+Tune
|
|
||||||
+====
|
|
||||||
+
|
|
||||||
+PTT tune is designed for monitoring and adjusting PCIe link parameters (events).
|
|
||||||
+Currently we support events in 2 classes. The scope of the events
|
|
||||||
+covers the PCIe core to which the PTT device belongs.
|
|
||||||
+
|
|
||||||
+Each event is presented as a file under $(PTT PMU dir)/tune, and
|
|
||||||
+a simple open/read/write/close cycle will be used to tune the event.
|
|
||||||
+::
|
|
||||||
+
|
|
||||||
+ $ cd /sys/devices/hisi_ptt<sicl_id>_<core_id>/tune
|
|
||||||
+ $ ls
|
|
||||||
+ qos_tx_cpl qos_tx_np qos_tx_p
|
|
||||||
+ tx_path_rx_req_alloc_buf_level
|
|
||||||
+ tx_path_tx_req_alloc_buf_level
|
|
||||||
+ $ cat qos_tx_dp
|
|
||||||
+ 1
|
|
||||||
+ $ echo 2 > qos_tx_dp
|
|
||||||
+ $ cat qos_tx_dp
|
|
||||||
+ 2
|
|
||||||
+
|
|
||||||
+Current value (numerical value) of the event can be simply read
|
|
||||||
+from the file, and the desired value written to the file to tune.
|
|
||||||
+
|
|
||||||
+1. Tx Path QoS Control
|
|
||||||
+------------------------
|
|
||||||
+
|
|
||||||
+The following files are provided to tune the QoS of the tx path of
|
|
||||||
+the PCIe core.
|
|
||||||
+
|
|
||||||
+- qos_tx_cpl: weight of Tx completion TLPs
|
|
||||||
+- qos_tx_np: weight of Tx non-posted TLPs
|
|
||||||
+- qos_tx_p: weight of Tx posted TLPs
|
|
||||||
+
|
|
||||||
+The weight influences the proportion of certain packets on the PCIe link.
|
|
||||||
+For example, for the storage scenario, increase the proportion
|
|
||||||
+of the completion packets on the link to enhance the performance as
|
|
||||||
+more completions are consumed.
|
|
||||||
+
|
|
||||||
+The available tune data of these events is [0, 1, 2].
|
|
||||||
+Writing a negative value will return an error, and out of range
|
|
||||||
+values will be converted to 2. Note that the event value just
|
|
||||||
+indicates a probable level, but is not precise.
|
|
||||||
+
|
|
||||||
+2. Tx Path Buffer Control
|
|
||||||
+-------------------------
|
|
||||||
+
|
|
||||||
+Following files are provided to tune the buffer of tx path of the PCIe core.
|
|
||||||
+
|
|
||||||
+- rx_alloc_buf_level: watermark of Rx requested
|
|
||||||
+- tx_alloc_buf_level: watermark of Tx requested
|
|
||||||
+
|
|
||||||
+These events influence the watermark of the buffer allocated for each
|
|
||||||
+type. Rx means the inbound while Tx means outbound. The packets will
|
|
||||||
+be stored in the buffer first and then transmitted either when the
|
|
||||||
+watermark reached or when timed out. For a busy direction, you should
|
|
||||||
+increase the related buffer watermark to avoid frequently posting and
|
|
||||||
+thus enhance the performance. In most cases just keep the default value.
|
|
||||||
+
|
|
||||||
+The available tune data of above events is [0, 1, 2].
|
|
||||||
+Writing a negative value will return an error, and out of range
|
|
||||||
+values will be converted to 2. Note that the event value just
|
|
||||||
+indicates a probable level, but is not precise.
|
|
||||||
+
|
|
||||||
+Trace
|
|
||||||
+=====
|
|
||||||
+
|
|
||||||
+PTT trace is designed for dumping the TLP headers to the memory, which
|
|
||||||
+can be used to analyze the transactions and usage condition of the PCIe
|
|
||||||
+Link. You can choose to filter the traced headers by either Requester ID,
|
|
||||||
+or those downstream of a set of Root Ports on the same core of the PTT
|
|
||||||
+device. It's also supported to trace the headers of certain type and of
|
|
||||||
+certain direction.
|
|
||||||
+
|
|
||||||
+You can use the perf command `perf record` to set the parameters, start
|
|
||||||
+trace and get the data. It's also supported to decode the trace
|
|
||||||
+data with `perf report`. The control parameters for trace is inputted
|
|
||||||
+as event code for each events, which will be further illustrated later.
|
|
||||||
+An example usage is like
|
|
||||||
+::
|
|
||||||
+
|
|
||||||
+ $ perf record -e hisi_ptt0_2/filter=0x80001,type=1,direction=1,
|
|
||||||
+ format=1/ -- sleep 5
|
|
||||||
+
|
|
||||||
+This will trace the TLP headers downstream root port 0000:00:10.1 (event
|
|
||||||
+code for event 'filter' is 0x80001) with type of posted TLP requests,
|
|
||||||
+direction of inbound and traced data format of 8DW.
|
|
||||||
+
|
|
||||||
+1. Filter
|
|
||||||
+---------
|
|
||||||
+
|
|
||||||
+The TLP headers to trace can be filtered by the Root Ports or the Requester ID
|
|
||||||
+of the Endpoint, which are located on the same core of the PTT device. You can
|
|
||||||
+set the filter by specifying the `filter` parameter which is required to start
|
|
||||||
+the trace. The parameter value is 20 bit. Bit 19 indicates the filter type.
|
|
||||||
+1 for Root Port filter and 0 for Requester filter. Bit[15:0] indicates the
|
|
||||||
+filter value. The value for a Root Port is a mask of the core port id which is
|
|
||||||
+calculated from its PCI Slot ID as (slotid & 7) * 2. The value for a Requester
|
|
||||||
+is the Requester ID (Device ID of the PCIe function). Bit[18:16] is currently
|
|
||||||
+reserved for extension.
|
|
||||||
+
|
|
||||||
+For example, if the desired filter is Endpoint function 0000:01:00.1 the filter
|
|
||||||
+value will be 0x00101. If the desired filter is Root Port 0000:00:10.0 then
|
|
||||||
+then filter value is calculated as 0x80001.
|
|
||||||
+
|
|
||||||
+Note that multiple Root Ports can be specified at one time, but only one
|
|
||||||
+Endpoint function can be specified in one trace. Specifying both Root Port
|
|
||||||
+and function at the same time is not supported. Driver maintains a list of
|
|
||||||
+available filters and will check the invalid inputs.
|
|
||||||
+
|
|
||||||
+Currently the available filters are detected in driver's probe. If the supported
|
|
||||||
+devices are removed/added after probe, you may need to reload the driver to update
|
|
||||||
+the filters.
|
|
||||||
+
|
|
||||||
+2. Type
|
|
||||||
+-------
|
|
||||||
+
|
|
||||||
+You can trace the TLP headers of certain types by specifying the `type`
|
|
||||||
+parameter, which is required to start the trace. The parameter value is
|
|
||||||
+8 bit. Current supported types and related values are shown below:
|
|
||||||
+
|
|
||||||
+- 8'b00000001: posted requests (P)
|
|
||||||
+- 8'b00000010: non-posted requests (NP)
|
|
||||||
+- 8'b00000100: completions (CPL)
|
|
||||||
+
|
|
||||||
+You can specify multiple types when tracing inbound TLP headers, but can only
|
|
||||||
+specify one when tracing outbound TLP headers.
|
|
||||||
+
|
|
||||||
+3. Direction
|
|
||||||
+------------
|
|
||||||
+
|
|
||||||
+You can trace the TLP headers from certain direction, which is relative
|
|
||||||
+to the Root Port or the PCIe core, by specifying the `direction` parameter.
|
|
||||||
+This is optional and the default parameter is inbound. The parameter value
|
|
||||||
+is 4 bit. When the desired format is 4DW, directions and related values
|
|
||||||
+supported are shown below:
|
|
||||||
+
|
|
||||||
+- 4'b0000: inbound TLPs (P, NP, CPL)
|
|
||||||
+- 4'b0001: outbound TLPs (P, NP, CPL)
|
|
||||||
+- 4'b0010: outbound TLPs (P, NP, CPL) and inbound TLPs (P, NP, CPL B)
|
|
||||||
+- 4'b0011: outbound TLPs (P, NP, CPL) and inbound TLPs (CPL A)
|
|
||||||
+
|
|
||||||
+When the desired format is 8DW, directions and related values supported are
|
|
||||||
+shown below:
|
|
||||||
+
|
|
||||||
+- 4'b0000: reserved
|
|
||||||
+- 4'b0001: outbound TLPs (P, NP, CPL)
|
|
||||||
+- 4'b0010: inbound TLPs (P, NP, CPL B)
|
|
||||||
+- 4'b0011: inbound TLPs (CPL A)
|
|
||||||
+
|
|
||||||
+Inbound completions are classified into two types:
|
|
||||||
+
|
|
||||||
+- completion A (CPL A): completion of CHI/DMA/Native non-posted requests, except for CPL B
|
|
||||||
+- completion B (CPL B): completion of DMA remote2local and P2P non-posted requests
|
|
||||||
+
|
|
||||||
+4. Format
|
|
||||||
+--------------
|
|
||||||
+
|
|
||||||
+You can change the format of the traced TLP headers by specifying the
|
|
||||||
+`format` parameter. The default format is 4DW. The parameter value is 4 bit.
|
|
||||||
+Current supported formats and related values are shown below:
|
|
||||||
+
|
|
||||||
+- 4'b0000: 4DW length per TLP header
|
|
||||||
+- 4'b0001: 8DW length per TLP header
|
|
||||||
+
|
|
||||||
+The traced TLP header format is different from the PCIe standard.
|
|
||||||
+
|
|
||||||
+When using the 8DW data format, the entire TLP header is logged
|
|
||||||
+(Header DW0-3 shown below). For example, the TLP header for Memory
|
|
||||||
+Reads with 64-bit addresses is shown in PCIe r5.0, Figure 2-17;
|
|
||||||
+the header for Configuration Requests is shown in Figure 2.20, etc.
|
|
||||||
+
|
|
||||||
+In addition, 8DW trace buffer entries contain a timestamp and
|
|
||||||
+possibly a prefix for a PASID TLP prefix (see Figure 6-20, PCIe r5.0).
|
|
||||||
+Otherwise this field will be all 0.
|
|
||||||
+
|
|
||||||
+The bit[31:11] of DW0 is always 0x1fffff, which can be
|
|
||||||
+used to distinguish the data format. 8DW format is like
|
|
||||||
+::
|
|
||||||
+
|
|
||||||
+ bits [ 31:11 ][ 10:0 ]
|
|
||||||
+ |---------------------------------------|-------------------|
|
|
||||||
+ DW0 [ 0x1fffff ][ Reserved (0x7ff) ]
|
|
||||||
+ DW1 [ Prefix ]
|
|
||||||
+ DW2 [ Header DW0 ]
|
|
||||||
+ DW3 [ Header DW1 ]
|
|
||||||
+ DW4 [ Header DW2 ]
|
|
||||||
+ DW5 [ Header DW3 ]
|
|
||||||
+ DW6 [ Reserved (0x0) ]
|
|
||||||
+ DW7 [ Time ]
|
|
||||||
+
|
|
||||||
+When using the 4DW data format, DW0 of the trace buffer entry
|
|
||||||
+contains selected fields of DW0 of the TLP, together with a
|
|
||||||
+timestamp. DW1-DW3 of the trace buffer entry contain DW1-DW3
|
|
||||||
+directly from the TLP header.
|
|
||||||
+
|
|
||||||
+4DW format is like
|
|
||||||
+::
|
|
||||||
+
|
|
||||||
+ bits [31:30] [ 29:25 ][24][23][22][21][ 20:11 ][ 10:0 ]
|
|
||||||
+ |-----|---------|---|---|---|---|-------------|-------------|
|
|
||||||
+ DW0 [ Fmt ][ Type ][T9][T8][TH][SO][ Length ][ Time ]
|
|
||||||
+ DW1 [ Header DW1 ]
|
|
||||||
+ DW2 [ Header DW2 ]
|
|
||||||
+ DW3 [ Header DW3 ]
|
|
||||||
+
|
|
||||||
+5. Memory Management
|
|
||||||
+--------------------
|
|
||||||
+
|
|
||||||
+The traced TLP headers will be written to the memory allocated
|
|
||||||
+by the driver. The hardware accepts 4 DMA address with same size,
|
|
||||||
+and writes the buffer sequentially like below. If DMA addr 3 is
|
|
||||||
+finished and the trace is still on, it will return to addr 0.
|
|
||||||
+::
|
|
||||||
+
|
|
||||||
+ +->[DMA addr 0]->[DMA addr 1]->[DMA addr 2]->[DMA addr 3]-+
|
|
||||||
+ +---------------------------------------------------------+
|
|
||||||
+
|
|
||||||
+Driver will allocate each DMA buffer of 4MiB. The finished buffer
|
|
||||||
+will be copied to the perf AUX buffer allocated by the perf core.
|
|
||||||
+Once the AUX buffer is full while the trace is still on, driver
|
|
||||||
+will commit the AUX buffer first and then apply for a new one with
|
|
||||||
+the same size. The size of AUX buffer is default to 16MiB. User can
|
|
||||||
+adjust the size by specifying the `-m` parameter of the perf command.
|
|
||||||
+
|
|
||||||
+6. Decoding
|
|
||||||
+-----------
|
|
||||||
+
|
|
||||||
+You can decode the traced data with `perf report -D` command (currently
|
|
||||||
+only support to dump the raw trace data). The traced data will be decoded
|
|
||||||
+according to the format described previously (take 8DW as an example):
|
|
||||||
+::
|
|
||||||
+
|
|
||||||
+ [...perf headers and other information]
|
|
||||||
+ . ... HISI PTT data: size 4194304 bytes
|
|
||||||
+ . 00000000: 00 00 00 00 Prefix
|
|
||||||
+ . 00000004: 01 00 00 60 Header DW0
|
|
||||||
+ . 00000008: 0f 1e 00 01 Header DW1
|
|
||||||
+ . 0000000c: 04 00 00 00 Header DW2
|
|
||||||
+ . 00000010: 40 00 81 02 Header DW3
|
|
||||||
+ . 00000014: 33 c0 04 00 Time
|
|
||||||
+ . 00000020: 00 00 00 00 Prefix
|
|
||||||
+ . 00000024: 01 00 00 60 Header DW0
|
|
||||||
+ . 00000028: 0f 1e 00 01 Header DW1
|
|
||||||
+ . 0000002c: 04 00 00 00 Header DW2
|
|
||||||
+ . 00000030: 40 00 81 02 Header DW3
|
|
||||||
+ . 00000034: 02 00 00 00 Time
|
|
||||||
+ . 00000040: 00 00 00 00 Prefix
|
|
||||||
+ . 00000044: 01 00 00 60 Header DW0
|
|
||||||
+ . 00000048: 0f 1e 00 01 Header DW1
|
|
||||||
+ . 0000004c: 04 00 00 00 Header DW2
|
|
||||||
+ . 00000050: 40 00 81 02 Header DW3
|
|
||||||
+ [...]
|
|
||||||
diff --git a/Documentation/trace/index.rst b/Documentation/trace/index.rst
|
|
||||||
index 306997941ba1..efbb91b49f39 100644
|
|
||||||
--- a/Documentation/trace/index.rst
|
|
||||||
+++ b/Documentation/trace/index.rst
|
|
||||||
@@ -22,3 +22,4 @@ Linux Tracing Technologies
|
|
||||||
hwlat_detector
|
|
||||||
intel_th
|
|
||||||
stm
|
|
||||||
+ hisi-ptt
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
From cd5c573c0275b1c83e2afb4e1522f65721e028ae Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Date: Thu, 29 Sep 2022 22:01:04 +0800
|
|
||||||
Subject: [PATCH 09/19] MAINTAINERS: Add maintainer for HiSilicon PTT driver
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v6.1-rc1
|
|
||||||
commit 366317eae983a0d96aeed78ad219b9c4ed2a719a
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RP8T
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git/commit/?id=366317eae983a0d96aeed78ad219b9c4ed2a719a
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Add maintainer for driver and documentation of HiSilicon PTT device.
|
|
||||||
|
|
||||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20220816114414.4092-6-yangyicong@huawei.com
|
|
||||||
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
|
|
||||||
Reviewed-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
|
|
||||||
Reviewed-by: Jay Fang <f.fangjian@huawei.com>
|
|
||||||
Acked-by: Xie XiuQi <xiexiuqi@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
MAINTAINERS
|
|
||||||
---
|
|
||||||
MAINTAINERS | 8 ++++++++
|
|
||||||
1 file changed, 8 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
|
||||||
index 3ad1e1b1da4a..3fafea62d296 100644
|
|
||||||
--- a/MAINTAINERS
|
|
||||||
+++ b/MAINTAINERS
|
|
||||||
@@ -6665,6 +6665,14 @@ S: Supported
|
|
||||||
F: drivers/perf/hisilicon
|
|
||||||
F: Documentation/perf/hisi-pmu.txt
|
|
||||||
|
|
||||||
+HISILICON PTT DRIVER
|
|
||||||
+M: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+L: linux-kernel@vger.kernel.org
|
|
||||||
+S: Maintained
|
|
||||||
+F: Documentation/ABI/testing/sysfs-devices-hisi_ptt
|
|
||||||
+F: Documentation/trace/hisi-ptt.rst
|
|
||||||
+F: drivers/hwtracing/ptt/
|
|
||||||
+
|
|
||||||
HISILICON ROCE DRIVER
|
|
||||||
M: Lijun Ou <oulijun@huawei.com>
|
|
||||||
M: Wei Hu(Xavier) <xavier.huwei@huawei.com>
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
From 5bcd48d8586935f02c89d96ca15dae8f144dd790 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Stephen Rothwell <sfr@canb.auug.org.au>
|
|
||||||
Date: Thu, 29 Sep 2022 22:01:05 +0800
|
|
||||||
Subject: [PATCH 10/19] hwtracing: hisi_ptt: Fix up for "iommu/dma: Make header
|
|
||||||
private"
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v6.1-rc1
|
|
||||||
commit 5fc1531dd771cd1481116a66f992a190e01efce6
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RP8T
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/coresight/linux.git/commit/?id=5fc1531dd771cd1481116a66f992a190e01efce6
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c:13:10: fatal error: linux/dma-iommu.h: No such file or directory
|
|
||||||
13 | #include <linux/dma-iommu.h>
|
|
||||||
| ^~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Caused by:
|
|
||||||
|
|
||||||
commit ff0de066b463 ("hwtracing: hisi_ptt: Add trace function support for HiSilicon PCIe Tune and Trace device")
|
|
||||||
|
|
||||||
interacting with:
|
|
||||||
|
|
||||||
commit f2042ed21da7 ("iommu/dma: Make header private")
|
|
||||||
|
|
||||||
from the iommu tree.
|
|
||||||
|
|
||||||
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
|
|
||||||
Acked-by: Robin Murphy <robin.murphy@arm.com>
|
|
||||||
Acked-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
[Fixed subject line and added changelog text]
|
|
||||||
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
|
|
||||||
Reviewed-by: Xiongfeng Wang <wangxiongfeng2@huawei.com>
|
|
||||||
Reviewed-by: Jay Fang <f.fangjian@huawei.com>
|
|
||||||
Acked-by: Xie XiuQi <xiexiuqi@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 1 -
|
|
||||||
1 file changed, 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index cffc625665a2..70d3398d341f 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -10,7 +10,6 @@
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/cpuhotplug.h>
|
|
||||||
#include <linux/delay.h>
|
|
||||||
-#include <linux/dma-iommu.h>
|
|
||||||
#include <linux/dma-mapping.h>
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/io.h>
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
From 5e414d74bedb6a2da45554952064133ccdead5ca Mon Sep 17 00:00:00 2001
|
|
||||||
From: Lei Zhou <zhoulei154@h-partners.com>
|
|
||||||
Date: Mon, 21 Nov 2022 22:02:10 +0800
|
|
||||||
Subject: [PATCH 11/19] hwtracing: hisi_ptt: Only add the supported devices to
|
|
||||||
the filters list
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v6.3-rc1
|
|
||||||
commit b8d976c7d41a28c0fccf22c7113be9a29dc07e5c
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I60FNG
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b8d976c7d41a28c0fccf22c7113be9a29dc07e5c
|
|
||||||
|
|
||||||
--------------------------------------------------------------
|
|
||||||
|
|
||||||
The PTT device can only filter the devices on the same PCIe core,
|
|
||||||
within BDF range [lower_bdf, upper_bdf]. Add the miss checking when
|
|
||||||
initialize the filters list.
|
|
||||||
|
|
||||||
Fixes: ff0de066b463 ("hwtracing: hisi_ptt: Add trace function support
|
|
||||||
for HiSilicon PCIe Tune and Trace device")
|
|
||||||
|
|
||||||
Signed-off-by: Wangming Shao <shaowangming@h-partners.com>
|
|
||||||
Signed-off-by: Lei Zhou <zhoulei154@h-partners.com>
|
|
||||||
Reviewed-by: Yicong Yang <yangyicong@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 10 ++++++++++
|
|
||||||
1 file changed, 10 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index 70d3398d341f..8e0dddbad0ec 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -364,8 +364,18 @@ static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt)
|
|
||||||
|
|
||||||
static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
|
|
||||||
{
|
|
||||||
+ struct pci_dev *root_port = pcie_find_root_port(pdev);
|
|
||||||
struct hisi_ptt_filter_desc *filter;
|
|
||||||
struct hisi_ptt *hisi_ptt = data;
|
|
||||||
+ u32 port_devid;
|
|
||||||
+
|
|
||||||
+ if (!root_port)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ port_devid = PCI_DEVID(root_port->bus->number, root_port->devfn);
|
|
||||||
+ if (port_devid < hisi_ptt->lower_bdf ||
|
|
||||||
+ port_devid > hisi_ptt->upper_bdf)
|
|
||||||
+ return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We won't fail the probe if filter allocation failed here. The filters
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
From f258c5de9bf043c1a363ce80f7a2c90130f21344 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yicong Yang <yangyicong@huawei.com>
|
|
||||||
Date: Wed, 7 Jun 2023 17:31:19 +0800
|
|
||||||
Subject: [PATCH 12/19] hwtracing: hisi_ptt: Factor out filter allocation and
|
|
||||||
release operation
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I7BZYX
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
|
|
||||||
Factor out the allocation and release of filters. This will make it easier
|
|
||||||
to extend and manage the function of the filter.
|
|
||||||
|
|
||||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
---
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 61 ++++++++++++++++++++------------
|
|
||||||
1 file changed, 39 insertions(+), 22 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index 8e0dddbad0ec..18907c47a22e 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -362,6 +362,40 @@ static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void hisi_ptt_del_free_filter(struct hisi_ptt *hisi_ptt,
|
|
||||||
+ struct hisi_ptt_filter_desc *filter)
|
|
||||||
+{
|
|
||||||
+ list_del(&filter->list);
|
|
||||||
+ kfree(filter);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct hisi_ptt_filter_desc *
|
|
||||||
+hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, struct pci_dev *pdev)
|
|
||||||
+{
|
|
||||||
+ struct hisi_ptt_filter_desc *filter;
|
|
||||||
+
|
|
||||||
+ filter = kzalloc(sizeof(*filter), GFP_KERNEL);
|
|
||||||
+ if (!filter) {
|
|
||||||
+ pci_err(hisi_ptt->pdev, "failed to add filter for %s\n",
|
|
||||||
+ pci_name(pdev));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ filter->devid = PCI_DEVID(pdev->bus->number, pdev->devfn);
|
|
||||||
+ filter->is_port = pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT;
|
|
||||||
+ if (filter->is_port) {
|
|
||||||
+ list_add_tail(&filter->list, &hisi_ptt->port_filters);
|
|
||||||
+
|
|
||||||
+ /* Update the available port mask */
|
|
||||||
+ hisi_ptt->port_mask |= hisi_ptt_get_filter_val(filter->devid,
|
|
||||||
+ true);
|
|
||||||
+ } else {
|
|
||||||
+ list_add_tail(&filter->list, &hisi_ptt->req_filters);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return filter;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
|
|
||||||
{
|
|
||||||
struct pci_dev *root_port = pcie_find_root_port(pdev);
|
|
||||||
@@ -382,23 +416,10 @@ static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
|
|
||||||
* should be partial initialized and users would know which filter fails
|
|
||||||
* through the log. Other functions of PTT device are still available.
|
|
||||||
*/
|
|
||||||
- filter = kzalloc(sizeof(*filter), GFP_KERNEL);
|
|
||||||
+ filter = hisi_ptt_alloc_add_filter(hisi_ptt, pdev);
|
|
||||||
if (!filter)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
- filter->devid = PCI_DEVID(pdev->bus->number, pdev->devfn);
|
|
||||||
-
|
|
||||||
- if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT) {
|
|
||||||
- filter->is_port = true;
|
|
||||||
- list_add_tail(&filter->list, &hisi_ptt->port_filters);
|
|
||||||
-
|
|
||||||
- /* Update the available port mask */
|
|
||||||
- hisi_ptt->port_mask |= hisi_ptt_get_filter_val(filter->devid,
|
|
||||||
- true);
|
|
||||||
- } else {
|
|
||||||
- list_add_tail(&filter->list, &hisi_ptt->req_filters);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -407,15 +428,11 @@ static void hisi_ptt_release_filters(void *data)
|
|
||||||
struct hisi_ptt_filter_desc *filter, *tmp;
|
|
||||||
struct hisi_ptt *hisi_ptt = data;
|
|
||||||
|
|
||||||
- list_for_each_entry_safe(filter, tmp, &hisi_ptt->req_filters, list) {
|
|
||||||
- list_del(&filter->list);
|
|
||||||
- kfree(filter);
|
|
||||||
- }
|
|
||||||
+ list_for_each_entry_safe(filter, tmp, &hisi_ptt->req_filters, list)
|
|
||||||
+ hisi_ptt_del_free_filter(hisi_ptt, filter);
|
|
||||||
|
|
||||||
- list_for_each_entry_safe(filter, tmp, &hisi_ptt->port_filters, list) {
|
|
||||||
- list_del(&filter->list);
|
|
||||||
- kfree(filter);
|
|
||||||
- }
|
|
||||||
+ list_for_each_entry_safe(filter, tmp, &hisi_ptt->port_filters, list)
|
|
||||||
+ hisi_ptt_del_free_filter(hisi_ptt, filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int hisi_ptt_config_trace_buf(struct hisi_ptt *hisi_ptt)
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,423 +0,0 @@
|
|||||||
From c0b71e3333323112781c701001761ff2624626db Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yicong Yang <yangyicong@huawei.com>
|
|
||||||
Date: Wed, 7 Jun 2023 17:31:20 +0800
|
|
||||||
Subject: [PATCH 13/19] hwtracing: hisi_ptt: Add support for dynamically
|
|
||||||
updating the filter list
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I7BZYX
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
|
|
||||||
The PCIe devices supported by the PTT trace can be removed/rescanned by
|
|
||||||
hotplug or through sysfs. Add support for dynamically updating the
|
|
||||||
available filter list by registering a PCI bus notifier block. Then user
|
|
||||||
can always get latest information about available tracing filters and
|
|
||||||
driver can block the invalid filters of which related devices no longer
|
|
||||||
exist in the system.
|
|
||||||
|
|
||||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
---
|
|
||||||
Documentation/trace/hisi-ptt.rst | 6 +-
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 183 +++++++++++++++++++++++++++++--
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.h | 40 +++++++
|
|
||||||
3 files changed, 218 insertions(+), 11 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/Documentation/trace/hisi-ptt.rst b/Documentation/trace/hisi-ptt.rst
|
|
||||||
index 4f87d8e21065..69c538153838 100644
|
|
||||||
--- a/Documentation/trace/hisi-ptt.rst
|
|
||||||
+++ b/Documentation/trace/hisi-ptt.rst
|
|
||||||
@@ -153,9 +153,9 @@ Endpoint function can be specified in one trace. Specifying both Root Port
|
|
||||||
and function at the same time is not supported. Driver maintains a list of
|
|
||||||
available filters and will check the invalid inputs.
|
|
||||||
|
|
||||||
-Currently the available filters are detected in driver's probe. If the supported
|
|
||||||
-devices are removed/added after probe, you may need to reload the driver to update
|
|
||||||
-the filters.
|
|
||||||
+The available filters will be dynamically updated, which means you will always
|
|
||||||
+get correct filter information when hotplug events happen, or when you manually
|
|
||||||
+remove/rescan the devices.
|
|
||||||
|
|
||||||
2. Type
|
|
||||||
-------
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index 18907c47a22e..6842c2f623ae 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -365,24 +365,45 @@ static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt)
|
|
||||||
static void hisi_ptt_del_free_filter(struct hisi_ptt *hisi_ptt,
|
|
||||||
struct hisi_ptt_filter_desc *filter)
|
|
||||||
{
|
|
||||||
+ if (filter->is_port)
|
|
||||||
+ hisi_ptt->port_mask &= ~hisi_ptt_get_filter_val(filter->devid,
|
|
||||||
+ true);
|
|
||||||
+
|
|
||||||
list_del(&filter->list);
|
|
||||||
+ kfree(filter->name);
|
|
||||||
kfree(filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct hisi_ptt_filter_desc *
|
|
||||||
-hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, struct pci_dev *pdev)
|
|
||||||
+hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, u16 devid, bool is_port)
|
|
||||||
{
|
|
||||||
struct hisi_ptt_filter_desc *filter;
|
|
||||||
+ u8 devfn = devid & 0xff;
|
|
||||||
+ char *filter_name;
|
|
||||||
+
|
|
||||||
+ filter_name = kasprintf(GFP_KERNEL, "%04x:%02x:%02x.%d",
|
|
||||||
+ pci_domain_nr(hisi_ptt->pdev->bus),
|
|
||||||
+ PCI_BUS_NUM(devid), PCI_SLOT(devfn),
|
|
||||||
+ PCI_FUNC(devfn));
|
|
||||||
+ if (!filter_name) {
|
|
||||||
+ pci_err(hisi_ptt->pdev, "failed to allocate name for filter %04x:%02x:%02x.%d\n",
|
|
||||||
+ pci_domain_nr(hisi_ptt->pdev->bus), PCI_BUS_NUM(devid),
|
|
||||||
+ PCI_SLOT(devfn), PCI_FUNC(devfn));
|
|
||||||
+ return NULL;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
filter = kzalloc(sizeof(*filter), GFP_KERNEL);
|
|
||||||
if (!filter) {
|
|
||||||
pci_err(hisi_ptt->pdev, "failed to add filter for %s\n",
|
|
||||||
- pci_name(pdev));
|
|
||||||
+ filter_name);
|
|
||||||
+ kfree(filter_name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- filter->devid = PCI_DEVID(pdev->bus->number, pdev->devfn);
|
|
||||||
- filter->is_port = pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT;
|
|
||||||
+ filter->name = filter_name;
|
|
||||||
+ filter->is_port = is_port;
|
|
||||||
+ filter->devid = devid;
|
|
||||||
+
|
|
||||||
if (filter->is_port) {
|
|
||||||
list_add_tail(&filter->list, &hisi_ptt->port_filters);
|
|
||||||
|
|
||||||
@@ -396,6 +417,108 @@ hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, struct pci_dev *pdev)
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void hisi_ptt_update_filters(struct work_struct *work)
|
|
||||||
+{
|
|
||||||
+ struct delayed_work *delayed_work = to_delayed_work(work);
|
|
||||||
+ struct hisi_ptt_filter_update_info info;
|
|
||||||
+ struct hisi_ptt_filter_desc *filter;
|
|
||||||
+ struct hisi_ptt *hisi_ptt;
|
|
||||||
+
|
|
||||||
+ hisi_ptt = container_of(delayed_work, struct hisi_ptt, work);
|
|
||||||
+
|
|
||||||
+ if (!mutex_trylock(&hisi_ptt->filter_lock)) {
|
|
||||||
+ schedule_delayed_work(&hisi_ptt->work, HISI_PTT_WORK_DELAY_MS);
|
|
||||||
+ return;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ while (kfifo_get(&hisi_ptt->filter_update_kfifo, &info)) {
|
|
||||||
+ if (info.is_add) {
|
|
||||||
+ /*
|
|
||||||
+ * Notify the users if failed to add this filter, others
|
|
||||||
+ * still work and available. See the comments in
|
|
||||||
+ * hisi_ptt_init_filters().
|
|
||||||
+ */
|
|
||||||
+ filter = hisi_ptt_alloc_add_filter(hisi_ptt,
|
|
||||||
+ info.devid,
|
|
||||||
+ info.is_port);
|
|
||||||
+ if (!filter)
|
|
||||||
+ continue;
|
|
||||||
+ } else {
|
|
||||||
+ struct hisi_ptt_filter_desc *tmp;
|
|
||||||
+ struct list_head *target_list;
|
|
||||||
+
|
|
||||||
+ target_list = info.is_port ? &hisi_ptt->port_filters :
|
|
||||||
+ &hisi_ptt->req_filters;
|
|
||||||
+
|
|
||||||
+ list_for_each_entry_safe(filter, tmp, target_list, list)
|
|
||||||
+ if (filter->devid == info.devid) {
|
|
||||||
+ hisi_ptt_del_free_filter(hisi_ptt,
|
|
||||||
+ filter);
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ mutex_unlock(&hisi_ptt->filter_lock);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/*
|
|
||||||
+ * A PCI bus notifier is used here for dynamically updating the filter
|
|
||||||
+ * list.
|
|
||||||
+ */
|
|
||||||
+static int hisi_ptt_notifier_call(struct notifier_block *nb,
|
|
||||||
+ unsigned long action,
|
|
||||||
+ void *data)
|
|
||||||
+{
|
|
||||||
+ struct hisi_ptt *hisi_ptt = container_of(nb,
|
|
||||||
+ struct hisi_ptt,
|
|
||||||
+ hisi_ptt_nb);
|
|
||||||
+ struct hisi_ptt_filter_update_info info;
|
|
||||||
+ struct pci_dev *pdev, *root_port;
|
|
||||||
+ struct device *dev = data;
|
|
||||||
+ u32 port_devid;
|
|
||||||
+
|
|
||||||
+ pdev = to_pci_dev(dev);
|
|
||||||
+ root_port = pcie_find_root_port(pdev);
|
|
||||||
+ if (!root_port)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ port_devid = PCI_DEVID(root_port->bus->number, root_port->devfn);
|
|
||||||
+ if (port_devid < hisi_ptt->lower_bdf ||
|
|
||||||
+ port_devid > hisi_ptt->upper_bdf)
|
|
||||||
+ return 0;
|
|
||||||
+
|
|
||||||
+ info.is_port = pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT;
|
|
||||||
+ info.devid = PCI_DEVID(pdev->bus->number, pdev->devfn);
|
|
||||||
+
|
|
||||||
+ switch (action) {
|
|
||||||
+ case BUS_NOTIFY_ADD_DEVICE:
|
|
||||||
+ info.is_add = true;
|
|
||||||
+ break;
|
|
||||||
+ case BUS_NOTIFY_DEL_DEVICE:
|
|
||||||
+ info.is_add = false;
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * The FIFO size is 16 which is sufficient for almost all the cases,
|
|
||||||
+ * since each PCIe core will have most 8 Root Ports (typically only
|
|
||||||
+ * 1~4 Root Ports). On failure log the failed filter and let user
|
|
||||||
+ * handle it.
|
|
||||||
+ */
|
|
||||||
+ if (kfifo_in_spinlocked(&hisi_ptt->filter_update_kfifo, &info, 1,
|
|
||||||
+ &hisi_ptt->filter_update_lock))
|
|
||||||
+ schedule_delayed_work(&hisi_ptt->work, 0);
|
|
||||||
+ else
|
|
||||||
+ pci_warn(hisi_ptt->pdev,
|
|
||||||
+ "filter update fifo overflow for target %s\n",
|
|
||||||
+ pci_name(pdev));
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
|
|
||||||
{
|
|
||||||
struct pci_dev *root_port = pcie_find_root_port(pdev);
|
|
||||||
@@ -416,7 +539,11 @@ static int hisi_ptt_init_filters(struct pci_dev *pdev, void *data)
|
|
||||||
* should be partial initialized and users would know which filter fails
|
|
||||||
* through the log. Other functions of PTT device are still available.
|
|
||||||
*/
|
|
||||||
- filter = hisi_ptt_alloc_add_filter(hisi_ptt, pdev);
|
|
||||||
+ filter = hisi_ptt_alloc_add_filter(hisi_ptt,
|
|
||||||
+ PCI_DEVID(pdev->bus->number,
|
|
||||||
+ pdev->devfn),
|
|
||||||
+ pci_pcie_type(pdev) ==
|
|
||||||
+ PCI_EXP_TYPE_ROOT_PORT);
|
|
||||||
if (!filter)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
@@ -478,8 +605,13 @@ static int hisi_ptt_init_ctrls(struct hisi_ptt *hisi_ptt)
|
|
||||||
int ret;
|
|
||||||
u32 reg;
|
|
||||||
|
|
||||||
+ INIT_DELAYED_WORK(&hisi_ptt->work, hisi_ptt_update_filters);
|
|
||||||
+ INIT_KFIFO(hisi_ptt->filter_update_kfifo);
|
|
||||||
+ spin_lock_init(&hisi_ptt->filter_update_lock);
|
|
||||||
+
|
|
||||||
INIT_LIST_HEAD(&hisi_ptt->port_filters);
|
|
||||||
INIT_LIST_HEAD(&hisi_ptt->req_filters);
|
|
||||||
+ mutex_init(&hisi_ptt->filter_lock);
|
|
||||||
|
|
||||||
ret = hisi_ptt_config_trace_buf(hisi_ptt);
|
|
||||||
if (ret)
|
|
||||||
@@ -636,6 +768,7 @@ static int hisi_ptt_trace_valid_filter(struct hisi_ptt *hisi_ptt, u64 config)
|
|
||||||
{
|
|
||||||
unsigned long val, port_mask = hisi_ptt->port_mask;
|
|
||||||
struct hisi_ptt_filter_desc *filter;
|
|
||||||
+ int ret = 0;
|
|
||||||
|
|
||||||
hisi_ptt->trace_ctrl.is_port = FIELD_GET(HISI_PTT_PMU_FILTER_IS_PORT,
|
|
||||||
config);
|
|
||||||
@@ -650,17 +783,21 @@ static int hisi_ptt_trace_valid_filter(struct hisi_ptt *hisi_ptt, u64 config)
|
|
||||||
* For Requester ID filters, walk the available filter list to see
|
|
||||||
* whether we have one matched.
|
|
||||||
*/
|
|
||||||
+ mutex_lock(&hisi_ptt->filter_lock);
|
|
||||||
if (!hisi_ptt->trace_ctrl.is_port) {
|
|
||||||
list_for_each_entry(filter, &hisi_ptt->req_filters, list) {
|
|
||||||
if (val == hisi_ptt_get_filter_val(filter->devid,
|
|
||||||
filter->is_port))
|
|
||||||
- return 0;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
} else if (bitmap_subset(&val, &port_mask, BITS_PER_LONG)) {
|
|
||||||
- return 0;
|
|
||||||
+ goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return -EINVAL;
|
|
||||||
+ ret = -EINVAL;
|
|
||||||
+out:
|
|
||||||
+ mutex_unlock(&hisi_ptt->filter_lock);
|
|
||||||
+ return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hisi_ptt_pmu_init_configs(struct hisi_ptt *hisi_ptt,
|
|
||||||
@@ -940,6 +1077,31 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt)
|
|
||||||
&hisi_ptt->hisi_ptt_pmu);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void hisi_ptt_unregister_filter_update_notifier(void *data)
|
|
||||||
+{
|
|
||||||
+ struct hisi_ptt *hisi_ptt = data;
|
|
||||||
+
|
|
||||||
+ bus_unregister_notifier(&pci_bus_type, &hisi_ptt->hisi_ptt_nb);
|
|
||||||
+
|
|
||||||
+ /* Cancel any work that has been queued */
|
|
||||||
+ cancel_delayed_work_sync(&hisi_ptt->work);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/* Register the bus notifier for dynamically updating the filter list */
|
|
||||||
+static int hisi_ptt_register_filter_update_notifier(struct hisi_ptt *hisi_ptt)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ hisi_ptt->hisi_ptt_nb.notifier_call = hisi_ptt_notifier_call;
|
|
||||||
+ ret = bus_register_notifier(&pci_bus_type, &hisi_ptt->hisi_ptt_nb);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ return devm_add_action_or_reset(&hisi_ptt->pdev->dev,
|
|
||||||
+ hisi_ptt_unregister_filter_update_notifier,
|
|
||||||
+ hisi_ptt);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
* The DMA of PTT trace can only use direct mappings due to some
|
|
||||||
* hardware restriction. Check whether there is no IOMMU or the
|
|
||||||
@@ -1011,6 +1173,11 @@ static int hisi_ptt_probe(struct pci_dev *pdev,
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ ret = hisi_ptt_register_filter_update_notifier(hisi_ptt);
|
|
||||||
+ if (ret)
|
|
||||||
+ pci_warn(pdev, "failed to register filter update notifier, ret = %d",
|
|
||||||
+ ret);
|
|
||||||
+
|
|
||||||
ret = hisi_ptt_register_pmu(hisi_ptt);
|
|
||||||
if (ret) {
|
|
||||||
pci_err(pdev, "failed to register PMU device, ret = %d", ret);
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.h b/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
index ae99e5c78102..814c3ef40acd 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
@@ -11,12 +11,15 @@
|
|
||||||
|
|
||||||
#include <linux/bits.h>
|
|
||||||
#include <linux/cpumask.h>
|
|
||||||
+#include <linux/kfifo.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
+#include <linux/notifier.h>
|
|
||||||
#include <linux/pci.h>
|
|
||||||
#include <linux/perf_event.h>
|
|
||||||
#include <linux/spinlock.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
+#include <linux/workqueue.h>
|
|
||||||
|
|
||||||
#define DRV_NAME "hisi_ptt"
|
|
||||||
|
|
||||||
@@ -71,6 +74,11 @@
|
|
||||||
#define HISI_PTT_WAIT_TRACE_TIMEOUT_US 100UL
|
|
||||||
#define HISI_PTT_WAIT_POLL_INTERVAL_US 10UL
|
|
||||||
|
|
||||||
+/* FIFO size for dynamically updating the PTT trace filter list. */
|
|
||||||
+#define HISI_PTT_FILTER_UPDATE_FIFO_SIZE 16
|
|
||||||
+/* Delay time for filter updating work */
|
|
||||||
+#define HISI_PTT_WORK_DELAY_MS 100UL
|
|
||||||
+
|
|
||||||
#define HISI_PCIE_CORE_PORT_ID(devfn) ((PCI_SLOT(devfn) & 0x7) << 1)
|
|
||||||
|
|
||||||
/* Definition of the PMU configs */
|
|
||||||
@@ -135,11 +143,25 @@ struct hisi_ptt_trace_ctrl {
|
|
||||||
* struct hisi_ptt_filter_desc - Descriptor of the PTT trace filter
|
|
||||||
* @list: entry of this descriptor in the filter list
|
|
||||||
* @is_port: the PCI device of the filter is a Root Port or not
|
|
||||||
+ * @name: name of this filter, same as the name of the related PCI device
|
|
||||||
* @devid: the PCI device's devid of the filter
|
|
||||||
*/
|
|
||||||
struct hisi_ptt_filter_desc {
|
|
||||||
struct list_head list;
|
|
||||||
bool is_port;
|
|
||||||
+ char *name;
|
|
||||||
+ u16 devid;
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * struct hisi_ptt_filter_update_info - Information for PTT filter updating
|
|
||||||
+ * @is_port: the PCI device to update is a Root Port or not
|
|
||||||
+ * @is_add: adding to the filter or not
|
|
||||||
+ * @devid: the PCI device's devid of the filter
|
|
||||||
+ */
|
|
||||||
+struct hisi_ptt_filter_update_info {
|
|
||||||
+ bool is_port;
|
|
||||||
+ bool is_add;
|
|
||||||
u16 devid;
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -160,6 +182,7 @@ struct hisi_ptt_pmu_buf {
|
|
||||||
/**
|
|
||||||
* struct hisi_ptt - Per PTT device data
|
|
||||||
* @trace_ctrl: the control information of PTT trace
|
|
||||||
+ * @hisi_ptt_nb: dynamic filter update notifier
|
|
||||||
* @hotplug_node: node for register cpu hotplug event
|
|
||||||
* @hisi_ptt_pmu: the pum device of trace
|
|
||||||
* @iobase: base IO address of the device
|
|
||||||
@@ -172,10 +195,15 @@ struct hisi_ptt_pmu_buf {
|
|
||||||
* managed by this PTT device
|
|
||||||
* @port_filters: the filter list of root ports
|
|
||||||
* @req_filters: the filter list of requester ID
|
|
||||||
+ * @filter_lock: lock to protect the filters
|
|
||||||
* @port_mask: port mask of the managed root ports
|
|
||||||
+ * @work: delayed work for filter updating
|
|
||||||
+ * @filter_update_lock: spinlock to protect the filter update fifo
|
|
||||||
+ * @filter_update_fifo: fifo of the filters waiting to update the filter list
|
|
||||||
*/
|
|
||||||
struct hisi_ptt {
|
|
||||||
struct hisi_ptt_trace_ctrl trace_ctrl;
|
|
||||||
+ struct notifier_block hisi_ptt_nb;
|
|
||||||
struct hlist_node hotplug_node;
|
|
||||||
struct pmu hisi_ptt_pmu;
|
|
||||||
void __iomem *iobase;
|
|
||||||
@@ -194,7 +222,19 @@ struct hisi_ptt {
|
|
||||||
*/
|
|
||||||
struct list_head port_filters;
|
|
||||||
struct list_head req_filters;
|
|
||||||
+ struct mutex filter_lock;
|
|
||||||
u16 port_mask;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * We use a delayed work here to avoid indefinitely waiting for
|
|
||||||
+ * the hisi_ptt->mutex which protecting the filter list. The
|
|
||||||
+ * work will be delayed only if the mutex can not be held,
|
|
||||||
+ * otherwise no delay will be applied.
|
|
||||||
+ */
|
|
||||||
+ struct delayed_work work;
|
|
||||||
+ spinlock_t filter_update_lock;
|
|
||||||
+ DECLARE_KFIFO(filter_update_kfifo, struct hisi_ptt_filter_update_info,
|
|
||||||
+ HISI_PTT_FILTER_UPDATE_FIFO_SIZE);
|
|
||||||
};
|
|
||||||
|
|
||||||
#define to_hisi_ptt(pmu) container_of(pmu, struct hisi_ptt, hisi_ptt_pmu)
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,435 +0,0 @@
|
|||||||
From 3f8f04f1a27315514e997194e19adcd0bfe85c27 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yicong Yang <yangyicong@huawei.com>
|
|
||||||
Date: Wed, 7 Jun 2023 17:31:21 +0800
|
|
||||||
Subject: [PATCH 14/19] hwtracing: hisi_ptt: Export available filters through
|
|
||||||
sysfs
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I7BZYX
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
|
|
||||||
The PTT can only filter the traced TLP headers by the Root Ports or the
|
|
||||||
Requester ID of the Endpoint, which are located on the same PCIe core of
|
|
||||||
the PTT device. The filter value used is derived from the BDF number of
|
|
||||||
the supported Root Port or the Endpoint. It's not friendly enough for the
|
|
||||||
users since it requires the user to be familiar enough with the platform
|
|
||||||
and calculate the filter value manually.
|
|
||||||
|
|
||||||
This patch export the available filters through sysfs. Each available
|
|
||||||
filters is presented as an individual file with the name of the BDF
|
|
||||||
number of the related PCIe device. The files are created under
|
|
||||||
$(PTT PMU dir)/available_root_port_filters and
|
|
||||||
$(PTT PMU dir)/available_requester_filters respectively. The filter
|
|
||||||
value can be known by reading the related file.
|
|
||||||
|
|
||||||
Then the users can easily know the available filters for trace and get
|
|
||||||
the filter values without calculating.
|
|
||||||
|
|
||||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
---
|
|
||||||
.../ABI/testing/sysfs-devices-hisi_ptt | 52 +++++
|
|
||||||
Documentation/trace/hisi-ptt.rst | 6 +
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 213 +++++++++++++++++-
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.h | 14 ++
|
|
||||||
4 files changed, 283 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/Documentation/ABI/testing/sysfs-devices-hisi_ptt b/Documentation/ABI/testing/sysfs-devices-hisi_ptt
|
|
||||||
index 82de6d710266..d7e206b4901c 100644
|
|
||||||
--- a/Documentation/ABI/testing/sysfs-devices-hisi_ptt
|
|
||||||
+++ b/Documentation/ABI/testing/sysfs-devices-hisi_ptt
|
|
||||||
@@ -59,3 +59,55 @@ Description: (RW) Control the allocated buffer watermark of outbound packets.
|
|
||||||
The available tune data is [0, 1, 2]. Writing a negative value
|
|
||||||
will return an error, and out of range values will be converted
|
|
||||||
to 2. The value indicates a probable level of the event.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/root_port_filters
|
|
||||||
+Date: May 2023
|
|
||||||
+KernelVersion: 6.5
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: This directory contains the files providing the PCIe Root Port filters
|
|
||||||
+ information used for PTT trace. Each file is named after the supported
|
|
||||||
+ Root Port device name <domain>:<bus>:<device>.<function>.
|
|
||||||
+
|
|
||||||
+ See the description of the "filter" in Documentation/trace/hisi-ptt.rst
|
|
||||||
+ for more information.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/root_port_filters/multiselect
|
|
||||||
+Date: May 2023
|
|
||||||
+KernelVersion: 6.5
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: (Read) Indicates if this kind of filter can be selected at the same
|
|
||||||
+ time as others filters, or must be used on it's own. 1 indicates
|
|
||||||
+ the former case and 0 indicates the latter.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/root_port_filters/<bdf>
|
|
||||||
+Date: May 2023
|
|
||||||
+KernelVersion: 6.5
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: (Read) Indicates the filter value of this Root Port filter, which
|
|
||||||
+ can be used to control the TLP headers to trace by the PTT trace.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/requester_filters
|
|
||||||
+Date: May 2023
|
|
||||||
+KernelVersion: 6.5
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: This directory contains the files providing the PCIe Requester filters
|
|
||||||
+ information used for PTT trace. Each file is named after the supported
|
|
||||||
+ Endpoint device name <domain>:<bus>:<device>.<function>.
|
|
||||||
+
|
|
||||||
+ See the description of the "filter" in Documentation/trace/hisi-ptt.rst
|
|
||||||
+ for more information.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/requester_filters/multiselect
|
|
||||||
+Date: May 2023
|
|
||||||
+KernelVersion: 6.5
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: (Read) Indicates if this kind of filter can be selected at the same
|
|
||||||
+ time as others filters, or must be used on it's own. 1 indicates
|
|
||||||
+ the former case and 0 indicates the latter.
|
|
||||||
+
|
|
||||||
+What: /sys/devices/hisi_ptt<sicl_id>_<core_id>/requester_filters/<bdf>
|
|
||||||
+Date: May 2023
|
|
||||||
+KernelVersion: 6.5
|
|
||||||
+Contact: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
+Description: (Read) Indicates the filter value of this Requester filter, which
|
|
||||||
+ can be used to control the TLP headers to trace by the PTT trace.
|
|
||||||
diff --git a/Documentation/trace/hisi-ptt.rst b/Documentation/trace/hisi-ptt.rst
|
|
||||||
index 69c538153838..989255eb5622 100644
|
|
||||||
--- a/Documentation/trace/hisi-ptt.rst
|
|
||||||
+++ b/Documentation/trace/hisi-ptt.rst
|
|
||||||
@@ -148,6 +148,12 @@ For example, if the desired filter is Endpoint function 0000:01:00.1 the filter
|
|
||||||
value will be 0x00101. If the desired filter is Root Port 0000:00:10.0 then
|
|
||||||
then filter value is calculated as 0x80001.
|
|
||||||
|
|
||||||
+The driver also presents every supported Root Port and Requester filter through
|
|
||||||
+sysfs. Each filter will be an individual file with name of its related PCIe
|
|
||||||
+device name (domain:bus:device.function). The files of Root Port filters are
|
|
||||||
+under $(PTT PMU dir)/root_port_filters and files of Requester filters
|
|
||||||
+are under $(PTT PMU dir)/requester_filters.
|
|
||||||
+
|
|
||||||
Note that multiple Root Ports can be specified at one time, but only one
|
|
||||||
Endpoint function can be specified in one trace. Specifying both Root Port
|
|
||||||
and function at the same time is not supported. Driver maintains a list of
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index 6842c2f623ae..31977a7c7e68 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -417,6 +417,145 @@ hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, u16 devid, bool is_port)
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static ssize_t hisi_ptt_filter_show(struct device *dev,
|
|
||||||
+ struct device_attribute *attr,
|
|
||||||
+ char *buf)
|
|
||||||
+{
|
|
||||||
+ struct hisi_ptt_filter_desc *filter;
|
|
||||||
+ unsigned long filter_val;
|
|
||||||
+
|
|
||||||
+ filter = container_of(attr, struct hisi_ptt_filter_desc, attr);
|
|
||||||
+ filter_val = hisi_ptt_get_filter_val(filter->devid, filter->is_port) |
|
|
||||||
+ (filter->is_port ? HISI_PTT_PMU_FILTER_IS_PORT : 0);
|
|
||||||
+
|
|
||||||
+ return sysfs_emit(buf, "0x%05lx\n", filter_val);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int hisi_ptt_create_rp_filter_attr(struct hisi_ptt *hisi_ptt,
|
|
||||||
+ struct hisi_ptt_filter_desc *filter)
|
|
||||||
+{
|
|
||||||
+ struct kobject *kobj = &hisi_ptt->hisi_ptt_pmu.dev->kobj;
|
|
||||||
+
|
|
||||||
+ sysfs_attr_init(&filter->attr.attr);
|
|
||||||
+ filter->attr.attr.name = filter->name;
|
|
||||||
+ filter->attr.attr.mode = 0400; /* DEVICE_ATTR_ADMIN_RO */
|
|
||||||
+ filter->attr.show = hisi_ptt_filter_show;
|
|
||||||
+
|
|
||||||
+ return sysfs_add_file_to_group(kobj, &filter->attr.attr,
|
|
||||||
+ HISI_PTT_RP_FILTERS_GRP_NAME);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ptt_remove_rp_filter_attr(struct hisi_ptt *hisi_ptt,
|
|
||||||
+ struct hisi_ptt_filter_desc *filter)
|
|
||||||
+{
|
|
||||||
+ struct kobject *kobj = &hisi_ptt->hisi_ptt_pmu.dev->kobj;
|
|
||||||
+
|
|
||||||
+ sysfs_remove_file_from_group(kobj, &filter->attr.attr,
|
|
||||||
+ HISI_PTT_RP_FILTERS_GRP_NAME);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int hisi_ptt_create_req_filter_attr(struct hisi_ptt *hisi_ptt,
|
|
||||||
+ struct hisi_ptt_filter_desc *filter)
|
|
||||||
+{
|
|
||||||
+ struct kobject *kobj = &hisi_ptt->hisi_ptt_pmu.dev->kobj;
|
|
||||||
+
|
|
||||||
+ sysfs_attr_init(&filter->attr.attr);
|
|
||||||
+ filter->attr.attr.name = filter->name;
|
|
||||||
+ filter->attr.attr.mode = 0400; /* DEVICE_ATTR_ADMIN_RO */
|
|
||||||
+ filter->attr.show = hisi_ptt_filter_show;
|
|
||||||
+
|
|
||||||
+ return sysfs_add_file_to_group(kobj, &filter->attr.attr,
|
|
||||||
+ HISI_PTT_REQ_FILTERS_GRP_NAME);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ptt_remove_req_filter_attr(struct hisi_ptt *hisi_ptt,
|
|
||||||
+ struct hisi_ptt_filter_desc *filter)
|
|
||||||
+{
|
|
||||||
+ struct kobject *kobj = &hisi_ptt->hisi_ptt_pmu.dev->kobj;
|
|
||||||
+
|
|
||||||
+ sysfs_remove_file_from_group(kobj, &filter->attr.attr,
|
|
||||||
+ HISI_PTT_REQ_FILTERS_GRP_NAME);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int hisi_ptt_create_filter_attr(struct hisi_ptt *hisi_ptt,
|
|
||||||
+ struct hisi_ptt_filter_desc *filter)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ if (filter->is_port)
|
|
||||||
+ ret = hisi_ptt_create_rp_filter_attr(hisi_ptt, filter);
|
|
||||||
+ else
|
|
||||||
+ ret = hisi_ptt_create_req_filter_attr(hisi_ptt, filter);
|
|
||||||
+
|
|
||||||
+ if (ret)
|
|
||||||
+ pci_err(hisi_ptt->pdev, "failed to create sysfs attribute for filter %s\n",
|
|
||||||
+ filter->name);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ptt_remove_filter_attr(struct hisi_ptt *hisi_ptt,
|
|
||||||
+ struct hisi_ptt_filter_desc *filter)
|
|
||||||
+{
|
|
||||||
+ if (filter->is_port)
|
|
||||||
+ hisi_ptt_remove_rp_filter_attr(hisi_ptt, filter);
|
|
||||||
+ else
|
|
||||||
+ hisi_ptt_remove_req_filter_attr(hisi_ptt, filter);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ptt_remove_all_filter_attributes(void *data)
|
|
||||||
+{
|
|
||||||
+ struct hisi_ptt_filter_desc *filter;
|
|
||||||
+ struct hisi_ptt *hisi_ptt = data;
|
|
||||||
+
|
|
||||||
+ mutex_lock(&hisi_ptt->filter_lock);
|
|
||||||
+
|
|
||||||
+ list_for_each_entry(filter, &hisi_ptt->req_filters, list)
|
|
||||||
+ hisi_ptt_remove_filter_attr(hisi_ptt, filter);
|
|
||||||
+
|
|
||||||
+ list_for_each_entry(filter, &hisi_ptt->port_filters, list)
|
|
||||||
+ hisi_ptt_remove_filter_attr(hisi_ptt, filter);
|
|
||||||
+
|
|
||||||
+ hisi_ptt->sysfs_inited = false;
|
|
||||||
+ mutex_unlock(&hisi_ptt->filter_lock);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int hisi_ptt_init_filter_attributes(struct hisi_ptt *hisi_ptt)
|
|
||||||
+{
|
|
||||||
+ struct hisi_ptt_filter_desc *filter;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ mutex_lock(&hisi_ptt->filter_lock);
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Register the reset callback in the first stage. In reset we traverse
|
|
||||||
+ * the filters list to remove the sysfs attributes so the callback can
|
|
||||||
+ * be called safely even without below filter attributes creation.
|
|
||||||
+ */
|
|
||||||
+ ret = devm_add_action(&hisi_ptt->pdev->dev,
|
|
||||||
+ hisi_ptt_remove_all_filter_attributes,
|
|
||||||
+ hisi_ptt);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto out;
|
|
||||||
+
|
|
||||||
+ list_for_each_entry(filter, &hisi_ptt->port_filters, list) {
|
|
||||||
+ ret = hisi_ptt_create_filter_attr(hisi_ptt, filter);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ list_for_each_entry(filter, &hisi_ptt->req_filters, list) {
|
|
||||||
+ ret = hisi_ptt_create_filter_attr(hisi_ptt, filter);
|
|
||||||
+ if (ret)
|
|
||||||
+ goto out;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ hisi_ptt->sysfs_inited = true;
|
|
||||||
+out:
|
|
||||||
+ mutex_unlock(&hisi_ptt->filter_lock);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void hisi_ptt_update_filters(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct delayed_work *delayed_work = to_delayed_work(work);
|
|
||||||
@@ -443,6 +582,18 @@ static void hisi_ptt_update_filters(struct work_struct *work)
|
|
||||||
info.is_port);
|
|
||||||
if (!filter)
|
|
||||||
continue;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * If filters' sysfs entries hasn't been initialized,
|
|
||||||
+ * then we're still at probe stage. Add the filters to
|
|
||||||
+ * the list and later hisi_ptt_init_filter_attributes()
|
|
||||||
+ * will create sysfs attributes for all the filters.
|
|
||||||
+ */
|
|
||||||
+ if (hisi_ptt->sysfs_inited &&
|
|
||||||
+ hisi_ptt_create_filter_attr(hisi_ptt, filter)) {
|
|
||||||
+ hisi_ptt_del_free_filter(hisi_ptt, filter);
|
|
||||||
+ continue;
|
|
||||||
+ }
|
|
||||||
} else {
|
|
||||||
struct hisi_ptt_filter_desc *tmp;
|
|
||||||
struct list_head *target_list;
|
|
||||||
@@ -452,8 +603,11 @@ static void hisi_ptt_update_filters(struct work_struct *work)
|
|
||||||
|
|
||||||
list_for_each_entry_safe(filter, tmp, target_list, list)
|
|
||||||
if (filter->devid == info.devid) {
|
|
||||||
- hisi_ptt_del_free_filter(hisi_ptt,
|
|
||||||
- filter);
|
|
||||||
+ if (hisi_ptt->sysfs_inited)
|
|
||||||
+ hisi_ptt_remove_filter_attr(
|
|
||||||
+ hisi_ptt,
|
|
||||||
+ filter);
|
|
||||||
+
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -691,10 +845,58 @@ static struct attribute_group hisi_ptt_pmu_format_group = {
|
|
||||||
.attrs = hisi_ptt_pmu_format_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static ssize_t hisi_ptt_filter_multiselect_show(struct device *dev,
|
|
||||||
+ struct device_attribute *attr,
|
|
||||||
+ char *buf)
|
|
||||||
+{
|
|
||||||
+ struct dev_ext_attribute *ext_attr;
|
|
||||||
+
|
|
||||||
+ ext_attr = container_of(attr, struct dev_ext_attribute, attr);
|
|
||||||
+ return sysfs_emit(buf, "%s\n", (char *)ext_attr->var);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct dev_ext_attribute root_port_filters_multiselect = {
|
|
||||||
+ .attr = {
|
|
||||||
+ .attr = { .name = "multiselect", .mode = 0400 },
|
|
||||||
+ .show = hisi_ptt_filter_multiselect_show,
|
|
||||||
+ },
|
|
||||||
+ .var = "1",
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_ptt_pmu_root_ports_attrs[] = {
|
|
||||||
+ &root_port_filters_multiselect.attr.attr,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute_group hisi_ptt_pmu_root_ports_group = {
|
|
||||||
+ .name = HISI_PTT_RP_FILTERS_GRP_NAME,
|
|
||||||
+ .attrs = hisi_ptt_pmu_root_ports_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct dev_ext_attribute requester_filters_multiselect = {
|
|
||||||
+ .attr = {
|
|
||||||
+ .attr = { .name = "multiselect", .mode = 0400 },
|
|
||||||
+ .show = hisi_ptt_filter_multiselect_show,
|
|
||||||
+ },
|
|
||||||
+ .var = "0",
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_ptt_pmu_requesters_attrs[] = {
|
|
||||||
+ &requester_filters_multiselect.attr.attr,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute_group hisi_ptt_pmu_requesters_group = {
|
|
||||||
+ .name = HISI_PTT_REQ_FILTERS_GRP_NAME,
|
|
||||||
+ .attrs = hisi_ptt_pmu_requesters_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const struct attribute_group *hisi_ptt_pmu_groups[] = {
|
|
||||||
&hisi_ptt_cpumask_attr_group,
|
|
||||||
&hisi_ptt_pmu_format_group,
|
|
||||||
&hisi_ptt_tune_group,
|
|
||||||
+ &hisi_ptt_pmu_root_ports_group,
|
|
||||||
+ &hisi_ptt_pmu_requesters_group,
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -1184,6 +1386,13 @@ static int hisi_ptt_probe(struct pci_dev *pdev,
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ ret = hisi_ptt_init_filter_attributes(hisi_ptt);
|
|
||||||
+ if (ret) {
|
|
||||||
+ pci_err(pdev, "failed to init sysfs filter attributes, ret = %d",
|
|
||||||
+ ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.h b/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
index 814c3ef40acd..8342f2069f16 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
@@ -11,6 +11,7 @@
|
|
||||||
|
|
||||||
#include <linux/bits.h>
|
|
||||||
#include <linux/cpumask.h>
|
|
||||||
+#include <linux/device.h>
|
|
||||||
#include <linux/kfifo.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
#include <linux/mutex.h>
|
|
||||||
@@ -139,14 +140,25 @@ struct hisi_ptt_trace_ctrl {
|
|
||||||
u32 type:4;
|
|
||||||
};
|
|
||||||
|
|
||||||
+/*
|
|
||||||
+ * sysfs attribute group name for root port filters and requester filters:
|
|
||||||
+ * /sys/devices/hisi_ptt<sicl_id>_<core_id>/root_port_filters
|
|
||||||
+ * and
|
|
||||||
+ * /sys/devices/hisi_ptt<sicl_id>_<core_id>/requester_filters
|
|
||||||
+ */
|
|
||||||
+#define HISI_PTT_RP_FILTERS_GRP_NAME "root_port_filters"
|
|
||||||
+#define HISI_PTT_REQ_FILTERS_GRP_NAME "requester_filters"
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* struct hisi_ptt_filter_desc - Descriptor of the PTT trace filter
|
|
||||||
+ * @attr: sysfs attribute of this filter
|
|
||||||
* @list: entry of this descriptor in the filter list
|
|
||||||
* @is_port: the PCI device of the filter is a Root Port or not
|
|
||||||
* @name: name of this filter, same as the name of the related PCI device
|
|
||||||
* @devid: the PCI device's devid of the filter
|
|
||||||
*/
|
|
||||||
struct hisi_ptt_filter_desc {
|
|
||||||
+ struct device_attribute attr;
|
|
||||||
struct list_head list;
|
|
||||||
bool is_port;
|
|
||||||
char *name;
|
|
||||||
@@ -196,6 +208,7 @@ struct hisi_ptt_pmu_buf {
|
|
||||||
* @port_filters: the filter list of root ports
|
|
||||||
* @req_filters: the filter list of requester ID
|
|
||||||
* @filter_lock: lock to protect the filters
|
|
||||||
+ * @sysfs_inited: whether the filters' sysfs entries has been initialized
|
|
||||||
* @port_mask: port mask of the managed root ports
|
|
||||||
* @work: delayed work for filter updating
|
|
||||||
* @filter_update_lock: spinlock to protect the filter update fifo
|
|
||||||
@@ -223,6 +236,7 @@ struct hisi_ptt {
|
|
||||||
struct list_head port_filters;
|
|
||||||
struct list_head req_filters;
|
|
||||||
struct mutex filter_lock;
|
|
||||||
+ bool sysfs_inited;
|
|
||||||
u16 port_mask;
|
|
||||||
|
|
||||||
/*
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
From db12a7b834f2a871db351062740ecafffb78fac6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yicong Yang <yangyicong@huawei.com>
|
|
||||||
Date: Wed, 7 Jun 2023 17:31:22 +0800
|
|
||||||
Subject: [PATCH 15/19] hwtracing: hisi_ptt: Advertise PERF_PMU_CAP_NO_EXCLUDE
|
|
||||||
for PTT PMU
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I7BZYX
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
|
|
||||||
The PTT trace collects PCIe TLP headers from the PCIe link and don't
|
|
||||||
have the ability to exclude certain context. It doesn't support itrace
|
|
||||||
as well. So only advertise PERF_PMU_CAP_NO_EXCLUDE. This will greatly
|
|
||||||
save the storage of final data. Tested tracing idle link for ~15s,
|
|
||||||
without this patch we'll collect ~28.682MB data for context related
|
|
||||||
information and with this patch it reduced to ~0.226MB.
|
|
||||||
|
|
||||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index 31977a7c7e68..afd069245a1f 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -1248,7 +1248,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt)
|
|
||||||
|
|
||||||
hisi_ptt->hisi_ptt_pmu = (struct pmu) {
|
|
||||||
.module = THIS_MODULE,
|
|
||||||
- .capabilities = PERF_PMU_CAP_EXCLUSIVE | PERF_PMU_CAP_ITRACE,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
.task_ctx_nr = perf_sw_context,
|
|
||||||
.attr_groups = hisi_ptt_pmu_groups,
|
|
||||||
.event_init = hisi_ptt_pmu_event_init,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,111 +0,0 @@
|
|||||||
From fde19b199000532ee397f2730c7b1cfca1c48a73 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Yicong Yang <yangyicong@huawei.com>
|
|
||||||
Date: Wed, 7 Jun 2023 17:31:23 +0800
|
|
||||||
Subject: [PATCH 16/19] hwtracing: hisi_ptt: Fix potential sleep in atomic
|
|
||||||
context
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v6.5-rc1
|
|
||||||
commit 6c50384ef8b94a527445e3694ae6549e1f15d859
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I7BZYX
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6c50384ef8b94a527445e3694ae6549e1f15d859
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------
|
|
||||||
|
|
||||||
From: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
|
|
||||||
We're using pci_irq_vector() to obtain the interrupt number and then
|
|
||||||
bind it to the CPU start perf under the protection of spinlock in
|
|
||||||
pmu::start(). pci_irq_vector() might sleep since [1] because it will
|
|
||||||
call msi_domain_get_virq() to get the MSI interrupt number and it
|
|
||||||
needs to acquire dev->msi.data->mutex. Getting a mutex will sleep on
|
|
||||||
contention. So use pci_irq_vector() in an atomic context is problematic.
|
|
||||||
|
|
||||||
This patch cached the interrupt number in the probe() and uses the
|
|
||||||
cached data instead to avoid potential sleep.
|
|
||||||
|
|
||||||
[1] commit 82ff8e6b78fc ("PCI/MSI: Use msi_get_virq() in pci_get_vector()")
|
|
||||||
Fixes: ff0de066b463 ("hwtracing: hisi_ptt: Add trace function support for HiSilicon PCIe Tune and Trace device")
|
|
||||||
Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
---
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 17 +++++------------
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.h | 2 ++
|
|
||||||
2 files changed, 7 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index afd069245a1f..f8aa66e37a4e 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -346,16 +346,13 @@ static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt)
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- ret = devm_request_threaded_irq(&pdev->dev,
|
|
||||||
- pci_irq_vector(pdev,
|
|
||||||
- HISI_PTT_TRACE_DMA_IRQ),
|
|
||||||
+ hisi_ptt->trace_irq = pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ);
|
|
||||||
+ ret = devm_request_threaded_irq(&pdev->dev, hisi_ptt->trace_irq,
|
|
||||||
NULL, hisi_ptt_isr, 0,
|
|
||||||
DRV_NAME, hisi_ptt);
|
|
||||||
if (ret) {
|
|
||||||
pci_err(pdev, "failed to request irq %d, ret = %d\n",
|
|
||||||
- pci_irq_vector(pdev,
|
|
||||||
- HISI_PTT_TRACE_DMA_IRQ),
|
|
||||||
- ret);
|
|
||||||
+ hisi_ptt->trace_irq, ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1130,9 +1127,7 @@ static void hisi_ptt_pmu_start(struct perf_event *event, int flags)
|
|
||||||
* core in event_function_local(). If CPU passed is offline we'll fail
|
|
||||||
* here, just log it since we can do nothing here.
|
|
||||||
*/
|
|
||||||
- ret = irq_set_affinity(pci_irq_vector(hisi_ptt->pdev,
|
|
||||||
- HISI_PTT_TRACE_DMA_IRQ),
|
|
||||||
- cpumask_of(cpu));
|
|
||||||
+ ret = irq_set_affinity(hisi_ptt->trace_irq, cpumask_of(cpu));
|
|
||||||
if (ret)
|
|
||||||
dev_warn(dev, "failed to set the affinity of trace interrupt\n");
|
|
||||||
|
|
||||||
@@ -1435,9 +1430,7 @@ static int hisi_ptt_cpu_teardown(unsigned int cpu, struct hlist_node *node)
|
|
||||||
* Also make sure the interrupt bind to the migrated CPU as well. Warn
|
|
||||||
* the user on failure here.
|
|
||||||
*/
|
|
||||||
- if (irq_set_affinity(pci_irq_vector(hisi_ptt->pdev,
|
|
||||||
- HISI_PTT_TRACE_DMA_IRQ),
|
|
||||||
- cpumask_of(target)))
|
|
||||||
+ if (irq_set_affinity(hisi_ptt->trace_irq, cpumask_of(target)))
|
|
||||||
dev_warn(dev, "failed to set the affinity of trace interrupt\n");
|
|
||||||
|
|
||||||
hisi_ptt->trace_ctrl.on_cpu = target;
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.h b/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
index 8342f2069f16..435260920267 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.h
|
|
||||||
@@ -201,6 +201,7 @@ struct hisi_ptt_pmu_buf {
|
|
||||||
* @pdev: pci_dev of this PTT device
|
|
||||||
* @tune_lock: lock to serialize the tune process
|
|
||||||
* @pmu_lock: lock to serialize the perf process
|
|
||||||
+ * @trace_irq: interrupt number used by trace
|
|
||||||
* @upper_bdf: the upper BDF range of the PCI devices
|
|
||||||
* managed by this PTT device
|
|
||||||
* @lower_bdf: the lower BDF range of the PCI devices
|
|
||||||
@@ -223,6 +224,7 @@ struct hisi_ptt {
|
|
||||||
struct pci_dev *pdev;
|
|
||||||
struct mutex tune_lock;
|
|
||||||
spinlock_t pmu_lock;
|
|
||||||
+ int trace_irq;
|
|
||||||
u32 upper_bdf;
|
|
||||||
u32 lower_bdf;
|
|
||||||
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
From 5fb3efe86694b0340b9bf17b060022495bafdb00 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Junhao He <hejunhao3@huawei.com>
|
|
||||||
Date: Tue, 20 Jun 2023 22:06:43 +0800
|
|
||||||
Subject: [PATCH 17/19] hwtracing: hisi_ptt: Keep to advertise
|
|
||||||
PERF_PMU_CAP_EXCLUSIVE
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I7F2F2
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
Keep to advertise PERF_PMU_CAP_EXCLUSIVE. Such pmus can only have one
|
|
||||||
event scheduled at a time, and the perf tool will report device busy.
|
|
||||||
|
|
||||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index f8aa66e37a4e..ea981afb55fe 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -1243,7 +1243,8 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt)
|
|
||||||
|
|
||||||
hisi_ptt->hisi_ptt_pmu = (struct pmu) {
|
|
||||||
.module = THIS_MODULE,
|
|
||||||
- .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE |
|
|
||||||
+ PERF_PMU_CAP_EXCLUSIVE,
|
|
||||||
.task_ctx_nr = perf_sw_context,
|
|
||||||
.attr_groups = hisi_ptt_pmu_groups,
|
|
||||||
.event_init = hisi_ptt_pmu_event_init,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
From dc4d7fdddf976f9f14ce4b37c5dacd23a2219ed9 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Junhao He <hejunhao3@huawei.com>
|
|
||||||
Date: Tue, 20 Jun 2023 22:06:42 +0800
|
|
||||||
Subject: [PATCH 18/19] hwtracing: hisi_ptt: Add dummy callback pmu::read()
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I7F2F2
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
When the perf is tracing hisi_ptt pmu and then stopped immediately
|
|
||||||
with "ctrl + c". the perf will call pmu::read() to updata trace data,
|
|
||||||
but driver does not implement the callback pmu::read().
|
|
||||||
Will cause the following panic.
|
|
||||||
|
|
||||||
root@localhost:/# perf record -m,16M -e hisi_ptt0_2/xxx/ -C 0
|
|
||||||
^C
|
|
||||||
[ perf record: Woken up 0 times to write data ]
|
|
||||||
[ 3693.734230] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
|
|
||||||
[ 3693.747212] Mem abort info:
|
|
||||||
[ 3693.749991] ESR = 0x0000000086000006
|
|
||||||
[ 3693.753725] EC = 0x21: IABT (current EL), IL = 32 bits
|
|
||||||
[ 3693.759022] SET = 0, FnV = 0
|
|
||||||
[ 3693.762062] EA = 0, S1PTW = 0
|
|
||||||
[ 3693.765188] FSC = 0x06: level 2 translation fault
|
|
||||||
[ 3693.770051] user pgtable: 4k pages, 48-bit VAs, pgdp=000008302912e000
|
|
||||||
[ 3693.776477] [0000000000000000] pgd=0800083019fc2003, p4d=0800083019fc2003, pud=0800083019fca003, pmd=0000000000000000
|
|
||||||
[ 3693.787072] Internal error: Oops: 0000000086000006 [#1] PREEMPT SMP
|
|
||||||
[ 3693.822414] pstate: 614008c9 (nZCv daIF +PAN -UAO -TCO +DIT -SSBS BTYPE=-c)
|
|
||||||
[ 3693.829361] pc : 0x0
|
|
||||||
[ 3693.831534] lr : __perf_event_read+0x110/0x208
|
|
||||||
[ 3693.835966] sp : ffff800008003eb0
|
|
||||||
[ 3693.839266] x29: ffff800008003eb0 x28: ffffa4f0d14f1100 x27: 0000000000000001
|
|
||||||
[ 3693.846388] x26: ffffa4f0d14f1100 x25: 0000000000000000 x24: 0000000000000000
|
|
||||||
[ 3693.853509] x23: ffff082197adf4f8 x22: 0000000000000000 x21: ffff80001f8ebc28
|
|
||||||
[ 3693.860630] x20: ffff08478be506c8 x19: ffff083028f22220 x18: 0000000000000000
|
|
||||||
[ 3693.867751] x17: ffff6356bb355000 x16: ffff800008000000 x15: 0000000000000000
|
|
||||||
[ 3693.874871] x14: 0000000000000002 x13: 0000000000000000 x12: 0000000000000040
|
|
||||||
[ 3693.881992] x11: ffff08300a915b40 x10: ffff08300a915b42 x9 : ffffa4f0ce6ee5a0
|
|
||||||
[ 3693.889113] x8 : ffff083000401268 x7 : 0000000000000000 x6 : 000000108dce8ee0
|
|
||||||
[ 3693.896234] x5 : 01ffffffffffffff x4 : 0000000000000000 x3 : 000000000112024a
|
|
||||||
[ 3693.903355] x2 : 000000003cadb114 x1 : 0000000000000000 x0 : ffff083028f22220
|
|
||||||
[ 3693.910476] Call trace:
|
|
||||||
[ 3693.912908] 0x0
|
|
||||||
[ 3693.914733] __flush_smp_call_function_queue+0x154/0x258
|
|
||||||
[ 3693.920032] generic_smp_call_function_single_interrupt+0x1c/0x30
|
|
||||||
[ 3693.926111] ipi_handler+0x90/0x2d0
|
|
||||||
[ 3693.929588] handle_percpu_devid_irq+0x90/0x250
|
|
||||||
[ 3693.934105] generic_handle_domain_irq+0x34/0x58
|
|
||||||
[ 3693.938708] gic_handle_irq+0x12c/0x270
|
|
||||||
[ 3693.942530] call_on_irq_stack+0x24/0x30
|
|
||||||
[ 3693.946439] do_interrupt_handler+0x88/0x98
|
|
||||||
[ 3693.950608] el1_interrupt+0x48/0xe8
|
|
||||||
[ 3693.954171] el1h_64_irq_handler+0x18/0x28
|
|
||||||
[ 3693.958253] el1h_64_irq+0x78/0x80
|
|
||||||
[ 3693.961641] default_idle_call+0x5c/0x180
|
|
||||||
[ 3693.965636] do_idle+0x25c/0x2d0
|
|
||||||
[ 3693.968851] cpu_startup_entry+0x2c/0x40
|
|
||||||
[ 3693.972760] rest_init+0xec/0xf8
|
|
||||||
[ 3693.975974] arch_call_rest_init+0x18/0x20
|
|
||||||
[ 3693.980057] start_kernel+0x41c/0x7f0
|
|
||||||
[ 3693.983705] __primary_switched+0xbc/0xd0
|
|
||||||
[ 3693.987702] Code: ???????? ???????? ???????? ???????? (????????)
|
|
||||||
[ 3693.993781] ---[ end trace 0000000000000000 ]---
|
|
||||||
[ 3694.182495] Kernel panic - not syncing: Oops: Fatal exception in interrupt
|
|
||||||
[ 3694.189354] SMP: stopping secondary CPUs
|
|
||||||
[ 3694.193276] Kernel Offset: 0x24f0c6470000 from 0xffff800008000000
|
|
||||||
[ 3694.199354] PHYS_OFFSET: 0x0
|
|
||||||
[ 3694.202220] CPU features: 0x000000,00d005be,12affea7
|
|
||||||
[ 3694.207170] Memory Limit: none
|
|
||||||
[ 3694.389463] ---[ end Kernel panic - not syncing: Oops: Fatal exception in interrupt ]---
|
|
||||||
|
|
||||||
Signed-off-by: Junhao He <hejunhao3@huawei.com>
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/hwtracing/ptt/hisi_ptt.c | 5 +++++
|
|
||||||
1 file changed, 5 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/hwtracing/ptt/hisi_ptt.c b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
index ea981afb55fe..793352390191 100644
|
|
||||||
--- a/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
+++ b/drivers/hwtracing/ptt/hisi_ptt.c
|
|
||||||
@@ -1210,6 +1210,10 @@ static void hisi_ptt_pmu_del(struct perf_event *event, int flags)
|
|
||||||
hisi_ptt_pmu_stop(event, PERF_EF_UPDATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void hisi_ptt_pmu_read(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void hisi_ptt_remove_cpuhp_instance(void *hotplug_node)
|
|
||||||
{
|
|
||||||
cpuhp_state_remove_instance_nocalls(hisi_ptt_pmu_online, hotplug_node);
|
|
||||||
@@ -1254,6 +1258,7 @@ static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt)
|
|
||||||
.stop = hisi_ptt_pmu_stop,
|
|
||||||
.add = hisi_ptt_pmu_add,
|
|
||||||
.del = hisi_ptt_pmu_del,
|
|
||||||
+ .read = hisi_ptt_pmu_read,
|
|
||||||
};
|
|
||||||
|
|
||||||
reg = readl(hisi_ptt->iobase + HISI_PTT_LOCATION);
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
From d8c1e574fad2421eb6c9b394b4d2de33ebb728b5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
Date: Tue, 24 Oct 2023 19:54:57 +0800
|
|
||||||
Subject: [PATCH 19/19] config: arm64: Enable config of hisi ptt
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I5RP8T
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
|
|
||||||
Enable config of hisi ptt. Set CONFIG_HISI_PTT to m.
|
|
||||||
|
|
||||||
Signed-off-by: YunYi Yang <yangyunyi2@huawei.com>
|
|
||||||
---
|
|
||||||
arch/arm64/configs/openeuler_defconfig | 1 +
|
|
||||||
1 file changed, 1 insertion(+)
|
|
||||||
|
|
||||||
diff --git a/arch/arm64/configs/openeuler_defconfig b/arch/arm64/configs/openeuler_defconfig
|
|
||||||
index 60b1db8e190c..6667015bfa35 100644
|
|
||||||
--- a/arch/arm64/configs/openeuler_defconfig
|
|
||||||
+++ b/arch/arm64/configs/openeuler_defconfig
|
|
||||||
@@ -5135,6 +5135,7 @@ CONFIG_NVMEM=y
|
|
||||||
# CONFIG_FPGA is not set
|
|
||||||
# CONFIG_FSI is not set
|
|
||||||
CONFIG_TEE=m
|
|
||||||
+CONFIG_HISI_PTT=m
|
|
||||||
|
|
||||||
#
|
|
||||||
# TEE drivers
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,336 +0,0 @@
|
|||||||
From f28828d9b8b7171aa25f83cd9db9a95493db7c81 Mon Sep 17 00:00:00 2001
|
|
||||||
From: lauyarn <liuyang645@huawei.com>
|
|
||||||
Date: Tue, 14 Nov 2023 11:25:22 +0800
|
|
||||||
Subject: [PATCH] Subject: [PATCH] crypto: hisilicon - fix different versions
|
|
||||||
of devices driver compatibility issue
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8BFOM
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
In order to be compatible with devices of different versions, V1 in the
|
|
||||||
accelerator driver is now isolated, and other versions are the previous
|
|
||||||
V2 processing flow.
|
|
||||||
|
|
||||||
Signed-off-by: Liu Yang <liuyang645@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/crypto/hisilicon/hpre/hpre_main.c | 2 +-
|
|
||||||
drivers/crypto/hisilicon/qm.c | 70 +++++++++--------------
|
|
||||||
drivers/crypto/hisilicon/qm.h | 14 ++---
|
|
||||||
drivers/crypto/hisilicon/rde/rde_main.c | 12 +---
|
|
||||||
drivers/crypto/hisilicon/sec2/sec_main.c | 12 +---
|
|
||||||
drivers/crypto/hisilicon/zip/zip_main.c | 17 ++----
|
|
||||||
6 files changed, 41 insertions(+), 86 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c
|
|
||||||
index cbe8ea438fd2..8c71353cd4b5 100644
|
|
||||||
--- a/drivers/crypto/hisilicon/hpre/hpre_main.c
|
|
||||||
+++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
|
|
||||||
@@ -840,7 +840,7 @@ static int hpre_pf_probe_init(struct hisi_qm *qm)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- if (qm->ver != QM_HW_V2)
|
|
||||||
+ if (qm->ver == QM_HW_V1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
qm->ctrl_q_num = HPRE_QUEUE_NUM_V2;
|
|
||||||
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c
|
|
||||||
index 25bb24b4c131..398d5bab439e 100644
|
|
||||||
--- a/drivers/crypto/hisilicon/qm.c
|
|
||||||
+++ b/drivers/crypto/hisilicon/qm.c
|
|
||||||
@@ -814,7 +814,7 @@ static int qm_irq_register(struct hisi_qm *qm)
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- if (qm->ver == QM_HW_V2) {
|
|
||||||
+ if (qm->ver != QM_HW_V1) {
|
|
||||||
ret = request_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR),
|
|
||||||
qm_aeq_irq, IRQF_SHARED, qm->dev_name, qm);
|
|
||||||
if (ret)
|
|
||||||
@@ -845,13 +845,12 @@ static void qm_irq_unregister(struct hisi_qm *qm)
|
|
||||||
|
|
||||||
free_irq(pci_irq_vector(pdev, QM_EQ_EVENT_IRQ_VECTOR), qm);
|
|
||||||
|
|
||||||
- if (qm->ver == QM_HW_V2) {
|
|
||||||
- free_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR), qm);
|
|
||||||
+ if (qm->ver == QM_HW_V1)
|
|
||||||
+ return;
|
|
||||||
|
|
||||||
- if (qm->fun_type == QM_HW_PF)
|
|
||||||
- free_irq(pci_irq_vector(pdev,
|
|
||||||
- QM_ABNORMAL_EVENT_IRQ_VECTOR), qm);
|
|
||||||
- }
|
|
||||||
+ free_irq(pci_irq_vector(pdev, QM_AEQ_EVENT_IRQ_VECTOR), qm);
|
|
||||||
+ if (qm->fun_type == QM_HW_PF)
|
|
||||||
+ free_irq(pci_irq_vector(pdev, QM_ABNORMAL_EVENT_IRQ_VECTOR), qm);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void qm_init_qp_status(struct hisi_qp *qp)
|
|
||||||
@@ -873,36 +872,26 @@ static void qm_vft_data_cfg(struct hisi_qm *qm, enum vft_type type, u32 base,
|
|
||||||
if (number > 0) {
|
|
||||||
switch (type) {
|
|
||||||
case SQC_VFT:
|
|
||||||
- switch (qm->ver) {
|
|
||||||
- case QM_HW_V1:
|
|
||||||
+ if (qm->ver == QM_HW_V1) {
|
|
||||||
tmp = QM_SQC_VFT_BUF_SIZE |
|
|
||||||
QM_SQC_VFT_SQC_SIZE |
|
|
||||||
QM_SQC_VFT_INDEX_NUMBER |
|
|
||||||
QM_SQC_VFT_VALID |
|
|
||||||
(u64)base << QM_SQC_VFT_START_SQN_SHIFT;
|
|
||||||
- break;
|
|
||||||
- case QM_HW_V2:
|
|
||||||
+ } else {
|
|
||||||
tmp = (u64)base << QM_SQC_VFT_START_SQN_SHIFT |
|
|
||||||
QM_SQC_VFT_VALID |
|
|
||||||
(u64)(number - 1) << QM_SQC_VFT_SQN_SHIFT;
|
|
||||||
- break;
|
|
||||||
- case QM_HW_UNKNOWN:
|
|
||||||
- break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CQC_VFT:
|
|
||||||
- switch (qm->ver) {
|
|
||||||
- case QM_HW_V1:
|
|
||||||
+ if (qm->ver == QM_HW_V1) {
|
|
||||||
tmp = QM_CQC_VFT_BUF_SIZE |
|
|
||||||
QM_CQC_VFT_SQC_SIZE |
|
|
||||||
QM_CQC_VFT_INDEX_NUMBER |
|
|
||||||
QM_CQC_VFT_VALID;
|
|
||||||
- break;
|
|
||||||
- case QM_HW_V2:
|
|
||||||
+ } else {
|
|
||||||
tmp = QM_CQC_VFT_VALID;
|
|
||||||
- break;
|
|
||||||
- case QM_HW_UNKNOWN:
|
|
||||||
- break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
@@ -1850,7 +1839,7 @@ static int qm_sq_ctx_cfg(struct hisi_qp *qp, int qp_id, int pasid)
|
|
||||||
if (ver == QM_HW_V1) {
|
|
||||||
sqc.dw3 = cpu_to_le32(QM_MK_SQC_DW3_V1(0, 0, 0, qm->sqe_size));
|
|
||||||
sqc.w8 = cpu_to_le16(QM_Q_DEPTH - 1);
|
|
||||||
- } else if (ver == QM_HW_V2) {
|
|
||||||
+ } else {
|
|
||||||
sqc.dw3 = cpu_to_le32(QM_MK_SQC_DW3_V2(qm->sqe_size));
|
|
||||||
sqc.w8 = 0; /* rand_qc */
|
|
||||||
}
|
|
||||||
@@ -1873,7 +1862,7 @@ static int qm_cq_ctx_cfg(struct hisi_qp *qp, int qp_id, int pasid)
|
|
||||||
cqc.dw3 = cpu_to_le32(QM_MK_CQC_DW3_V1(0, 0, 0,
|
|
||||||
QM_QC_CQE_SIZE));
|
|
||||||
cqc.w8 = cpu_to_le16(QM_Q_DEPTH - 1);
|
|
||||||
- } else if (ver == QM_HW_V2) {
|
|
||||||
+ } else {
|
|
||||||
cqc.dw3 = cpu_to_le32(QM_MK_CQC_DW3_V2(QM_QC_CQE_SIZE));
|
|
||||||
cqc.w8 = 0; /* rand_qc */
|
|
||||||
}
|
|
||||||
@@ -2094,14 +2083,13 @@ static void hisi_qm_cache_wb(struct hisi_qm *qm)
|
|
||||||
{
|
|
||||||
unsigned int val;
|
|
||||||
|
|
||||||
- if (qm->ver == QM_HW_V2) {
|
|
||||||
- writel(0x1, qm->io_base + QM_CACHE_WB_START);
|
|
||||||
- if (readl_relaxed_poll_timeout(qm->io_base + QM_CACHE_WB_DONE,
|
|
||||||
- val, val & BIT(0), POLL_PERIOD,
|
|
||||||
- POLL_TIMEOUT))
|
|
||||||
- dev_err(&qm->pdev->dev,
|
|
||||||
- "QM writeback sqc cache fail!\n");
|
|
||||||
- }
|
|
||||||
+ if (qm->ver == QM_HW_V1)
|
|
||||||
+ return;
|
|
||||||
+
|
|
||||||
+ writel(0x1, qm->io_base + QM_CACHE_WB_START);
|
|
||||||
+ if (readl_relaxed_poll_timeout(qm->io_base + QM_CACHE_WB_DONE,
|
|
||||||
+ val, val & BIT(0), 10, 1000))
|
|
||||||
+ dev_err(&qm->pdev->dev, "QM writeback sqc cache fail!\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
int hisi_qm_get_free_qp_num(struct hisi_qm *qm)
|
|
||||||
@@ -2202,12 +2190,12 @@ static int hisi_qm_uacce_mmap(struct uacce_queue *q,
|
|
||||||
|
|
||||||
switch (qfr->type) {
|
|
||||||
case UACCE_QFRT_MMIO:
|
|
||||||
- if (qm->ver == QM_HW_V2) {
|
|
||||||
- if (WARN_ON(sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR +
|
|
||||||
- QM_V2_DOORBELL_OFFSET / PAGE_SIZE)))
|
|
||||||
+ if (qm->ver == QM_HW_V1) {
|
|
||||||
+ if (WARN_ON(sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR))
|
|
||||||
return -EINVAL;
|
|
||||||
} else {
|
|
||||||
- if (WARN_ON(sz > PAGE_SIZE * QM_DOORBELL_PAGE_NR))
|
|
||||||
+ if (WARN_ON(sz > PAGE_SIZE * (QM_DOORBELL_PAGE_NR +
|
|
||||||
+ QM_V2_DOORBELL_OFFSET / PAGE_SIZE)))
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -2743,16 +2731,10 @@ int hisi_qm_init(struct hisi_qm *qm)
|
|
||||||
struct device *dev = &pdev->dev;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- switch (qm->ver) {
|
|
||||||
- case QM_HW_V1:
|
|
||||||
+ if (qm->ver == QM_HW_V1)
|
|
||||||
qm->ops = &qm_hw_ops_v1;
|
|
||||||
- break;
|
|
||||||
- case QM_HW_V2:
|
|
||||||
+ else
|
|
||||||
qm->ops = &qm_hw_ops_v2;
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
|
|
||||||
if (qm->use_uacce) {
|
|
||||||
dev_info(dev, "qm register to uacce\n");
|
|
||||||
@@ -2772,7 +2754,7 @@ int hisi_qm_init(struct hisi_qm *qm)
|
|
||||||
goto err_irq_register;
|
|
||||||
|
|
||||||
mutex_init(&qm->mailbox_lock);
|
|
||||||
- if (qm->fun_type == QM_HW_VF && qm->ver == QM_HW_V2) {
|
|
||||||
+ if (qm->fun_type == QM_HW_VF && qm->ver != QM_HW_V1) {
|
|
||||||
/* v2 or v3 starts to support get vft by mailbox */
|
|
||||||
ret = hisi_qm_get_vft(qm, &qm->qp_base, &qm->qp_num);
|
|
||||||
if (ret)
|
|
||||||
diff --git a/drivers/crypto/hisilicon/qm.h b/drivers/crypto/hisilicon/qm.h
|
|
||||||
index 9f5e440d7396..89c0977ac81f 100644
|
|
||||||
--- a/drivers/crypto/hisilicon/qm.h
|
|
||||||
+++ b/drivers/crypto/hisilicon/qm.h
|
|
||||||
@@ -114,6 +114,7 @@ enum qm_hw_ver {
|
|
||||||
QM_HW_UNKNOWN = -1,
|
|
||||||
QM_HW_V1 = 0x20,
|
|
||||||
QM_HW_V2 = 0x21,
|
|
||||||
+ QM_HW_V3 = 0x30,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum qm_fun_type {
|
|
||||||
@@ -398,7 +399,6 @@ static inline int q_num_set(const char *val, const struct kernel_param *kp,
|
|
||||||
struct pci_dev *pdev = pci_get_device(PCI_VENDOR_ID_HUAWEI,
|
|
||||||
device, NULL);
|
|
||||||
u32 n, q_num;
|
|
||||||
- u8 rev_id;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!val)
|
|
||||||
@@ -409,17 +409,10 @@ static inline int q_num_set(const char *val, const struct kernel_param *kp,
|
|
||||||
pr_info("No device found currently, suppose queue number is %d\n",
|
|
||||||
q_num);
|
|
||||||
} else {
|
|
||||||
- rev_id = pdev->revision;
|
|
||||||
- switch (rev_id) {
|
|
||||||
- case QM_HW_V1:
|
|
||||||
+ if (pdev->revision == QM_HW_V1)
|
|
||||||
q_num = QNUM_V1;
|
|
||||||
- break;
|
|
||||||
- case QM_HW_V2:
|
|
||||||
+ else
|
|
||||||
q_num = QNUM_V2;
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = kstrtou32(val, 10, &n);
|
|
||||||
@@ -487,6 +480,7 @@ static inline int hisi_qm_pre_init(struct hisi_qm *qm,
|
|
||||||
switch (pdev->revision) {
|
|
||||||
case QM_HW_V1:
|
|
||||||
case QM_HW_V2:
|
|
||||||
+ case QM_HW_V3:
|
|
||||||
qm->ver = pdev->revision;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
diff --git a/drivers/crypto/hisilicon/rde/rde_main.c b/drivers/crypto/hisilicon/rde/rde_main.c
|
|
||||||
index f2e00ff891db..9fee21bfaed0 100644
|
|
||||||
--- a/drivers/crypto/hisilicon/rde/rde_main.c
|
|
||||||
+++ b/drivers/crypto/hisilicon/rde/rde_main.c
|
|
||||||
@@ -647,18 +647,10 @@ static int hisi_rde_pf_probe_init(struct hisi_qm *qm)
|
|
||||||
hisi_rde->ctrl = ctrl;
|
|
||||||
ctrl->hisi_rde = hisi_rde;
|
|
||||||
|
|
||||||
- switch (qm->ver) {
|
|
||||||
- case QM_HW_V1:
|
|
||||||
+ if (qm->ver == QM_HW_V1)
|
|
||||||
qm->ctrl_q_num = HRDE_QUEUE_NUM_V1;
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- case QM_HW_V2:
|
|
||||||
+ else
|
|
||||||
qm->ctrl_q_num = HRDE_QUEUE_NUM_V2;
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- default:
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
|
|
||||||
ret = qm->err_ini.set_usr_domain_cache(qm);
|
|
||||||
if (ret)
|
|
||||||
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c
|
|
||||||
index 0f32dcb69e12..2f8dd6c30cb1 100644
|
|
||||||
--- a/drivers/crypto/hisilicon/sec2/sec_main.c
|
|
||||||
+++ b/drivers/crypto/hisilicon/sec2/sec_main.c
|
|
||||||
@@ -738,18 +738,10 @@ static int sec_pf_probe_init(struct hisi_qm *qm)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- switch (qm->ver) {
|
|
||||||
- case QM_HW_V1:
|
|
||||||
+ if (qm->ver == QM_HW_V1)
|
|
||||||
qm->ctrl_q_num = SEC_QUEUE_NUM_V1;
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- case QM_HW_V2:
|
|
||||||
+ else
|
|
||||||
qm->ctrl_q_num = SEC_QUEUE_NUM_V2;
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- default:
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
|
|
||||||
ret = qm->err_ini.set_usr_domain_cache(qm);
|
|
||||||
if (ret)
|
|
||||||
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c
|
|
||||||
index 1ca51793e26a..34c62e990602 100644
|
|
||||||
--- a/drivers/crypto/hisilicon/zip/zip_main.c
|
|
||||||
+++ b/drivers/crypto/hisilicon/zip/zip_main.c
|
|
||||||
@@ -790,18 +790,10 @@ static int hisi_zip_pf_probe_init(struct hisi_qm *qm)
|
|
||||||
zip->ctrl = ctrl;
|
|
||||||
ctrl->hisi_zip = zip;
|
|
||||||
|
|
||||||
- switch (qm->ver) {
|
|
||||||
- case QM_HW_V1:
|
|
||||||
+ if (qm->ver == QM_HW_V1)
|
|
||||||
qm->ctrl_q_num = HZIP_QUEUE_NUM_V1;
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- case QM_HW_V2:
|
|
||||||
+ else
|
|
||||||
qm->ctrl_q_num = HZIP_QUEUE_NUM_V2;
|
|
||||||
- break;
|
|
||||||
-
|
|
||||||
- default:
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
|
|
||||||
ret = qm->err_ini.set_usr_domain_cache(qm);
|
|
||||||
if (ret)
|
|
||||||
@@ -818,7 +810,10 @@ static int hisi_zip_qm_pre_init(struct hisi_qm *qm, struct pci_dev *pdev)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
- qm->algs = "zlib\ngzip\nxts(sm4)\nxts(aes)\n";
|
|
||||||
+ if (pdev->revision >= QM_HW_V3)
|
|
||||||
+ qm->algs = "zlib\ngzip\nxts(sm4)\nxts(aes)\ndeflate\n";
|
|
||||||
+ else
|
|
||||||
+ qm->algs = "zlib\ngzip\nxts(sm4)\nxts(aes)\n";
|
|
||||||
qm->uacce_mode = uacce_mode;
|
|
||||||
qm->pdev = pdev;
|
|
||||||
ret = hisi_qm_pre_init(qm, pf_q_num, HZIP_PF_DEF_Q_BASE);
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,86 +0,0 @@
|
|||||||
From a7e133186aa078eb9450e47121f5d26a4330f83c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:31:57 +0800
|
|
||||||
Subject: [PATCH 01/21] perf arm-spe: Include bitops.h for BIT() macro
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit c185f1cde46653cd0a7a1eaf461d16c462870781
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
Include header linux/bitops.h, directly use its BIT() macro and remove
|
|
||||||
the self defined macros.
|
|
||||||
|
|
||||||
Committer notes:
|
|
||||||
|
|
||||||
Use BIT_ULL() instead of BIT to build on 32-bit arches as mentioned in
|
|
||||||
review by Andre Przywara <andre.przywara@arm.com>. I noticed the build
|
|
||||||
failure when crossbuilding to arm32 from x86_64.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201111071149.815-2-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
|
|
||||||
---
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-decoder.c | 5 +----
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 7 +++----
|
|
||||||
2 files changed, 4 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
|
|
||||||
index 322961c863f0..3993c1524c73 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
|
|
||||||
@@ -7,6 +7,7 @@
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
+#include <linux/bitops.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
|
|
||||||
#include "cache.h"
|
|
||||||
@@ -16,10 +17,6 @@
|
|
||||||
#include "arm-spe-pkt-decoder.h"
|
|
||||||
#include "arm-spe-decoder.h"
|
|
||||||
|
|
||||||
-#ifndef BIT
|
|
||||||
-#define BIT(n) (1UL << (n))
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
struct arm_spe_decoder {
|
|
||||||
int (*get_trace)(struct arm_spe_buffer *buffer, void *data);
|
|
||||||
void *data;
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index b94001b756c7..5f65a3a70c57 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -8,13 +8,12 @@
|
|
||||||
#include <string.h>
|
|
||||||
#include <endian.h>
|
|
||||||
#include <byteswap.h>
|
|
||||||
+#include <linux/bitops.h>
|
|
||||||
|
|
||||||
#include "arm-spe-pkt-decoder.h"
|
|
||||||
|
|
||||||
-#define BIT(n) (1ULL << (n))
|
|
||||||
-
|
|
||||||
-#define NS_FLAG BIT(63)
|
|
||||||
-#define EL_FLAG (BIT(62) | BIT(61))
|
|
||||||
+#define NS_FLAG BIT_ULL(63)
|
|
||||||
+#define EL_FLAG (BIT_ULL(62) | BIT_ULL(61))
|
|
||||||
|
|
||||||
#define SPE_HEADER0_PAD 0x0
|
|
||||||
#define SPE_HEADER0_END 0x1
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
From 396666c4672c0ac44f4ce0e16f2f7ef33291c4f4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:31:58 +0800
|
|
||||||
Subject: [PATCH 02/21] perf arm-spe: Fix a typo in comment
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 903b659436b706928934ff5ef59d591267e5ce1a
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
Fix a typo: s/iff/if.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201111071149.815-3-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 5f65a3a70c57..12a96585da94 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -142,7 +142,7 @@ static int arm_spe_get_events(const unsigned char *buf, size_t len,
|
|
||||||
|
|
||||||
/* we use index to identify Events with a less number of
|
|
||||||
* comparisons in arm_spe_pkt_desc(): E.g., the LLC-ACCESS,
|
|
||||||
- * LLC-REFILL, and REMOTE-ACCESS events are identified iff
|
|
||||||
+ * LLC-REFILL, and REMOTE-ACCESS events are identified if
|
|
||||||
* index > 1.
|
|
||||||
*/
|
|
||||||
packet->index = ret - 1;
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,84 +0,0 @@
|
|||||||
From 8563343c538c17d40bcfabd329cf8de1d722c1ca Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:31:59 +0800
|
|
||||||
Subject: [PATCH 03/21] perf arm-spe: Refactor payload size calculation
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit b2ded2e2e2764e502fc025f615210434f1eaa2a9
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
This patch defines macro to extract "sz" field from header, and renames
|
|
||||||
the function payloadlen() to arm_spe_payload_len().
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201111071149.815-4-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
tools/include/linux/bits.h | 4 ++++
|
|
||||||
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 18 +++++++++---------
|
|
||||||
2 files changed, 13 insertions(+), 9 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/include/linux/bits.h b/tools/include/linux/bits.h
|
|
||||||
index 2b7b532c1d51..0d431f8e70cf 100644
|
|
||||||
--- a/tools/include/linux/bits.h
|
|
||||||
+++ b/tools/include/linux/bits.h
|
|
||||||
@@ -3,6 +3,10 @@
|
|
||||||
#define __LINUX_BITS_H
|
|
||||||
#include <asm/bitsperlong.h>
|
|
||||||
|
|
||||||
+#ifndef BITS_PER_LONG_LONG
|
|
||||||
+#define BITS_PER_LONG_LONG 64
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
#define BIT(nr) (1UL << (nr))
|
|
||||||
#define BIT_ULL(nr) (1ULL << (nr))
|
|
||||||
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 12a96585da94..a8eb7be189ec 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -69,22 +69,22 @@ const char *arm_spe_pkt_name(enum arm_spe_pkt_type type)
|
|
||||||
return arm_spe_packet_name[type];
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* return ARM SPE payload size from its encoding,
|
|
||||||
- * which is in bits 5:4 of the byte.
|
|
||||||
- * 00 : byte
|
|
||||||
- * 01 : halfword (2)
|
|
||||||
- * 10 : word (4)
|
|
||||||
- * 11 : doubleword (8)
|
|
||||||
+/*
|
|
||||||
+ * Extracts the field "sz" from header bits and converts to bytes:
|
|
||||||
+ * 00 : byte (1)
|
|
||||||
+ * 01 : halfword (2)
|
|
||||||
+ * 10 : word (4)
|
|
||||||
+ * 11 : doubleword (8)
|
|
||||||
*/
|
|
||||||
-static int payloadlen(unsigned char byte)
|
|
||||||
+static unsigned int arm_spe_payload_len(unsigned char hdr)
|
|
||||||
{
|
|
||||||
- return 1 << ((byte & 0x30) >> 4);
|
|
||||||
+ return 1U << ((hdr & GENMASK_ULL(5, 4)) >> 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_payload(const unsigned char *buf, size_t len,
|
|
||||||
struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
- size_t payload_len = payloadlen(buf[0]);
|
|
||||||
+ size_t payload_len = arm_spe_payload_len(buf[0]);
|
|
||||||
|
|
||||||
if (len < 1 + payload_len)
|
|
||||||
return ARM_SPE_NEED_MORE_BYTES;
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,70 +0,0 @@
|
|||||||
From 3c5dcbec06d52582a33bd142000fe41581d79d04 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:00 +0800
|
|
||||||
Subject: [PATCH 04/21] perf arm-spe: Refactor arm_spe_get_events()
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit b65577baf482909225c79d8a6bad44d2a62751f4
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
In function arm_spe_get_events(), the event packet's 'index' is assigned
|
|
||||||
as payload length, but the flow is not directive: it firstly gets the
|
|
||||||
packet length from the return value of arm_spe_get_payload(), the value
|
|
||||||
includes header length (1) and payload length:
|
|
||||||
|
|
||||||
int ret = arm_spe_get_payload(buf, len, packet);
|
|
||||||
|
|
||||||
and then reduces header length from packet length, so finally get the
|
|
||||||
payload length:
|
|
||||||
|
|
||||||
packet->index = ret - 1;
|
|
||||||
|
|
||||||
To simplify the code, this patch directly assigns payload length to
|
|
||||||
event packet's index; and at the end it calls arm_spe_get_payload() to
|
|
||||||
return the payload value.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201111071149.815-5-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 6 ++----
|
|
||||||
1 file changed, 2 insertions(+), 4 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index a8eb7be189ec..57904da89db1 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -136,8 +136,6 @@ static int arm_spe_get_timestamp(const unsigned char *buf, size_t len,
|
|
||||||
static int arm_spe_get_events(const unsigned char *buf, size_t len,
|
|
||||||
struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
- int ret = arm_spe_get_payload(buf, len, packet);
|
|
||||||
-
|
|
||||||
packet->type = ARM_SPE_EVENTS;
|
|
||||||
|
|
||||||
/* we use index to identify Events with a less number of
|
|
||||||
@@ -145,9 +143,9 @@ static int arm_spe_get_events(const unsigned char *buf, size_t len,
|
|
||||||
* LLC-REFILL, and REMOTE-ACCESS events are identified if
|
|
||||||
* index > 1.
|
|
||||||
*/
|
|
||||||
- packet->index = ret - 1;
|
|
||||||
+ packet->index = arm_spe_payload_len(buf[0]);
|
|
||||||
|
|
||||||
- return ret;
|
|
||||||
+ return arm_spe_get_payload(buf, len, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_data_source(const unsigned char *buf, size_t len,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,157 +0,0 @@
|
|||||||
From e7588e8a33a8f5eec2a013c1e0279a894df725cd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:01 +0800
|
|
||||||
Subject: [PATCH 05/21] perf arm-spe: Fix packet length handling
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 0a04244cabc5560ce1e08555e8712a4cd20ab6ce
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
When processing address packet and counter packet, if the packet
|
|
||||||
contains extended header, it misses to account the extra one byte for
|
|
||||||
header length calculation, thus returns the wrong packet length.
|
|
||||||
|
|
||||||
To correct the packet length calculation, one possible fixing is simply
|
|
||||||
to plus extra 1 for extended header, but will spread some duplicate code
|
|
||||||
in the flows for processing address packet and counter packet.
|
|
||||||
Alternatively, we can refine the function arm_spe_get_payload() to not
|
|
||||||
only support short header and allow it to support extended header, and
|
|
||||||
rely on it for the packet length calculation.
|
|
||||||
|
|
||||||
So this patch refactors function arm_spe_get_payload() with a new
|
|
||||||
argument 'ext_hdr' for support extended header; the packet processing
|
|
||||||
flows can invoke this function to unify the packet length calculation.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201111071149.815-6-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 34 +++++++------------
|
|
||||||
1 file changed, 12 insertions(+), 22 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 57904da89db1..671a4763fb47 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -82,14 +82,15 @@ static unsigned int arm_spe_payload_len(unsigned char hdr)
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_payload(const unsigned char *buf, size_t len,
|
|
||||||
+ unsigned char ext_hdr,
|
|
||||||
struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
- size_t payload_len = arm_spe_payload_len(buf[0]);
|
|
||||||
+ size_t payload_len = arm_spe_payload_len(buf[ext_hdr]);
|
|
||||||
|
|
||||||
- if (len < 1 + payload_len)
|
|
||||||
+ if (len < 1 + ext_hdr + payload_len)
|
|
||||||
return ARM_SPE_NEED_MORE_BYTES;
|
|
||||||
|
|
||||||
- buf++;
|
|
||||||
+ buf += 1 + ext_hdr;
|
|
||||||
|
|
||||||
switch (payload_len) {
|
|
||||||
case 1: packet->payload = *(uint8_t *)buf; break;
|
|
||||||
@@ -99,7 +100,7 @@ static int arm_spe_get_payload(const unsigned char *buf, size_t len,
|
|
||||||
default: return ARM_SPE_BAD_PACKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return 1 + payload_len;
|
|
||||||
+ return 1 + ext_hdr + payload_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_pad(struct arm_spe_pkt *packet)
|
|
||||||
@@ -130,7 +131,7 @@ static int arm_spe_get_timestamp(const unsigned char *buf, size_t len,
|
|
||||||
struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
packet->type = ARM_SPE_TIMESTAMP;
|
|
||||||
- return arm_spe_get_payload(buf, len, packet);
|
|
||||||
+ return arm_spe_get_payload(buf, len, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_events(const unsigned char *buf, size_t len,
|
|
||||||
@@ -145,14 +146,14 @@ static int arm_spe_get_events(const unsigned char *buf, size_t len,
|
|
||||||
*/
|
|
||||||
packet->index = arm_spe_payload_len(buf[0]);
|
|
||||||
|
|
||||||
- return arm_spe_get_payload(buf, len, packet);
|
|
||||||
+ return arm_spe_get_payload(buf, len, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_data_source(const unsigned char *buf, size_t len,
|
|
||||||
struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
packet->type = ARM_SPE_DATA_SOURCE;
|
|
||||||
- return arm_spe_get_payload(buf, len, packet);
|
|
||||||
+ return arm_spe_get_payload(buf, len, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_context(const unsigned char *buf, size_t len,
|
|
||||||
@@ -160,8 +161,7 @@ static int arm_spe_get_context(const unsigned char *buf, size_t len,
|
|
||||||
{
|
|
||||||
packet->type = ARM_SPE_CONTEXT;
|
|
||||||
packet->index = buf[0] & 0x3;
|
|
||||||
-
|
|
||||||
- return arm_spe_get_payload(buf, len, packet);
|
|
||||||
+ return arm_spe_get_payload(buf, len, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_op_type(const unsigned char *buf, size_t len,
|
|
||||||
@@ -169,41 +169,31 @@ static int arm_spe_get_op_type(const unsigned char *buf, size_t len,
|
|
||||||
{
|
|
||||||
packet->type = ARM_SPE_OP_TYPE;
|
|
||||||
packet->index = buf[0] & 0x3;
|
|
||||||
- return arm_spe_get_payload(buf, len, packet);
|
|
||||||
+ return arm_spe_get_payload(buf, len, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_counter(const unsigned char *buf, size_t len,
|
|
||||||
const unsigned char ext_hdr, struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
- if (len < 2)
|
|
||||||
- return ARM_SPE_NEED_MORE_BYTES;
|
|
||||||
-
|
|
||||||
packet->type = ARM_SPE_COUNTER;
|
|
||||||
if (ext_hdr)
|
|
||||||
packet->index = ((buf[0] & 0x3) << 3) | (buf[1] & 0x7);
|
|
||||||
else
|
|
||||||
packet->index = buf[0] & 0x7;
|
|
||||||
|
|
||||||
- packet->payload = le16_to_cpu(*(uint16_t *)(buf + 1));
|
|
||||||
-
|
|
||||||
- return 1 + ext_hdr + 2;
|
|
||||||
+ return arm_spe_get_payload(buf, len, ext_hdr, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_get_addr(const unsigned char *buf, size_t len,
|
|
||||||
const unsigned char ext_hdr, struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
- if (len < 8)
|
|
||||||
- return ARM_SPE_NEED_MORE_BYTES;
|
|
||||||
-
|
|
||||||
packet->type = ARM_SPE_ADDRESS;
|
|
||||||
if (ext_hdr)
|
|
||||||
packet->index = ((buf[0] & 0x3) << 3) | (buf[1] & 0x7);
|
|
||||||
else
|
|
||||||
packet->index = buf[0] & 0x7;
|
|
||||||
|
|
||||||
- memcpy_le64(&packet->payload, buf + 1, 8);
|
|
||||||
-
|
|
||||||
- return 1 + ext_hdr + 8;
|
|
||||||
+ return arm_spe_get_payload(buf, len, ext_hdr, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int arm_spe_do_get_packet(const unsigned char *buf, size_t len,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,439 +0,0 @@
|
|||||||
From bff3118d92bfd22952f81e9772e6472f8efcb6ed Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:02 +0800
|
|
||||||
Subject: [PATCH 06/21] perf arm-spe: Refactor printing string to buffer
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 75eeaddd57f4a0ac89110547221df8f3757d5a6f
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
When outputs strings to the decoding buffer with function snprintf(),
|
|
||||||
SPE decoder needs to detects if any error returns from snprintf() and if
|
|
||||||
so needs to directly bail out. If snprintf() returns success, it needs
|
|
||||||
to update buffer pointer and reduce the buffer length so can continue to
|
|
||||||
output the next string into the consequent memory space.
|
|
||||||
|
|
||||||
This complex logics are spreading in the function arm_spe_pkt_desc() so
|
|
||||||
there has many duplicate codes for handling error detecting, increment
|
|
||||||
buffer pointer and decrement buffer size.
|
|
||||||
|
|
||||||
To avoid the duplicate code, this patch introduces a new helper function
|
|
||||||
arm_spe_pkt_out_string() which is used to wrap up the complex logics,
|
|
||||||
and it's used by the caller arm_spe_pkt_desc(). This patch moves the
|
|
||||||
variable 'blen' as the function's local variable so allows to remove
|
|
||||||
the unnecessary braces and improve the readability.
|
|
||||||
|
|
||||||
This patch simplifies the return value for arm_spe_pkt_desc(): '0' means
|
|
||||||
success and other values mean an error has occurred. To realize this,
|
|
||||||
it relies on arm_spe_pkt_out_string()'s parameter 'err', the 'err' is a
|
|
||||||
cumulative value, returns its final value if printing buffer is called
|
|
||||||
for one time or multiple times. Finally, the error is handled in a
|
|
||||||
central place, rather than directly bailing out in switch-cases, it
|
|
||||||
returns error at the end of arm_spe_pkt_desc().
|
|
||||||
|
|
||||||
This patch changes the caller arm_spe_dump() to respect the updated
|
|
||||||
return value semantics of arm_spe_pkt_desc().
|
|
||||||
|
|
||||||
Suggested-by: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-2-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 302 +++++++++---------
|
|
||||||
tools/perf/util/arm-spe.c | 2 +-
|
|
||||||
2 files changed, 151 insertions(+), 153 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 671a4763fb47..fbededc1bcd4 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -9,6 +9,7 @@
|
|
||||||
#include <endian.h>
|
|
||||||
#include <byteswap.h>
|
|
||||||
#include <linux/bitops.h>
|
|
||||||
+#include <stdarg.h>
|
|
||||||
|
|
||||||
#include "arm-spe-pkt-decoder.h"
|
|
||||||
|
|
||||||
@@ -258,192 +259,189 @@ int arm_spe_get_packet(const unsigned char *buf, size_t len,
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
|
|
||||||
+ const char *fmt, ...)
|
|
||||||
+{
|
|
||||||
+ va_list ap;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ /* Bail out if any error occurred */
|
|
||||||
+ if (err && *err)
|
|
||||||
+ return *err;
|
|
||||||
+
|
|
||||||
+ va_start(ap, fmt);
|
|
||||||
+ ret = vsnprintf(*buf_p, *blen, fmt, ap);
|
|
||||||
+ va_end(ap);
|
|
||||||
+
|
|
||||||
+ if (ret < 0) {
|
|
||||||
+ if (err && !*err)
|
|
||||||
+ *err = ret;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * A return value of *blen or more means that the output was
|
|
||||||
+ * truncated and the buffer is overrun.
|
|
||||||
+ */
|
|
||||||
+ } else if ((size_t)ret >= *blen) {
|
|
||||||
+ (*buf_p)[*blen - 1] = '\0';
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Set *err to 'ret' to avoid overflow if tries to
|
|
||||||
+ * fill this buffer sequentially.
|
|
||||||
+ */
|
|
||||||
+ if (err && !*err)
|
|
||||||
+ *err = ret;
|
|
||||||
+ } else {
|
|
||||||
+ *buf_p += ret;
|
|
||||||
+ *blen -= ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
|
|
||||||
size_t buf_len)
|
|
||||||
{
|
|
||||||
- int ret, ns, el, idx = packet->index;
|
|
||||||
+ int ns, el, idx = packet->index;
|
|
||||||
unsigned long long payload = packet->payload;
|
|
||||||
const char *name = arm_spe_pkt_name(packet->type);
|
|
||||||
+ char *buf_orig = buf;
|
|
||||||
+ size_t blen = buf_len;
|
|
||||||
+ int err = 0;
|
|
||||||
|
|
||||||
switch (packet->type) {
|
|
||||||
case ARM_SPE_BAD:
|
|
||||||
case ARM_SPE_PAD:
|
|
||||||
case ARM_SPE_END:
|
|
||||||
- return snprintf(buf, buf_len, "%s", name);
|
|
||||||
- case ARM_SPE_EVENTS: {
|
|
||||||
- size_t blen = buf_len;
|
|
||||||
-
|
|
||||||
- ret = 0;
|
|
||||||
- ret = snprintf(buf, buf_len, "EV");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- if (payload & 0x1) {
|
|
||||||
- ret = snprintf(buf, buf_len, " EXCEPTION-GEN");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x2) {
|
|
||||||
- ret = snprintf(buf, buf_len, " RETIRED");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x4) {
|
|
||||||
- ret = snprintf(buf, buf_len, " L1D-ACCESS");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x8) {
|
|
||||||
- ret = snprintf(buf, buf_len, " L1D-REFILL");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x10) {
|
|
||||||
- ret = snprintf(buf, buf_len, " TLB-ACCESS");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x20) {
|
|
||||||
- ret = snprintf(buf, buf_len, " TLB-REFILL");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x40) {
|
|
||||||
- ret = snprintf(buf, buf_len, " NOT-TAKEN");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x80) {
|
|
||||||
- ret = snprintf(buf, buf_len, " MISPRED");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, "%s", name);
|
|
||||||
+ break;
|
|
||||||
+ case ARM_SPE_EVENTS:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, "EV");
|
|
||||||
+
|
|
||||||
+ if (payload & 0x1)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " EXCEPTION-GEN");
|
|
||||||
+ if (payload & 0x2)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " RETIRED");
|
|
||||||
+ if (payload & 0x4)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " L1D-ACCESS");
|
|
||||||
+ if (payload & 0x8)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " L1D-REFILL");
|
|
||||||
+ if (payload & 0x10)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " TLB-ACCESS");
|
|
||||||
+ if (payload & 0x20)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " TLB-REFILL");
|
|
||||||
+ if (payload & 0x40)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " NOT-TAKEN");
|
|
||||||
+ if (payload & 0x80)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " MISPRED");
|
|
||||||
if (idx > 1) {
|
|
||||||
- if (payload & 0x100) {
|
|
||||||
- ret = snprintf(buf, buf_len, " LLC-ACCESS");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x200) {
|
|
||||||
- ret = snprintf(buf, buf_len, " LLC-REFILL");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x400) {
|
|
||||||
- ret = snprintf(buf, buf_len, " REMOTE-ACCESS");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
+ if (payload & 0x100)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " LLC-ACCESS");
|
|
||||||
+ if (payload & 0x200)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " LLC-REFILL");
|
|
||||||
+ if (payload & 0x400)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " REMOTE-ACCESS");
|
|
||||||
}
|
|
||||||
- if (ret < 0)
|
|
||||||
- return ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- return buf_len - blen;
|
|
||||||
- }
|
|
||||||
+ break;
|
|
||||||
case ARM_SPE_OP_TYPE:
|
|
||||||
switch (idx) {
|
|
||||||
- case 0: return snprintf(buf, buf_len, "%s", payload & 0x1 ?
|
|
||||||
- "COND-SELECT" : "INSN-OTHER");
|
|
||||||
- case 1: {
|
|
||||||
- size_t blen = buf_len;
|
|
||||||
+ case 0:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
+ payload & 0x1 ? "COND-SELECT" : "INSN-OTHER");
|
|
||||||
+ break;
|
|
||||||
+ case 1:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
+ payload & 0x1 ? "ST" : "LD");
|
|
||||||
|
|
||||||
- if (payload & 0x1)
|
|
||||||
- ret = snprintf(buf, buf_len, "ST");
|
|
||||||
- else
|
|
||||||
- ret = snprintf(buf, buf_len, "LD");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
if (payload & 0x2) {
|
|
||||||
- if (payload & 0x4) {
|
|
||||||
- ret = snprintf(buf, buf_len, " AT");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x8) {
|
|
||||||
- ret = snprintf(buf, buf_len, " EXCL");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x10) {
|
|
||||||
- ret = snprintf(buf, buf_len, " AR");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
+ if (payload & 0x4)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " AT");
|
|
||||||
+ if (payload & 0x8)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " EXCL");
|
|
||||||
+ if (payload & 0x10)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " AR");
|
|
||||||
} else if (payload & 0x4) {
|
|
||||||
- ret = snprintf(buf, buf_len, " SIMD-FP");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (ret < 0)
|
|
||||||
- return ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- return buf_len - blen;
|
|
||||||
- }
|
|
||||||
- case 2: {
|
|
||||||
- size_t blen = buf_len;
|
|
||||||
-
|
|
||||||
- ret = snprintf(buf, buf_len, "B");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- if (payload & 0x1) {
|
|
||||||
- ret = snprintf(buf, buf_len, " COND");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (payload & 0x2) {
|
|
||||||
- ret = snprintf(buf, buf_len, " IND");
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- }
|
|
||||||
- if (ret < 0)
|
|
||||||
- return ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- return buf_len - blen;
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " SIMD-FP");
|
|
||||||
}
|
|
||||||
- default: return 0;
|
|
||||||
+ break;
|
|
||||||
+ case 2:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, "B");
|
|
||||||
+
|
|
||||||
+ if (payload & 0x1)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " COND");
|
|
||||||
+ if (payload & 0x2)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, " IND");
|
|
||||||
+
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ /* Unknown index */
|
|
||||||
+ err = -1;
|
|
||||||
+ break;
|
|
||||||
}
|
|
||||||
+ break;
|
|
||||||
case ARM_SPE_DATA_SOURCE:
|
|
||||||
case ARM_SPE_TIMESTAMP:
|
|
||||||
- return snprintf(buf, buf_len, "%s %lld", name, payload);
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, "%s %lld", name, payload);
|
|
||||||
+ break;
|
|
||||||
case ARM_SPE_ADDRESS:
|
|
||||||
switch (idx) {
|
|
||||||
case 0:
|
|
||||||
- case 1: ns = !!(packet->payload & NS_FLAG);
|
|
||||||
+ case 1:
|
|
||||||
+ ns = !!(packet->payload & NS_FLAG);
|
|
||||||
el = (packet->payload & EL_FLAG) >> 61;
|
|
||||||
payload &= ~(0xffULL << 56);
|
|
||||||
- return snprintf(buf, buf_len, "%s 0x%llx el%d ns=%d",
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
+ "%s 0x%llx el%d ns=%d",
|
|
||||||
(idx == 1) ? "TGT" : "PC", payload, el, ns);
|
|
||||||
- case 2: return snprintf(buf, buf_len, "VA 0x%llx", payload);
|
|
||||||
- case 3: ns = !!(packet->payload & NS_FLAG);
|
|
||||||
+ break;
|
|
||||||
+ case 2:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
+ "VA 0x%llx", payload);
|
|
||||||
+ break;
|
|
||||||
+ case 3:
|
|
||||||
+ ns = !!(packet->payload & NS_FLAG);
|
|
||||||
payload &= ~(0xffULL << 56);
|
|
||||||
- return snprintf(buf, buf_len, "PA 0x%llx ns=%d",
|
|
||||||
- payload, ns);
|
|
||||||
- default: return 0;
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
+ "PA 0x%llx ns=%d", payload, ns);
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ /* Unknown index */
|
|
||||||
+ err = -1;
|
|
||||||
+ break;
|
|
||||||
}
|
|
||||||
+ break;
|
|
||||||
case ARM_SPE_CONTEXT:
|
|
||||||
- return snprintf(buf, buf_len, "%s 0x%lx el%d", name,
|
|
||||||
- (unsigned long)payload, idx + 1);
|
|
||||||
- case ARM_SPE_COUNTER: {
|
|
||||||
- size_t blen = buf_len;
|
|
||||||
-
|
|
||||||
- ret = snprintf(buf, buf_len, "%s %d ", name,
|
|
||||||
- (unsigned short)payload);
|
|
||||||
- buf += ret;
|
|
||||||
- blen -= ret;
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, "%s 0x%lx el%d",
|
|
||||||
+ name, (unsigned long)payload, idx + 1);
|
|
||||||
+ break;
|
|
||||||
+ case ARM_SPE_COUNTER:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, "%s %d ", name,
|
|
||||||
+ (unsigned short)payload);
|
|
||||||
switch (idx) {
|
|
||||||
- case 0: ret = snprintf(buf, buf_len, "TOT"); break;
|
|
||||||
- case 1: ret = snprintf(buf, buf_len, "ISSUE"); break;
|
|
||||||
- case 2: ret = snprintf(buf, buf_len, "XLAT"); break;
|
|
||||||
- default: ret = 0;
|
|
||||||
+ case 0:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, "TOT");
|
|
||||||
+ break;
|
|
||||||
+ case 1:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, "ISSUE");
|
|
||||||
+ break;
|
|
||||||
+ case 2:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &blen, "XLAT");
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ break;
|
|
||||||
}
|
|
||||||
- if (ret < 0)
|
|
||||||
- return ret;
|
|
||||||
- blen -= ret;
|
|
||||||
- return buf_len - blen;
|
|
||||||
- }
|
|
||||||
+ break;
|
|
||||||
default:
|
|
||||||
+ /* Unknown packet type */
|
|
||||||
+ err = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
- return snprintf(buf, buf_len, "%s 0x%llx (%d)",
|
|
||||||
- name, payload, packet->index);
|
|
||||||
+ /* Output raw data if detect any error */
|
|
||||||
+ if (err) {
|
|
||||||
+ err = 0;
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf_orig, &buf_len, "%s 0x%llx (%d)",
|
|
||||||
+ name, payload, packet->index);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return err;
|
|
||||||
}
|
|
||||||
diff --git a/tools/perf/util/arm-spe.c b/tools/perf/util/arm-spe.c
|
|
||||||
index 1f97e432d125..81b3a12ed176 100644
|
|
||||||
--- a/tools/perf/util/arm-spe.c
|
|
||||||
+++ b/tools/perf/util/arm-spe.c
|
|
||||||
@@ -161,7 +161,7 @@ static void arm_spe_dump(struct arm_spe *spe __maybe_unused,
|
|
||||||
if (ret > 0) {
|
|
||||||
ret = arm_spe_pkt_desc(&packet, desc,
|
|
||||||
ARM_SPE_PKT_DESC_MAX);
|
|
||||||
- if (ret > 0)
|
|
||||||
+ if (!ret)
|
|
||||||
color_fprintf(stdout, color, " %s\n", desc);
|
|
||||||
} else {
|
|
||||||
color_fprintf(stdout, color, " Bad packet!\n");
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,210 +0,0 @@
|
|||||||
From 38d291dbe53affcb0828c5a851cbb80e68d0ba9a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:03 +0800
|
|
||||||
Subject: [PATCH 07/21] perf arm-spe: Refactor packet header parsing
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 11695142e25e957dc3e56c29dc5f9daaf9530b10
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
The packet header parsing uses the hard coded values and it uses nested
|
|
||||||
if-else statements.
|
|
||||||
|
|
||||||
To improve the readability, this patch refactors the macros for packet
|
|
||||||
header format so it removes the hard coded values. Furthermore, based
|
|
||||||
on the new mask macros it reduces the nested if-else statements and
|
|
||||||
changes to use the flat conditions checking, this is directive and can
|
|
||||||
easily map to the descriptions in ARMv8-a architecture reference manual
|
|
||||||
(ARM DDI 0487E.a), chapter 'D10.1.5 Statistical Profiling Extension
|
|
||||||
protocol packet headers'.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-3-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 92 +++++++++----------
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.h | 20 ++++
|
|
||||||
2 files changed, 61 insertions(+), 51 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index fbededc1bcd4..a769fe5a4496 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -16,28 +16,6 @@
|
|
||||||
#define NS_FLAG BIT_ULL(63)
|
|
||||||
#define EL_FLAG (BIT_ULL(62) | BIT_ULL(61))
|
|
||||||
|
|
||||||
-#define SPE_HEADER0_PAD 0x0
|
|
||||||
-#define SPE_HEADER0_END 0x1
|
|
||||||
-#define SPE_HEADER0_ADDRESS 0x30 /* address packet (short) */
|
|
||||||
-#define SPE_HEADER0_ADDRESS_MASK 0x38
|
|
||||||
-#define SPE_HEADER0_COUNTER 0x18 /* counter packet (short) */
|
|
||||||
-#define SPE_HEADER0_COUNTER_MASK 0x38
|
|
||||||
-#define SPE_HEADER0_TIMESTAMP 0x71
|
|
||||||
-#define SPE_HEADER0_TIMESTAMP 0x71
|
|
||||||
-#define SPE_HEADER0_EVENTS 0x2
|
|
||||||
-#define SPE_HEADER0_EVENTS_MASK 0xf
|
|
||||||
-#define SPE_HEADER0_SOURCE 0x3
|
|
||||||
-#define SPE_HEADER0_SOURCE_MASK 0xf
|
|
||||||
-#define SPE_HEADER0_CONTEXT 0x24
|
|
||||||
-#define SPE_HEADER0_CONTEXT_MASK 0x3c
|
|
||||||
-#define SPE_HEADER0_OP_TYPE 0x8
|
|
||||||
-#define SPE_HEADER0_OP_TYPE_MASK 0x3c
|
|
||||||
-#define SPE_HEADER1_ALIGNMENT 0x0
|
|
||||||
-#define SPE_HEADER1_ADDRESS 0xb0 /* address packet (extended) */
|
|
||||||
-#define SPE_HEADER1_ADDRESS_MASK 0xf8
|
|
||||||
-#define SPE_HEADER1_COUNTER 0x98 /* counter packet (extended) */
|
|
||||||
-#define SPE_HEADER1_COUNTER_MASK 0xf8
|
|
||||||
-
|
|
||||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
|
||||||
#define le16_to_cpu bswap_16
|
|
||||||
#define le32_to_cpu bswap_32
|
|
||||||
@@ -200,46 +178,58 @@ static int arm_spe_get_addr(const unsigned char *buf, size_t len,
|
|
||||||
static int arm_spe_do_get_packet(const unsigned char *buf, size_t len,
|
|
||||||
struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
- unsigned int byte;
|
|
||||||
+ unsigned int hdr;
|
|
||||||
+ unsigned char ext_hdr = 0;
|
|
||||||
|
|
||||||
memset(packet, 0, sizeof(struct arm_spe_pkt));
|
|
||||||
|
|
||||||
if (!len)
|
|
||||||
return ARM_SPE_NEED_MORE_BYTES;
|
|
||||||
|
|
||||||
- byte = buf[0];
|
|
||||||
- if (byte == SPE_HEADER0_PAD)
|
|
||||||
+ hdr = buf[0];
|
|
||||||
+
|
|
||||||
+ if (hdr == SPE_HEADER0_PAD)
|
|
||||||
return arm_spe_get_pad(packet);
|
|
||||||
- else if (byte == SPE_HEADER0_END) /* no timestamp at end of record */
|
|
||||||
+
|
|
||||||
+ if (hdr == SPE_HEADER0_END) /* no timestamp at end of record */
|
|
||||||
return arm_spe_get_end(packet);
|
|
||||||
- else if (byte & 0xc0 /* 0y11xxxxxx */) {
|
|
||||||
- if (byte & 0x80) {
|
|
||||||
- if ((byte & SPE_HEADER0_ADDRESS_MASK) == SPE_HEADER0_ADDRESS)
|
|
||||||
- return arm_spe_get_addr(buf, len, 0, packet);
|
|
||||||
- if ((byte & SPE_HEADER0_COUNTER_MASK) == SPE_HEADER0_COUNTER)
|
|
||||||
- return arm_spe_get_counter(buf, len, 0, packet);
|
|
||||||
- } else
|
|
||||||
- if (byte == SPE_HEADER0_TIMESTAMP)
|
|
||||||
- return arm_spe_get_timestamp(buf, len, packet);
|
|
||||||
- else if ((byte & SPE_HEADER0_EVENTS_MASK) == SPE_HEADER0_EVENTS)
|
|
||||||
- return arm_spe_get_events(buf, len, packet);
|
|
||||||
- else if ((byte & SPE_HEADER0_SOURCE_MASK) == SPE_HEADER0_SOURCE)
|
|
||||||
- return arm_spe_get_data_source(buf, len, packet);
|
|
||||||
- else if ((byte & SPE_HEADER0_CONTEXT_MASK) == SPE_HEADER0_CONTEXT)
|
|
||||||
- return arm_spe_get_context(buf, len, packet);
|
|
||||||
- else if ((byte & SPE_HEADER0_OP_TYPE_MASK) == SPE_HEADER0_OP_TYPE)
|
|
||||||
- return arm_spe_get_op_type(buf, len, packet);
|
|
||||||
- } else if ((byte & 0xe0) == 0x20 /* 0y001xxxxx */) {
|
|
||||||
- /* 16-bit header */
|
|
||||||
- byte = buf[1];
|
|
||||||
- if (byte == SPE_HEADER1_ALIGNMENT)
|
|
||||||
+
|
|
||||||
+ if (hdr == SPE_HEADER0_TIMESTAMP)
|
|
||||||
+ return arm_spe_get_timestamp(buf, len, packet);
|
|
||||||
+
|
|
||||||
+ if ((hdr & SPE_HEADER0_MASK1) == SPE_HEADER0_EVENTS)
|
|
||||||
+ return arm_spe_get_events(buf, len, packet);
|
|
||||||
+
|
|
||||||
+ if ((hdr & SPE_HEADER0_MASK1) == SPE_HEADER0_SOURCE)
|
|
||||||
+ return arm_spe_get_data_source(buf, len, packet);
|
|
||||||
+
|
|
||||||
+ if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_CONTEXT)
|
|
||||||
+ return arm_spe_get_context(buf, len, packet);
|
|
||||||
+
|
|
||||||
+ if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_OP_TYPE)
|
|
||||||
+ return arm_spe_get_op_type(buf, len, packet);
|
|
||||||
+
|
|
||||||
+ if ((hdr & SPE_HEADER0_MASK2) == SPE_HEADER0_EXTENDED) {
|
|
||||||
+ /* 16-bit extended format header */
|
|
||||||
+ ext_hdr = 1;
|
|
||||||
+
|
|
||||||
+ hdr = buf[1];
|
|
||||||
+ if (hdr == SPE_HEADER1_ALIGNMENT)
|
|
||||||
return arm_spe_get_alignment(buf, len, packet);
|
|
||||||
- else if ((byte & SPE_HEADER1_ADDRESS_MASK) == SPE_HEADER1_ADDRESS)
|
|
||||||
- return arm_spe_get_addr(buf, len, 1, packet);
|
|
||||||
- else if ((byte & SPE_HEADER1_COUNTER_MASK) == SPE_HEADER1_COUNTER)
|
|
||||||
- return arm_spe_get_counter(buf, len, 1, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * The short format header's byte 0 or the extended format header's
|
|
||||||
+ * byte 1 has been assigned to 'hdr', which uses the same encoding for
|
|
||||||
+ * address packet and counter packet, so don't need to distinguish if
|
|
||||||
+ * it's short format or extended format and handle in once.
|
|
||||||
+ */
|
|
||||||
+ if ((hdr & SPE_HEADER0_MASK3) == SPE_HEADER0_ADDRESS)
|
|
||||||
+ return arm_spe_get_addr(buf, len, ext_hdr, packet);
|
|
||||||
+
|
|
||||||
+ if ((hdr & SPE_HEADER0_MASK3) == SPE_HEADER0_COUNTER)
|
|
||||||
+ return arm_spe_get_counter(buf, len, ext_hdr, packet);
|
|
||||||
+
|
|
||||||
return ARM_SPE_BAD_PACKET;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
index 865d1e35b401..66b99a1e3919 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
@@ -36,6 +36,26 @@ struct arm_spe_pkt {
|
|
||||||
uint64_t payload;
|
|
||||||
};
|
|
||||||
|
|
||||||
+/* Short header (HEADER0) and extended header (HEADER1) */
|
|
||||||
+#define SPE_HEADER0_PAD 0x0
|
|
||||||
+#define SPE_HEADER0_END 0x1
|
|
||||||
+#define SPE_HEADER0_TIMESTAMP 0x71
|
|
||||||
+/* Mask for event & data source */
|
|
||||||
+#define SPE_HEADER0_MASK1 (GENMASK_ULL(7, 6) | GENMASK_ULL(3, 0))
|
|
||||||
+#define SPE_HEADER0_EVENTS 0x42
|
|
||||||
+#define SPE_HEADER0_SOURCE 0x43
|
|
||||||
+/* Mask for context & operation */
|
|
||||||
+#define SPE_HEADER0_MASK2 GENMASK_ULL(7, 2)
|
|
||||||
+#define SPE_HEADER0_CONTEXT 0x64
|
|
||||||
+#define SPE_HEADER0_OP_TYPE 0x48
|
|
||||||
+/* Mask for extended format */
|
|
||||||
+#define SPE_HEADER0_EXTENDED 0x20
|
|
||||||
+/* Mask for address & counter */
|
|
||||||
+#define SPE_HEADER0_MASK3 GENMASK_ULL(7, 3)
|
|
||||||
+#define SPE_HEADER0_ADDRESS 0xb0
|
|
||||||
+#define SPE_HEADER0_COUNTER 0x98
|
|
||||||
+#define SPE_HEADER1_ALIGNMENT 0x0
|
|
||||||
+
|
|
||||||
const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
|
|
||||||
|
|
||||||
int arm_spe_get_packet(const unsigned char *buf, size_t len,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,132 +0,0 @@
|
|||||||
From b73a4bf5e10be8bab893952e6c7d23f9dfd077cc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:04 +0800
|
|
||||||
Subject: [PATCH 08/21] perf arm-spe: Add new function arm_spe_pkt_desc_addr()
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit ab2aa439e4aaa3ce0fdcfa0f847aed4bf13bf353
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
This patch moves out the address parsing code from arm_spe_pkt_desc()
|
|
||||||
and uses the new introduced function arm_spe_pkt_desc_addr() to process
|
|
||||||
address packet.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-4-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 64 +++++++++++--------
|
|
||||||
1 file changed, 38 insertions(+), 26 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index a769fe5a4496..b16d68b40bbd 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -288,10 +288,46 @@ static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
|
|
||||||
+ char *buf, size_t buf_len)
|
|
||||||
+{
|
|
||||||
+ int ns, el, idx = packet->index;
|
|
||||||
+ u64 payload = packet->payload;
|
|
||||||
+ int err = 0;
|
|
||||||
+
|
|
||||||
+ switch (idx) {
|
|
||||||
+ case 0:
|
|
||||||
+ case 1:
|
|
||||||
+ ns = !!(packet->payload & NS_FLAG);
|
|
||||||
+ el = (packet->payload & EL_FLAG) >> 61;
|
|
||||||
+ payload &= ~(0xffULL << 56);
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
+ "%s 0x%llx el%d ns=%d",
|
|
||||||
+ (idx == 1) ? "TGT" : "PC", payload, el, ns);
|
|
||||||
+ break;
|
|
||||||
+ case 2:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
+ "VA 0x%llx", payload);
|
|
||||||
+ break;
|
|
||||||
+ case 3:
|
|
||||||
+ ns = !!(packet->payload & NS_FLAG);
|
|
||||||
+ payload &= ~(0xffULL << 56);
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
+ "PA 0x%llx ns=%d", payload, ns);
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ /* Unknown index */
|
|
||||||
+ err = -1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return err;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
|
|
||||||
size_t buf_len)
|
|
||||||
{
|
|
||||||
- int ns, el, idx = packet->index;
|
|
||||||
+ int idx = packet->index;
|
|
||||||
unsigned long long payload = packet->payload;
|
|
||||||
const char *name = arm_spe_pkt_name(packet->type);
|
|
||||||
char *buf_orig = buf;
|
|
||||||
@@ -373,31 +409,7 @@ int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &blen, "%s %lld", name, payload);
|
|
||||||
break;
|
|
||||||
case ARM_SPE_ADDRESS:
|
|
||||||
- switch (idx) {
|
|
||||||
- case 0:
|
|
||||||
- case 1:
|
|
||||||
- ns = !!(packet->payload & NS_FLAG);
|
|
||||||
- el = (packet->payload & EL_FLAG) >> 61;
|
|
||||||
- payload &= ~(0xffULL << 56);
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
- "%s 0x%llx el%d ns=%d",
|
|
||||||
- (idx == 1) ? "TGT" : "PC", payload, el, ns);
|
|
||||||
- break;
|
|
||||||
- case 2:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
- "VA 0x%llx", payload);
|
|
||||||
- break;
|
|
||||||
- case 3:
|
|
||||||
- ns = !!(packet->payload & NS_FLAG);
|
|
||||||
- payload &= ~(0xffULL << 56);
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
- "PA 0x%llx ns=%d", payload, ns);
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- /* Unknown index */
|
|
||||||
- err = -1;
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
+ err = arm_spe_pkt_desc_addr(packet, buf, buf_len);
|
|
||||||
break;
|
|
||||||
case ARM_SPE_CONTEXT:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &blen, "%s 0x%lx el%d",
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
From c97102a71dc15b73456f00c97e4848a8a72b758a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:05 +0800
|
|
||||||
Subject: [PATCH 09/21] perf arm-spe: Refactor address packet handling
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 09935ca7b64cfa379b6ebf2b8cdb3126e09bffab
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
This patch is to refactor address packet handling, it defines macros for
|
|
||||||
address packet's header and payload, these macros are used by decoder
|
|
||||||
and the dump flow.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-5-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 26 +++++++++----------
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.h | 23 ++++++++++++++++
|
|
||||||
2 files changed, 35 insertions(+), 14 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index b16d68b40bbd..d37c4008adbc 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -13,9 +13,6 @@
|
|
||||||
|
|
||||||
#include "arm-spe-pkt-decoder.h"
|
|
||||||
|
|
||||||
-#define NS_FLAG BIT_ULL(63)
|
|
||||||
-#define EL_FLAG (BIT_ULL(62) | BIT_ULL(61))
|
|
||||||
-
|
|
||||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
|
||||||
#define le16_to_cpu bswap_16
|
|
||||||
#define le32_to_cpu bswap_32
|
|
||||||
@@ -167,10 +164,11 @@ static int arm_spe_get_addr(const unsigned char *buf, size_t len,
|
|
||||||
const unsigned char ext_hdr, struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
packet->type = ARM_SPE_ADDRESS;
|
|
||||||
+
|
|
||||||
if (ext_hdr)
|
|
||||||
- packet->index = ((buf[0] & 0x3) << 3) | (buf[1] & 0x7);
|
|
||||||
+ packet->index = SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]);
|
|
||||||
else
|
|
||||||
- packet->index = buf[0] & 0x7;
|
|
||||||
+ packet->index = SPE_HDR_SHORT_INDEX(buf[0]);
|
|
||||||
|
|
||||||
return arm_spe_get_payload(buf, len, ext_hdr, packet);
|
|
||||||
}
|
|
||||||
@@ -296,22 +294,22 @@ static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
switch (idx) {
|
|
||||||
- case 0:
|
|
||||||
- case 1:
|
|
||||||
- ns = !!(packet->payload & NS_FLAG);
|
|
||||||
- el = (packet->payload & EL_FLAG) >> 61;
|
|
||||||
- payload &= ~(0xffULL << 56);
|
|
||||||
+ case SPE_ADDR_PKT_HDR_INDEX_INS:
|
|
||||||
+ case SPE_ADDR_PKT_HDR_INDEX_BRANCH:
|
|
||||||
+ ns = !!SPE_ADDR_PKT_GET_NS(payload);
|
|
||||||
+ el = SPE_ADDR_PKT_GET_EL(payload);
|
|
||||||
+ payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
"%s 0x%llx el%d ns=%d",
|
|
||||||
(idx == 1) ? "TGT" : "PC", payload, el, ns);
|
|
||||||
break;
|
|
||||||
- case 2:
|
|
||||||
+ case SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
"VA 0x%llx", payload);
|
|
||||||
break;
|
|
||||||
- case 3:
|
|
||||||
- ns = !!(packet->payload & NS_FLAG);
|
|
||||||
- payload &= ~(0xffULL << 56);
|
|
||||||
+ case SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS:
|
|
||||||
+ ns = !!SPE_ADDR_PKT_GET_NS(payload);
|
|
||||||
+ payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
"PA 0x%llx ns=%d", payload, ns);
|
|
||||||
break;
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
index 66b99a1e3919..f97d6840be3a 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
@@ -56,6 +56,29 @@ struct arm_spe_pkt {
|
|
||||||
#define SPE_HEADER0_COUNTER 0x98
|
|
||||||
#define SPE_HEADER1_ALIGNMENT 0x0
|
|
||||||
|
|
||||||
+#define SPE_HDR_SHORT_INDEX(h) ((h) & GENMASK_ULL(2, 0))
|
|
||||||
+#define SPE_HDR_EXTENDED_INDEX(h0, h1) (((h0) & GENMASK_ULL(1, 0)) << 3 | \
|
|
||||||
+ SPE_HDR_SHORT_INDEX(h1))
|
|
||||||
+
|
|
||||||
+/* Address packet header */
|
|
||||||
+#define SPE_ADDR_PKT_HDR_INDEX_INS 0x0
|
|
||||||
+#define SPE_ADDR_PKT_HDR_INDEX_BRANCH 0x1
|
|
||||||
+#define SPE_ADDR_PKT_HDR_INDEX_DATA_VIRT 0x2
|
|
||||||
+#define SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS 0x3
|
|
||||||
+
|
|
||||||
+/* Address packet payload */
|
|
||||||
+#define SPE_ADDR_PKT_ADDR_BYTE7_SHIFT 56
|
|
||||||
+#define SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(v) ((v) & GENMASK_ULL(55, 0))
|
|
||||||
+#define SPE_ADDR_PKT_ADDR_GET_BYTE_6(v) (((v) & GENMASK_ULL(55, 48)) >> 48)
|
|
||||||
+
|
|
||||||
+#define SPE_ADDR_PKT_GET_NS(v) (((v) & BIT_ULL(63)) >> 63)
|
|
||||||
+#define SPE_ADDR_PKT_GET_EL(v) (((v) & GENMASK_ULL(62, 61)) >> 61)
|
|
||||||
+
|
|
||||||
+#define SPE_ADDR_PKT_EL0 0
|
|
||||||
+#define SPE_ADDR_PKT_EL1 1
|
|
||||||
+#define SPE_ADDR_PKT_EL2 2
|
|
||||||
+#define SPE_ADDR_PKT_EL3 3
|
|
||||||
+
|
|
||||||
const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
|
|
||||||
|
|
||||||
int arm_spe_get_packet(const unsigned char *buf, size_t len,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
From 804f63157ab444ba941a7f6960d954d48d4b29ea Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:07 +0800
|
|
||||||
Subject: [PATCH 10/21] perf arm-spe: Refactor context packet handling
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 6550149e801a32b1533ed86509af76319cb75eba
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
Minor refactoring to use macro for index mask.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-7-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 2 +-
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h | 3 +++
|
|
||||||
2 files changed, 4 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index d37c4008adbc..978f5551b82c 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -136,7 +136,7 @@ static int arm_spe_get_context(const unsigned char *buf, size_t len,
|
|
||||||
struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
packet->type = ARM_SPE_CONTEXT;
|
|
||||||
- packet->index = buf[0] & 0x3;
|
|
||||||
+ packet->index = SPE_CTX_PKT_HDR_INDEX(buf[0]);
|
|
||||||
return arm_spe_get_payload(buf, len, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
index f97d6840be3a..9bc876bffd35 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
@@ -79,6 +79,9 @@ struct arm_spe_pkt {
|
|
||||||
#define SPE_ADDR_PKT_EL2 2
|
|
||||||
#define SPE_ADDR_PKT_EL3 3
|
|
||||||
|
|
||||||
+/* Context packet header */
|
|
||||||
+#define SPE_CTX_PKT_HDR_INDEX(h) ((h) & GENMASK_ULL(1, 0))
|
|
||||||
+
|
|
||||||
const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
|
|
||||||
|
|
||||||
int arm_spe_get_packet(const unsigned char *buf, size_t len,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
From 3486742b3d287c5650ccec76aeb7fc7e1eaa69f5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:08 +0800
|
|
||||||
Subject: [PATCH 11/21] perf arm-spe: Add new function
|
|
||||||
arm_spe_pkt_desc_counter()
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit c52cfe9872132407eef6d734014d6fd7790146f5
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
This patch moves out the counter packet parsing code from
|
|
||||||
arm_spe_pkt_desc() to the new function arm_spe_pkt_desc_counter().
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-8-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 43 ++++++++++++-------
|
|
||||||
1 file changed, 28 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 978f5551b82c..397ade5ffdeb 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -322,6 +322,33 @@ static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int arm_spe_pkt_desc_counter(const struct arm_spe_pkt *packet,
|
|
||||||
+ char *buf, size_t buf_len)
|
|
||||||
+{
|
|
||||||
+ u64 payload = packet->payload;
|
|
||||||
+ const char *name = arm_spe_pkt_name(packet->type);
|
|
||||||
+ int err = 0;
|
|
||||||
+
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, "%s %d ", name,
|
|
||||||
+ (unsigned short)payload);
|
|
||||||
+
|
|
||||||
+ switch (packet->index) {
|
|
||||||
+ case 0:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, "TOT");
|
|
||||||
+ break;
|
|
||||||
+ case 1:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, "ISSUE");
|
|
||||||
+ break;
|
|
||||||
+ case 2:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, "XLAT");
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return err;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
|
|
||||||
size_t buf_len)
|
|
||||||
{
|
|
||||||
@@ -414,21 +441,7 @@ int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
|
|
||||||
name, (unsigned long)payload, idx + 1);
|
|
||||||
break;
|
|
||||||
case ARM_SPE_COUNTER:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, "%s %d ", name,
|
|
||||||
- (unsigned short)payload);
|
|
||||||
- switch (idx) {
|
|
||||||
- case 0:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, "TOT");
|
|
||||||
- break;
|
|
||||||
- case 1:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, "ISSUE");
|
|
||||||
- break;
|
|
||||||
- case 2:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, "XLAT");
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
+ err = arm_spe_pkt_desc_counter(packet, buf, buf_len);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Unknown packet type */
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,102 +0,0 @@
|
|||||||
From 07cc8f3f50f3a4f74abc1f1e9948a85a596f9539 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:09 +0800
|
|
||||||
Subject: [PATCH 12/21] perf arm-spe: Refactor counter packet handling
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit d158aa408f221756f99edb128ef35bfd4d3361d5
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
This patch defines macros for counter packet header, and uses macros to
|
|
||||||
replace hard code values in functions arm_spe_get_counter() and
|
|
||||||
arm_spe_pkt_desc().
|
|
||||||
|
|
||||||
In the function arm_spe_get_counter(), adds a new line for more
|
|
||||||
readable.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-9-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 11 ++++++-----
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h | 5 +++++
|
|
||||||
2 files changed, 11 insertions(+), 5 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 397ade5ffdeb..52f4339b1f0c 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -152,10 +152,11 @@ static int arm_spe_get_counter(const unsigned char *buf, size_t len,
|
|
||||||
const unsigned char ext_hdr, struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
packet->type = ARM_SPE_COUNTER;
|
|
||||||
+
|
|
||||||
if (ext_hdr)
|
|
||||||
- packet->index = ((buf[0] & 0x3) << 3) | (buf[1] & 0x7);
|
|
||||||
+ packet->index = SPE_HDR_EXTENDED_INDEX(buf[0], buf[1]);
|
|
||||||
else
|
|
||||||
- packet->index = buf[0] & 0x7;
|
|
||||||
+ packet->index = SPE_HDR_SHORT_INDEX(buf[0]);
|
|
||||||
|
|
||||||
return arm_spe_get_payload(buf, len, ext_hdr, packet);
|
|
||||||
}
|
|
||||||
@@ -333,13 +334,13 @@ static int arm_spe_pkt_desc_counter(const struct arm_spe_pkt *packet,
|
|
||||||
(unsigned short)payload);
|
|
||||||
|
|
||||||
switch (packet->index) {
|
|
||||||
- case 0:
|
|
||||||
+ case SPE_CNT_PKT_HDR_INDEX_TOTAL_LAT:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, "TOT");
|
|
||||||
break;
|
|
||||||
- case 1:
|
|
||||||
+ case SPE_CNT_PKT_HDR_INDEX_ISSUE_LAT:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, "ISSUE");
|
|
||||||
break;
|
|
||||||
- case 2:
|
|
||||||
+ case SPE_CNT_PKT_HDR_INDEX_TRANS_LAT:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, "XLAT");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
index 9bc876bffd35..7d8e34e35f05 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
@@ -82,6 +82,11 @@ struct arm_spe_pkt {
|
|
||||||
/* Context packet header */
|
|
||||||
#define SPE_CTX_PKT_HDR_INDEX(h) ((h) & GENMASK_ULL(1, 0))
|
|
||||||
|
|
||||||
+/* Counter packet header */
|
|
||||||
+#define SPE_CNT_PKT_HDR_INDEX_TOTAL_LAT 0x0
|
|
||||||
+#define SPE_CNT_PKT_HDR_INDEX_ISSUE_LAT 0x1
|
|
||||||
+#define SPE_CNT_PKT_HDR_INDEX_TRANS_LAT 0x2
|
|
||||||
+
|
|
||||||
const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
|
|
||||||
|
|
||||||
int arm_spe_get_packet(const unsigned char *buf, size_t len,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,127 +0,0 @@
|
|||||||
From 947dbf5874fd55dd5fe536fe02b3ff699d4efbf5 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:10 +0800
|
|
||||||
Subject: [PATCH 13/21] perf arm-spe: Add new function arm_spe_pkt_desc_event()
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit e66f6d75960220001ce94afe93c981826235c003
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
This patch moves out the event packet parsing from arm_spe_pkt_desc()
|
|
||||||
to the new function arm_spe_pkt_desc_event().
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-10-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 63 +++++++++++--------
|
|
||||||
1 file changed, 37 insertions(+), 26 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 52f4339b1f0c..da6b9f76739c 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -287,6 +287,42 @@ static int arm_spe_pkt_out_string(int *err, char **buf_p, size_t *blen,
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
|
|
||||||
+ char *buf, size_t buf_len)
|
|
||||||
+{
|
|
||||||
+ u64 payload = packet->payload;
|
|
||||||
+ int err = 0;
|
|
||||||
+
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
|
|
||||||
+
|
|
||||||
+ if (payload & 0x1)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
|
|
||||||
+ if (payload & 0x2)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
|
|
||||||
+ if (payload & 0x4)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
|
|
||||||
+ if (payload & 0x8)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
|
|
||||||
+ if (payload & 0x10)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
|
|
||||||
+ if (payload & 0x20)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
|
|
||||||
+ if (payload & 0x40)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
|
|
||||||
+ if (payload & 0x80)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
|
|
||||||
+ if (packet->index > 1) {
|
|
||||||
+ if (payload & 0x100)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
|
|
||||||
+ if (payload & 0x200)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
|
|
||||||
+ if (payload & 0x400)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return err;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
|
|
||||||
char *buf, size_t buf_len)
|
|
||||||
{
|
|
||||||
@@ -367,32 +403,7 @@ int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &blen, "%s", name);
|
|
||||||
break;
|
|
||||||
case ARM_SPE_EVENTS:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, "EV");
|
|
||||||
-
|
|
||||||
- if (payload & 0x1)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " EXCEPTION-GEN");
|
|
||||||
- if (payload & 0x2)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " RETIRED");
|
|
||||||
- if (payload & 0x4)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " L1D-ACCESS");
|
|
||||||
- if (payload & 0x8)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " L1D-REFILL");
|
|
||||||
- if (payload & 0x10)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " TLB-ACCESS");
|
|
||||||
- if (payload & 0x20)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " TLB-REFILL");
|
|
||||||
- if (payload & 0x40)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " NOT-TAKEN");
|
|
||||||
- if (payload & 0x80)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " MISPRED");
|
|
||||||
- if (idx > 1) {
|
|
||||||
- if (payload & 0x100)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " LLC-ACCESS");
|
|
||||||
- if (payload & 0x200)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " LLC-REFILL");
|
|
||||||
- if (payload & 0x400)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " REMOTE-ACCESS");
|
|
||||||
- }
|
|
||||||
+ err = arm_spe_pkt_desc_event(packet, buf, buf_len);
|
|
||||||
break;
|
|
||||||
case ARM_SPE_OP_TYPE:
|
|
||||||
switch (idx) {
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,171 +0,0 @@
|
|||||||
From 6bc7b166d7a3d17413c0d948553f18b66dbfe42d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:11 +0800
|
|
||||||
Subject: [PATCH 14/21] perf arm-spe: Refactor event type handling
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 889d1a675fcfe734f83c459de023a6f0a91a7a0e
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
Move the enums of event types to arm-spe-pkt-decoder.h, thus function
|
|
||||||
arm_spe_pkt_desc_event() can use them for bitmasks.
|
|
||||||
|
|
||||||
Suggested-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-11-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
|
|
||||||
---
|
|
||||||
.../util/arm-spe-decoder/arm-spe-decoder.c | 4 ++--
|
|
||||||
.../util/arm-spe-decoder/arm-spe-decoder.h | 14 ------------
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 22 +++++++++----------
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.h | 18 +++++++++++++++
|
|
||||||
4 files changed, 31 insertions(+), 27 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
|
|
||||||
index 3993c1524c73..2ca980fff04a 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.c
|
|
||||||
@@ -200,13 +200,13 @@ static int arm_spe_walk_trace(struct arm_spe_decoder *decoder)
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ARM_SPE_EVENTS:
|
|
||||||
- if (payload & BIT(EV_TLB_REFILL)) {
|
|
||||||
+ if (payload & BIT(EV_TLB_WALK)) {
|
|
||||||
decoder->state.type |= ARM_SPE_TLB_MISS;
|
|
||||||
decoder->state.is_tlb_miss = true;
|
|
||||||
}
|
|
||||||
if (payload & BIT(EV_MISPRED))
|
|
||||||
decoder->state.type |= ARM_SPE_BRANCH_MISS;
|
|
||||||
- if (idx > 1 && (payload & BIT(EV_LLC_REFILL))) {
|
|
||||||
+ if (idx > 1 && (payload & BIT(EV_LLC_MISS))) {
|
|
||||||
decoder->state.type |= ARM_SPE_LLC_MISS;
|
|
||||||
decoder->state.is_llc_miss = true;
|
|
||||||
}
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
|
|
||||||
index 36d593eda778..17db7d1c14a9 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-decoder.h
|
|
||||||
@@ -6,20 +6,6 @@
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
-enum arm_spe_events {
|
|
||||||
- EV_EXCEPTION_GEN,
|
|
||||||
- EV_RETIRED,
|
|
||||||
- EV_L1D_ACCESS,
|
|
||||||
- EV_L1D_REFILL,
|
|
||||||
- EV_TLB_ACCESS,
|
|
||||||
- EV_TLB_REFILL,
|
|
||||||
- EV_NOT_TAKEN,
|
|
||||||
- EV_MISPRED,
|
|
||||||
- EV_LLC_ACCESS,
|
|
||||||
- EV_LLC_REFILL,
|
|
||||||
- EV_REMOTE_ACCESS,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
enum arm_spe_sample_type {
|
|
||||||
ARM_SPE_LLC_MISS = 1 << 0,
|
|
||||||
ARM_SPE_TLB_MISS = 1 << 1,
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index da6b9f76739c..3f30b2937715 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -295,28 +295,28 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
|
|
||||||
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, "EV");
|
|
||||||
|
|
||||||
- if (payload & 0x1)
|
|
||||||
+ if (payload & BIT(EV_EXCEPTION_GEN))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCEPTION-GEN");
|
|
||||||
- if (payload & 0x2)
|
|
||||||
+ if (payload & BIT(EV_RETIRED))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " RETIRED");
|
|
||||||
- if (payload & 0x4)
|
|
||||||
+ if (payload & BIT(EV_L1D_ACCESS))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-ACCESS");
|
|
||||||
- if (payload & 0x8)
|
|
||||||
+ if (payload & BIT(EV_L1D_REFILL))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " L1D-REFILL");
|
|
||||||
- if (payload & 0x10)
|
|
||||||
+ if (payload & BIT(EV_TLB_ACCESS))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-ACCESS");
|
|
||||||
- if (payload & 0x20)
|
|
||||||
+ if (payload & BIT(EV_TLB_WALK))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " TLB-REFILL");
|
|
||||||
- if (payload & 0x40)
|
|
||||||
+ if (payload & BIT(EV_NOT_TAKEN))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
|
|
||||||
- if (payload & 0x80)
|
|
||||||
+ if (payload & BIT(EV_MISPRED))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
|
|
||||||
if (packet->index > 1) {
|
|
||||||
- if (payload & 0x100)
|
|
||||||
+ if (payload & BIT(EV_LLC_ACCESS))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
|
|
||||||
- if (payload & 0x200)
|
|
||||||
+ if (payload & BIT(EV_LLC_MISS))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
|
|
||||||
- if (payload & 0x400)
|
|
||||||
+ if (payload & BIT(EV_REMOTE_ACCESS))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
index 7d8e34e35f05..42ed4e61ede2 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
@@ -87,6 +87,24 @@ struct arm_spe_pkt {
|
|
||||||
#define SPE_CNT_PKT_HDR_INDEX_ISSUE_LAT 0x1
|
|
||||||
#define SPE_CNT_PKT_HDR_INDEX_TRANS_LAT 0x2
|
|
||||||
|
|
||||||
+/* Event packet payload */
|
|
||||||
+enum arm_spe_events {
|
|
||||||
+ EV_EXCEPTION_GEN = 0,
|
|
||||||
+ EV_RETIRED = 1,
|
|
||||||
+ EV_L1D_ACCESS = 2,
|
|
||||||
+ EV_L1D_REFILL = 3,
|
|
||||||
+ EV_TLB_ACCESS = 4,
|
|
||||||
+ EV_TLB_WALK = 5,
|
|
||||||
+ EV_NOT_TAKEN = 6,
|
|
||||||
+ EV_MISPRED = 7,
|
|
||||||
+ EV_LLC_ACCESS = 8,
|
|
||||||
+ EV_LLC_MISS = 9,
|
|
||||||
+ EV_REMOTE_ACCESS = 10,
|
|
||||||
+ EV_ALIGNMENT = 11,
|
|
||||||
+ EV_PARTIAL_PREDICATE = 17,
|
|
||||||
+ EV_EMPTY_PREDICATE = 18,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
|
|
||||||
|
|
||||||
int arm_spe_get_packet(const unsigned char *buf, size_t len,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
From 18de9e65c81f31b2855301308c05a55002f89239 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:12 +0800
|
|
||||||
Subject: [PATCH 15/21] perf arm-spe: Remove size condition checking for events
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 4d0f4ca273aa95bf592b8bad3c619b5766c8ecc7
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
In the Armv8 ARM (ARM DDI 0487F.c), chapter "D10.2.6 Events packet", it
|
|
||||||
describes the event bit is valid with specific payload requirement. For
|
|
||||||
example, the Last Level cache access event, the bit is defined as:
|
|
||||||
|
|
||||||
E[8], byte 1 bit [0], when SZ == 0b01 , when SZ == 0b10 ,
|
|
||||||
or when SZ == 0b11
|
|
||||||
|
|
||||||
It requires the payload size is at least 2 bytes, when byte 1 (start
|
|
||||||
counting from 0) is valid, E[8] (bit 0 in byte 1) can be used for LLC
|
|
||||||
access event type. For safety, the code checks the condition for
|
|
||||||
payload size firstly, if meet the requirement for payload size, then
|
|
||||||
continue to parse event type.
|
|
||||||
|
|
||||||
If review function arm_spe_get_payload(), it has used cast, so any bytes
|
|
||||||
beyond the valid size have been set to zeros.
|
|
||||||
|
|
||||||
For this reason, we don't need to check payload size anymore afterwards
|
|
||||||
when parse events, thus this patch removes payload size conditions.
|
|
||||||
|
|
||||||
Suggested-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-12-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
---
|
|
||||||
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 14 ++++++--------
|
|
||||||
1 file changed, 6 insertions(+), 8 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 3f30b2937715..88bcf7e5be76 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -311,14 +311,12 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " NOT-TAKEN");
|
|
||||||
if (payload & BIT(EV_MISPRED))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " MISPRED");
|
|
||||||
- if (packet->index > 1) {
|
|
||||||
- if (payload & BIT(EV_LLC_ACCESS))
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
|
|
||||||
- if (payload & BIT(EV_LLC_MISS))
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
|
|
||||||
- if (payload & BIT(EV_REMOTE_ACCESS))
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
|
|
||||||
- }
|
|
||||||
+ if (payload & BIT(EV_LLC_ACCESS))
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-ACCESS");
|
|
||||||
+ if (payload & BIT(EV_LLC_MISS))
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
|
|
||||||
+ if (payload & BIT(EV_REMOTE_ACCESS))
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
From 5428287200dbce2d9e5dbd50e4f32c5cf81a953f Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:13 +0800
|
|
||||||
Subject: [PATCH 16/21] perf arm-spe: Add new function
|
|
||||||
arm_spe_pkt_desc_op_type()
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 7488ffc4d981e19feddfe36a619051bf6216c7a1
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
The operation type packet is complex and contains subclass; the parsing
|
|
||||||
flow causes deep indentation; for more readable, this patch introduces
|
|
||||||
a new function arm_spe_pkt_desc_op_type() which is used for operation
|
|
||||||
type parsing.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-13-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 79 +++++++++++--------
|
|
||||||
1 file changed, 45 insertions(+), 34 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 88bcf7e5be76..d6c060f119b4 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -321,6 +321,50 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,
|
|
||||||
+ char *buf, size_t buf_len)
|
|
||||||
+{
|
|
||||||
+ u64 payload = packet->payload;
|
|
||||||
+ int err = 0;
|
|
||||||
+
|
|
||||||
+ switch (packet->index) {
|
|
||||||
+ case 0:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
+ payload & 0x1 ? "COND-SELECT" : "INSN-OTHER");
|
|
||||||
+ break;
|
|
||||||
+ case 1:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
+ payload & 0x1 ? "ST" : "LD");
|
|
||||||
+
|
|
||||||
+ if (payload & 0x2) {
|
|
||||||
+ if (payload & 0x4)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " AT");
|
|
||||||
+ if (payload & 0x8)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCL");
|
|
||||||
+ if (payload & 0x10)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR");
|
|
||||||
+ } else if (payload & 0x4) {
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP");
|
|
||||||
+ }
|
|
||||||
+ break;
|
|
||||||
+ case 2:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, "B");
|
|
||||||
+
|
|
||||||
+ if (payload & 0x1)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " COND");
|
|
||||||
+ if (payload & 0x2)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " IND");
|
|
||||||
+
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ /* Unknown index */
|
|
||||||
+ err = -1;
|
|
||||||
+ break;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return err;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
|
|
||||||
char *buf, size_t buf_len)
|
|
||||||
{
|
|
||||||
@@ -404,40 +448,7 @@ int arm_spe_pkt_desc(const struct arm_spe_pkt *packet, char *buf,
|
|
||||||
err = arm_spe_pkt_desc_event(packet, buf, buf_len);
|
|
||||||
break;
|
|
||||||
case ARM_SPE_OP_TYPE:
|
|
||||||
- switch (idx) {
|
|
||||||
- case 0:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
- payload & 0x1 ? "COND-SELECT" : "INSN-OTHER");
|
|
||||||
- break;
|
|
||||||
- case 1:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen,
|
|
||||||
- payload & 0x1 ? "ST" : "LD");
|
|
||||||
-
|
|
||||||
- if (payload & 0x2) {
|
|
||||||
- if (payload & 0x4)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " AT");
|
|
||||||
- if (payload & 0x8)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " EXCL");
|
|
||||||
- if (payload & 0x10)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " AR");
|
|
||||||
- } else if (payload & 0x4) {
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " SIMD-FP");
|
|
||||||
- }
|
|
||||||
- break;
|
|
||||||
- case 2:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, "B");
|
|
||||||
-
|
|
||||||
- if (payload & 0x1)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " COND");
|
|
||||||
- if (payload & 0x2)
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &blen, " IND");
|
|
||||||
-
|
|
||||||
- break;
|
|
||||||
- default:
|
|
||||||
- /* Unknown index */
|
|
||||||
- err = -1;
|
|
||||||
- break;
|
|
||||||
- }
|
|
||||||
+ err = arm_spe_pkt_desc_op_type(packet, buf, buf_len);
|
|
||||||
break;
|
|
||||||
case ARM_SPE_DATA_SOURCE:
|
|
||||||
case ARM_SPE_TIMESTAMP:
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,140 +0,0 @@
|
|||||||
From fca84900bf3f1269b6669e7f3dc99810e65d75c8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:14 +0800
|
|
||||||
Subject: [PATCH 17/21] perf arm-spe: Refactor operation packet handling
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit e771218f32f97c0940ae46c23e20d27f3d4c05e3
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
Defines macros for operation packet header and formats (support sub
|
|
||||||
classes for 'other', 'branch', 'load and store', etc). Uses these
|
|
||||||
macros for operation packet decoding and dumping.
|
|
||||||
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-14-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 26 ++++++++++---------
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.h | 23 ++++++++++++++++
|
|
||||||
2 files changed, 37 insertions(+), 12 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index d6c060f119b4..1d1354a0eef4 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -144,7 +144,7 @@ static int arm_spe_get_op_type(const unsigned char *buf, size_t len,
|
|
||||||
struct arm_spe_pkt *packet)
|
|
||||||
{
|
|
||||||
packet->type = ARM_SPE_OP_TYPE;
|
|
||||||
- packet->index = buf[0] & 0x3;
|
|
||||||
+ packet->index = SPE_OP_PKT_HDR_CLASS(buf[0]);
|
|
||||||
return arm_spe_get_payload(buf, len, 0, packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -328,31 +328,33 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
switch (packet->index) {
|
|
||||||
- case 0:
|
|
||||||
+ case SPE_OP_PKT_HDR_CLASS_OTHER:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
- payload & 0x1 ? "COND-SELECT" : "INSN-OTHER");
|
|
||||||
+ payload & SPE_OP_PKT_COND ? "COND-SELECT" : "INSN-OTHER");
|
|
||||||
break;
|
|
||||||
- case 1:
|
|
||||||
+ case SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
payload & 0x1 ? "ST" : "LD");
|
|
||||||
|
|
||||||
- if (payload & 0x2) {
|
|
||||||
- if (payload & 0x4)
|
|
||||||
+ if (SPE_OP_PKT_IS_LDST_ATOMIC(payload)) {
|
|
||||||
+ if (payload & SPE_OP_PKT_AT)
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " AT");
|
|
||||||
- if (payload & 0x8)
|
|
||||||
+ if (payload & SPE_OP_PKT_EXCL)
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCL");
|
|
||||||
- if (payload & 0x10)
|
|
||||||
+ if (payload & SPE_OP_PKT_AR)
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR");
|
|
||||||
- } else if (payload & 0x4) {
|
|
||||||
+ } else if (SPE_OP_PKT_LDST_SUBCLASS_GET(payload) ==
|
|
||||||
+ SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP) {
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
- case 2:
|
|
||||||
+ case SPE_OP_PKT_HDR_CLASS_BR_ERET:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, "B");
|
|
||||||
|
|
||||||
- if (payload & 0x1)
|
|
||||||
+ if (payload & SPE_OP_PKT_COND)
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " COND");
|
|
||||||
- if (payload & 0x2)
|
|
||||||
+
|
|
||||||
+ if (SPE_OP_PKT_IS_INDIRECT_BRANCH(payload))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " IND");
|
|
||||||
|
|
||||||
break;
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
index 42ed4e61ede2..7032fc141ad4 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
@@ -105,6 +105,29 @@ enum arm_spe_events {
|
|
||||||
EV_EMPTY_PREDICATE = 18,
|
|
||||||
};
|
|
||||||
|
|
||||||
+/* Operation packet header */
|
|
||||||
+#define SPE_OP_PKT_HDR_CLASS(h) ((h) & GENMASK_ULL(1, 0))
|
|
||||||
+#define SPE_OP_PKT_HDR_CLASS_OTHER 0x0
|
|
||||||
+#define SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC 0x1
|
|
||||||
+#define SPE_OP_PKT_HDR_CLASS_BR_ERET 0x2
|
|
||||||
+
|
|
||||||
+#define SPE_OP_PKT_COND BIT(0)
|
|
||||||
+
|
|
||||||
+#define SPE_OP_PKT_LDST_SUBCLASS_GET(v) ((v) & GENMASK_ULL(7, 1))
|
|
||||||
+#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG 0x0
|
|
||||||
+#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP 0x4
|
|
||||||
+#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG 0x10
|
|
||||||
+#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG 0x30
|
|
||||||
+
|
|
||||||
+#define SPE_OP_PKT_IS_LDST_ATOMIC(v) (((v) & (GENMASK_ULL(7, 5) | BIT(1))) == 0x2)
|
|
||||||
+
|
|
||||||
+#define SPE_OP_PKT_AR BIT(4)
|
|
||||||
+#define SPE_OP_PKT_EXCL BIT(3)
|
|
||||||
+#define SPE_OP_PKT_AT BIT(2)
|
|
||||||
+#define SPE_OP_PKT_ST BIT(0)
|
|
||||||
+
|
|
||||||
+#define SPE_OP_PKT_IS_INDIRECT_BRANCH(v) (((v) & GENMASK_ULL(7, 1)) == 0x2)
|
|
||||||
+
|
|
||||||
const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
|
|
||||||
|
|
||||||
int arm_spe_get_packet(const unsigned char *buf, size_t len,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
From 574ebcfb7fa23c87ee9bf03f46db5e4a9fb99b7d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:15 +0800
|
|
||||||
Subject: [PATCH 18/21] perf arm-spe: Add more sub classes for operation packet
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 3d829724b16c5d2de42e6c9601c696c93a10bc61
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
For the operation type packet payload with load/store class, it misses
|
|
||||||
to support these sub classes:
|
|
||||||
|
|
||||||
- A load/store targeting the general-purpose registers;
|
|
||||||
- A load/store targeting unspecified registers;
|
|
||||||
- The ARMv8.4 nested virtualisation extension can redirect system
|
|
||||||
register accesses to a memory page controlled by the hypervisor.
|
|
||||||
The SPE profiling feature in newer implementations can tag those
|
|
||||||
memory accesses accordingly.
|
|
||||||
|
|
||||||
Add the bit pattern describing load/store sub classes, so that the perf
|
|
||||||
tool can decode it properly.
|
|
||||||
|
|
||||||
Inspired by Andre Przywara, refined the commit log and code for more
|
|
||||||
clear description.
|
|
||||||
|
|
||||||
Co-developed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-15-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../util/arm-spe-decoder/arm-spe-pkt-decoder.c | 18 ++++++++++++++++--
|
|
||||||
1 file changed, 16 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 1d1354a0eef4..84d661aab54f 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -343,9 +343,23 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " EXCL");
|
|
||||||
if (payload & SPE_OP_PKT_AR)
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR");
|
|
||||||
- } else if (SPE_OP_PKT_LDST_SUBCLASS_GET(payload) ==
|
|
||||||
- SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP) {
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ switch (SPE_OP_PKT_LDST_SUBCLASS_GET(payload)) {
|
|
||||||
+ case SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP");
|
|
||||||
+ break;
|
|
||||||
+ case SPE_OP_PKT_LDST_SUBCLASS_GP_REG:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " GP-REG");
|
|
||||||
+ break;
|
|
||||||
+ case SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " UNSPEC-REG");
|
|
||||||
+ break;
|
|
||||||
+ case SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG:
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " NV-SYSREG");
|
|
||||||
+ break;
|
|
||||||
+ default:
|
|
||||||
+ break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SPE_OP_PKT_HDR_CLASS_BR_ERET:
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
From eac9484827942af027d362264f1730824e162108 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:16 +0800
|
|
||||||
Subject: [PATCH 19/21] perf arm_spe: Decode memory tagging properties
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 3601e605501df289db149785e1e6a8d16e557d31
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
When SPE records a physical address, it can additionally tag the event
|
|
||||||
with information from the Memory Tagging architecture extension.
|
|
||||||
|
|
||||||
Decode the two additional fields in the SPE event payload.
|
|
||||||
|
|
||||||
[leoy: Refined patch to use predefined macros]
|
|
||||||
|
|
||||||
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-16-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 6 +++++-
|
|
||||||
tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h | 2 ++
|
|
||||||
2 files changed, 7 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 84d661aab54f..57c01ce27915 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -385,6 +385,7 @@ static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
|
|
||||||
char *buf, size_t buf_len)
|
|
||||||
{
|
|
||||||
int ns, el, idx = packet->index;
|
|
||||||
+ int ch, pat;
|
|
||||||
u64 payload = packet->payload;
|
|
||||||
int err = 0;
|
|
||||||
|
|
||||||
@@ -404,9 +405,12 @@ static int arm_spe_pkt_desc_addr(const struct arm_spe_pkt *packet,
|
|
||||||
break;
|
|
||||||
case SPE_ADDR_PKT_HDR_INDEX_DATA_PHYS:
|
|
||||||
ns = !!SPE_ADDR_PKT_GET_NS(payload);
|
|
||||||
+ ch = !!SPE_ADDR_PKT_GET_CH(payload);
|
|
||||||
+ pat = SPE_ADDR_PKT_GET_PAT(payload);
|
|
||||||
payload = SPE_ADDR_PKT_ADDR_GET_BYTES_0_6(payload);
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
- "PA 0x%llx ns=%d", payload, ns);
|
|
||||||
+ "PA 0x%llx ns=%d ch=%d pat=%x",
|
|
||||||
+ payload, ns, ch, pat);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Unknown index */
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
index 7032fc141ad4..1ad14885c2a1 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
@@ -73,6 +73,8 @@ struct arm_spe_pkt {
|
|
||||||
|
|
||||||
#define SPE_ADDR_PKT_GET_NS(v) (((v) & BIT_ULL(63)) >> 63)
|
|
||||||
#define SPE_ADDR_PKT_GET_EL(v) (((v) & GENMASK_ULL(62, 61)) >> 61)
|
|
||||||
+#define SPE_ADDR_PKT_GET_CH(v) (((v) & BIT_ULL(62)) >> 62)
|
|
||||||
+#define SPE_ADDR_PKT_GET_PAT(v) (((v) & GENMASK_ULL(59, 56)) >> 56)
|
|
||||||
|
|
||||||
#define SPE_ADDR_PKT_EL0 0
|
|
||||||
#define SPE_ADDR_PKT_EL1 1
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,146 +0,0 @@
|
|||||||
From afde7e19070a48deaac649e0f16f19b164870af1 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Wei Li <liwei391@huawei.com>
|
|
||||||
Date: Fri, 31 Dec 2021 13:32:17 +0800
|
|
||||||
Subject: [PATCH 20/21] perf arm-spe: Add support for ARMv8.3-SPE
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc1
|
|
||||||
commit 05e91e7fe26c6fb116fa16f43c1eed78020f9463
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
-------------------------------------------------
|
|
||||||
|
|
||||||
This patch is to support Armv8.3 extension for SPE, it adds alignment
|
|
||||||
field in the Events packet and it supports the Scalable Vector Extension
|
|
||||||
(SVE) for Operation packet and Events packet with two additions:
|
|
||||||
|
|
||||||
- The vector length for SVE operations in the Operation Type packet;
|
|
||||||
- The incomplete predicate and empty predicate fields in the Events
|
|
||||||
packet.
|
|
||||||
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Signed-off-by: Leo Yan <leo.yan@linaro.org>
|
|
||||||
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
|
|
||||||
Acked-by: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
|
|
||||||
Cc: Al Grant <Al.Grant@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Dave Martin <Dave.Martin@arm.com>
|
|
||||||
Cc: Ingo Molnar <mingo@redhat.com>
|
|
||||||
Cc: James Clark <james.clark@arm.com>
|
|
||||||
Cc: Jiri Olsa <jolsa@redhat.com>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
|
|
||||||
Cc: Namhyung Kim <namhyung@kernel.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Link: https://lore.kernel.org/r/20201119152441.6972-17-leo.yan@linaro.org
|
|
||||||
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
|
|
||||||
Reviewed-by: Yang Jihong <yangjihong1@huawei.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.c | 36 +++++++++++++++++--
|
|
||||||
.../arm-spe-decoder/arm-spe-pkt-decoder.h | 16 +++++++++
|
|
||||||
2 files changed, 50 insertions(+), 2 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
index 57c01ce27915..f3ac9d40cebf 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c
|
|
||||||
@@ -317,6 +317,12 @@ static int arm_spe_pkt_desc_event(const struct arm_spe_pkt *packet,
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " LLC-REFILL");
|
|
||||||
if (payload & BIT(EV_REMOTE_ACCESS))
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, " REMOTE-ACCESS");
|
|
||||||
+ if (payload & BIT(EV_ALIGNMENT))
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " ALIGNMENT");
|
|
||||||
+ if (payload & BIT(EV_PARTIAL_PREDICATE))
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-PARTIAL-PRED");
|
|
||||||
+ if (payload & BIT(EV_EMPTY_PREDICATE))
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " SVE-EMPTY-PRED");
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
@@ -329,8 +335,23 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,
|
|
||||||
|
|
||||||
switch (packet->index) {
|
|
||||||
case SPE_OP_PKT_HDR_CLASS_OTHER:
|
|
||||||
- arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
- payload & SPE_OP_PKT_COND ? "COND-SELECT" : "INSN-OTHER");
|
|
||||||
+ if (SPE_OP_PKT_IS_OTHER_SVE_OP(payload)) {
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, "SVE-OTHER");
|
|
||||||
+
|
|
||||||
+ /* SVE effective vector length */
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " EVLEN %d",
|
|
||||||
+ SPE_OP_PKG_SVE_EVL(payload));
|
|
||||||
+
|
|
||||||
+ if (payload & SPE_OP_PKT_SVE_FP)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " FP");
|
|
||||||
+ if (payload & SPE_OP_PKT_SVE_PRED)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " PRED");
|
|
||||||
+ } else {
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, "OTHER");
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " %s",
|
|
||||||
+ payload & SPE_OP_PKT_COND ?
|
|
||||||
+ "COND-SELECT" : "INSN-OTHER");
|
|
||||||
+ }
|
|
||||||
break;
|
|
||||||
case SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len,
|
|
||||||
@@ -361,6 +382,17 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet,
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ if (SPE_OP_PKT_IS_LDST_SVE(payload)) {
|
|
||||||
+ /* SVE effective vector length */
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " EVLEN %d",
|
|
||||||
+ SPE_OP_PKG_SVE_EVL(payload));
|
|
||||||
+
|
|
||||||
+ if (payload & SPE_OP_PKT_SVE_PRED)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " PRED");
|
|
||||||
+ if (payload & SPE_OP_PKT_SVE_SG)
|
|
||||||
+ arm_spe_pkt_out_string(&err, &buf, &buf_len, " SG");
|
|
||||||
+ }
|
|
||||||
break;
|
|
||||||
case SPE_OP_PKT_HDR_CLASS_BR_ERET:
|
|
||||||
arm_spe_pkt_out_string(&err, &buf, &buf_len, "B");
|
|
||||||
diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
index 1ad14885c2a1..9b970e7bf1e2 100644
|
|
||||||
--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
+++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h
|
|
||||||
@@ -113,6 +113,8 @@ enum arm_spe_events {
|
|
||||||
#define SPE_OP_PKT_HDR_CLASS_LD_ST_ATOMIC 0x1
|
|
||||||
#define SPE_OP_PKT_HDR_CLASS_BR_ERET 0x2
|
|
||||||
|
|
||||||
+#define SPE_OP_PKT_IS_OTHER_SVE_OP(v) (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8)
|
|
||||||
+
|
|
||||||
#define SPE_OP_PKT_COND BIT(0)
|
|
||||||
|
|
||||||
#define SPE_OP_PKT_LDST_SUBCLASS_GET(v) ((v) & GENMASK_ULL(7, 1))
|
|
||||||
@@ -128,6 +130,20 @@ enum arm_spe_events {
|
|
||||||
#define SPE_OP_PKT_AT BIT(2)
|
|
||||||
#define SPE_OP_PKT_ST BIT(0)
|
|
||||||
|
|
||||||
+#define SPE_OP_PKT_IS_LDST_SVE(v) (((v) & (BIT(3) | BIT(1))) == 0x8)
|
|
||||||
+
|
|
||||||
+#define SPE_OP_PKT_SVE_SG BIT(7)
|
|
||||||
+/*
|
|
||||||
+ * SVE effective vector length (EVL) is stored in byte 0 bits [6:4];
|
|
||||||
+ * the length is rounded up to a power of two and use 32 as one step,
|
|
||||||
+ * so EVL calculation is:
|
|
||||||
+ *
|
|
||||||
+ * 32 * (2 ^ bits [6:4]) = 32 << (bits [6:4])
|
|
||||||
+ */
|
|
||||||
+#define SPE_OP_PKG_SVE_EVL(v) (32 << (((v) & GENMASK_ULL(6, 4)) >> 4))
|
|
||||||
+#define SPE_OP_PKT_SVE_PRED BIT(2)
|
|
||||||
+#define SPE_OP_PKT_SVE_FP BIT(1)
|
|
||||||
+
|
|
||||||
#define SPE_OP_PKT_IS_INDIRECT_BRANCH(v) (((v) & GENMASK_ULL(7, 1)) == 0x2)
|
|
||||||
|
|
||||||
const char *arm_spe_pkt_name(enum arm_spe_pkt_type);
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
From d1286fe7f4e98918dd074a4e0a4d593fb6378d42 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Wei Li <liwei391@huawei.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:00 +0800
|
|
||||||
Subject: [PATCH 21/21] drivers/perf: Add support for ARMv8.3-SPE
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.11-rc4
|
|
||||||
commit 4a669e2432fce9c01522a8453460e89f877dccd4
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I4NGPV
|
|
||||||
CVE: NA
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4a669e2432fce9c01522a8453460e89f877dccd4
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Armv8.3 extends the SPE by adding:
|
|
||||||
- Alignment field in the Events packet, and filtering on this event
|
|
||||||
using PMSEVFR_EL1.
|
|
||||||
- Support for the Scalable Vector Extension (SVE).
|
|
||||||
|
|
||||||
The main additions for SVE are:
|
|
||||||
- Recording the vector length for SVE operations in the Operation Type
|
|
||||||
packet. It is not possible to filter on vector length.
|
|
||||||
- Incomplete predicate and empty predicate fields in the Events packet,
|
|
||||||
and filtering on these events using PMSEVFR_EL1.
|
|
||||||
|
|
||||||
Update the check of pmsevfr for empty/partial predicated SVE and
|
|
||||||
alignment event in SPE driver.
|
|
||||||
|
|
||||||
Signed-off-by: Wei Li <liwei391@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/20201203141609.14148-1-liwei391@huawei.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
arch/arm64/include/asm/sysreg.h | 8 +++++++-
|
|
||||||
drivers/perf/arm_spe_pmu.c | 17 +++++++++++++++--
|
|
||||||
2 files changed, 22 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
|
|
||||||
index 242273a04af9..4a3427c2feb5 100644
|
|
||||||
--- a/arch/arm64/include/asm/sysreg.h
|
|
||||||
+++ b/arch/arm64/include/asm/sysreg.h
|
|
||||||
@@ -252,7 +252,11 @@
|
|
||||||
#define SYS_PMSFCR_EL1_ST_SHIFT 18
|
|
||||||
|
|
||||||
#define SYS_PMSEVFR_EL1 sys_reg(3, 0, 9, 9, 5)
|
|
||||||
-#define SYS_PMSEVFR_EL1_RES0 0x0000ffff00ff0f55UL
|
|
||||||
+#define SYS_PMSEVFR_EL1_RES0_8_2 \
|
|
||||||
+ (GENMASK_ULL(47, 32) | GENMASK_ULL(23, 16) | GENMASK_ULL(11, 8) |\
|
|
||||||
+ BIT_ULL(6) | BIT_ULL(4) | BIT_ULL(2) | BIT_ULL(0))
|
|
||||||
+#define SYS_PMSEVFR_EL1_RES0_8_3 \
|
|
||||||
+ (SYS_PMSEVFR_EL1_RES0_8_2 & ~(BIT_ULL(18) | BIT_ULL(17) | BIT_ULL(11)))
|
|
||||||
|
|
||||||
#define SYS_PMSLATFR_EL1 sys_reg(3, 0, 9, 9, 6)
|
|
||||||
#define SYS_PMSLATFR_EL1_MINLAT_SHIFT 0
|
|
||||||
@@ -620,6 +624,8 @@
|
|
||||||
#define ID_AA64DFR0_DEBUGVER_SHIFT 0
|
|
||||||
|
|
||||||
#define ID_AA64DFR0_PMUVER_8_1 0x4
|
|
||||||
+#define ID_AA64DFR0_PMSVER_8_2 0x1
|
|
||||||
+#define ID_AA64DFR0_PMSVER_8_3 0x2
|
|
||||||
|
|
||||||
#define ID_DFR0_PERFMON_SHIFT 24
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/arm_spe_pmu.c b/drivers/perf/arm_spe_pmu.c
|
|
||||||
index af84f3a61e96..74318410774c 100644
|
|
||||||
--- a/drivers/perf/arm_spe_pmu.c
|
|
||||||
+++ b/drivers/perf/arm_spe_pmu.c
|
|
||||||
@@ -65,7 +65,7 @@ struct arm_spe_pmu {
|
|
||||||
struct hlist_node hotplug_node;
|
|
||||||
|
|
||||||
int irq; /* PPI */
|
|
||||||
-
|
|
||||||
+ u16 pmsver;
|
|
||||||
u16 min_period;
|
|
||||||
u16 counter_sz;
|
|
||||||
|
|
||||||
@@ -666,6 +666,18 @@ static irqreturn_t arm_spe_pmu_irq_handler(int irq, void *dev)
|
|
||||||
return IRQ_HANDLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static u64 arm_spe_pmsevfr_res0(u16 pmsver)
|
|
||||||
+{
|
|
||||||
+ switch (pmsver) {
|
|
||||||
+ case ID_AA64DFR0_PMSVER_8_2:
|
|
||||||
+ return SYS_PMSEVFR_EL1_RES0_8_2;
|
|
||||||
+ case ID_AA64DFR0_PMSVER_8_3:
|
|
||||||
+ /* Return the highest version we support in default */
|
|
||||||
+ default:
|
|
||||||
+ return SYS_PMSEVFR_EL1_RES0_8_3;
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* Perf callbacks */
|
|
||||||
static int arm_spe_pmu_event_init(struct perf_event *event)
|
|
||||||
{
|
|
||||||
@@ -681,7 +693,7 @@ static int arm_spe_pmu_event_init(struct perf_event *event)
|
|
||||||
!cpumask_test_cpu(event->cpu, &spe_pmu->supported_cpus))
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
- if (arm_spe_event_to_pmsevfr(event) & SYS_PMSEVFR_EL1_RES0)
|
|
||||||
+ if (arm_spe_event_to_pmsevfr(event) & arm_spe_pmsevfr_res0(spe_pmu->pmsver))
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
if (attr->exclude_idle)
|
|
||||||
@@ -948,6 +960,7 @@ static void __arm_spe_pmu_dev_probe(void *info)
|
|
||||||
fld, smp_processor_id());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
+ spe_pmu->pmsver = (u16)fld;
|
|
||||||
|
|
||||||
/* Read PMBIDR first to determine whether or not we have access */
|
|
||||||
reg = read_sysreg_s(SYS_PMBIDR_EL1);
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,37 +0,0 @@
|
|||||||
From 6f28c899df9750b13fdc86b9b3bb80d46aa89c8d Mon Sep 17 00:00:00 2001
|
|
||||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
Date: Wed, 25 Oct 2023 14:58:04 +0800
|
|
||||||
Subject: [PATCH 01/55] Revert "perf: hisi: Fix compile error if defined
|
|
||||||
MODULE"
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
--------------------------------------------------------------
|
|
||||||
|
|
||||||
This reverts commit f00917fa81207962a5455e1084c90aff36b3a6ae.
|
|
||||||
|
|
||||||
This bugfix fixed in higher verison in L3t pmu driver, inclusion it later.
|
|
||||||
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c | 2 +-
|
|
||||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
|
||||||
index ca395252ccc3..8f8b211788e0 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
|
||||||
@@ -241,7 +241,7 @@ static int hisi_lpddrc_pmu_init_irq(struct hisi_pmu *lpddrc_pmu,
|
|
||||||
static const struct of_device_id lpddrc_of_match[] = {
|
|
||||||
{ .compatible = "hisilicon,lpddrc-pmu", },
|
|
||||||
{},
|
|
||||||
-};
|
|
||||||
+}
|
|
||||||
MODULE_DEVICE_TABLE(of, lpddrc_of_match);
|
|
||||||
|
|
||||||
static int hisi_lpddrc_pmu_init_data(struct platform_device *pdev,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,480 +0,0 @@
|
|||||||
From 7cd21a232cb93ea0598386c028c88e1931946887 Mon Sep 17 00:00:00 2001
|
|
||||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
Date: Wed, 25 Oct 2023 15:03:16 +0800
|
|
||||||
Subject: [PATCH 02/55] Revert "perf: hisi: Add support for HiSilicon SoC L3T
|
|
||||||
PMU driver"
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
------------------------------------------------------------
|
|
||||||
|
|
||||||
This reverts commit 72ed85332d7704ab91afe3f14ab95b39fca17e97.
|
|
||||||
|
|
||||||
Now, revert it, then we will inclusion the newer version of L3T PMU
|
|
||||||
driver.
|
|
||||||
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/perf/hisilicon/Makefile
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/Makefile | 7 +-
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c | 432 -------------------
|
|
||||||
2 files changed, 1 insertion(+), 438 deletions(-)
|
|
||||||
delete mode 100644 drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
|
||||||
index 63942ae6b167..3651f18260e5 100644
|
|
||||||
--- a/drivers/perf/hisilicon/Makefile
|
|
||||||
+++ b/drivers/perf/hisilicon/Makefile
|
|
||||||
@@ -1,6 +1 @@
|
|
||||||
-obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o \
|
|
||||||
- hisi_uncore_l3c_pmu.o \
|
|
||||||
- hisi_uncore_hha_pmu.o \
|
|
||||||
- hisi_uncore_ddrc_pmu.o \
|
|
||||||
- hisi_uncore_lpddrc_pmu.o \
|
|
||||||
- hisi_uncore_l3t_pmu.o
|
|
||||||
+obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_lpddrc_pmu.o
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c
|
|
||||||
deleted file mode 100644
|
|
||||||
index bd4e600e0c32..000000000000
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3t_pmu.c
|
|
||||||
+++ /dev/null
|
|
||||||
@@ -1,432 +0,0 @@
|
|
||||||
-// SPDX-License-Identifier: GPL-2.0
|
|
||||||
-/*
|
|
||||||
- * HiSilicon SoC L3T uncore Hardware event counters support
|
|
||||||
- *
|
|
||||||
- * Copyright (C) 2021 Hisilicon Limited
|
|
||||||
- * Author: Fang Lijun <fanglijun3@huawei.com>
|
|
||||||
- * Anurup M <anurup.m@huawei.com>
|
|
||||||
- * Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
- *
|
|
||||||
- * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
|
||||||
- *
|
|
||||||
- * This program is free software; you can redistribute it and/or modify
|
|
||||||
- * it under the terms of the GNU General Public License version 2 as
|
|
||||||
- * published by the Free Software Foundation.
|
|
||||||
- */
|
|
||||||
-#include <linux/acpi.h>
|
|
||||||
-#include <linux/bug.h>
|
|
||||||
-#include <linux/cpuhotplug.h>
|
|
||||||
-#include <linux/interrupt.h>
|
|
||||||
-#include <linux/irq.h>
|
|
||||||
-#include <linux/list.h>
|
|
||||||
-#include <linux/of.h>
|
|
||||||
-#include <linux/platform_device.h>
|
|
||||||
-#include <linux/smp.h>
|
|
||||||
-
|
|
||||||
-#include "hisi_uncore_pmu.h"
|
|
||||||
-
|
|
||||||
-/* L3T register definition */
|
|
||||||
-#define L3T_PERF_CTRL 0x0408
|
|
||||||
-#define L3T_INT_MASK 0x0800
|
|
||||||
-#define L3T_INT_STATUS 0x0808
|
|
||||||
-#define L3T_INT_CLEAR 0x080c
|
|
||||||
-#define L3T_EVENT_CTRL 0x1c00
|
|
||||||
-#define L3T_EVENT_TYPE0 0x1d00
|
|
||||||
-/*
|
|
||||||
- * Each counter is 48-bits and [48:63] are reserved
|
|
||||||
- * which are Read-As-Zero and Writes-Ignored.
|
|
||||||
- */
|
|
||||||
-#define L3T_CNTR0_LOWER 0x1e00
|
|
||||||
-
|
|
||||||
-/* L3T has 8-counters */
|
|
||||||
-#define L3T_NR_COUNTERS 0x8
|
|
||||||
-
|
|
||||||
-#define L3T_PERF_CTRL_EN 0x20000
|
|
||||||
-#define L3T_EVTYPE_NONE 0xff
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * Select the counter register offset using the counter index
|
|
||||||
- */
|
|
||||||
-static u32 hisi_l3t_pmu_get_counter_offset(u32 cntr_idx)
|
|
||||||
-{
|
|
||||||
- return (L3T_CNTR0_LOWER + (cntr_idx * 8));
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static u64 hisi_l3t_pmu_read_counter(struct hisi_pmu *l3t_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- u32 idx = hwc->idx;
|
|
||||||
-
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(l3t_pmu, idx)) {
|
|
||||||
- dev_err(l3t_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Read 64-bits and the upper 16 bits are RAZ */
|
|
||||||
- return readq(l3t_pmu->base + hisi_l3t_pmu_get_counter_offset(idx));
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_l3t_pmu_write_counter(struct hisi_pmu *l3t_pmu,
|
|
||||||
- struct hw_perf_event *hwc, u64 val)
|
|
||||||
-{
|
|
||||||
- u32 idx = hwc->idx;
|
|
||||||
-
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(l3t_pmu, idx)) {
|
|
||||||
- dev_err(l3t_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Write 64-bits and the upper 16 bits are WI */
|
|
||||||
- writeq(val, l3t_pmu->base + hisi_l3t_pmu_get_counter_offset(idx));
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_l3t_pmu_write_evtype(struct hisi_pmu *l3t_pmu, int idx,
|
|
||||||
- u32 type)
|
|
||||||
-{
|
|
||||||
- u32 reg, reg_idx, shift, val;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Select the appropriate event select register(L3T_EVENT_TYPE0/1).
|
|
||||||
- * There are 2 event select registers for the 8 hardware counters.
|
|
||||||
- * Event code is 8-bits and for the former 4 hardware counters,
|
|
||||||
- * L3T_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
|
|
||||||
- * L3T_EVENT_TYPE1 is chosen.
|
|
||||||
- */
|
|
||||||
- reg = L3T_EVENT_TYPE0 + (idx / 4) * 4;
|
|
||||||
- reg_idx = idx % 4;
|
|
||||||
- shift = 8 * reg_idx;
|
|
||||||
-
|
|
||||||
- /* Write event code to L3T_EVENT_TYPEx Register */
|
|
||||||
- val = readl(l3t_pmu->base + reg);
|
|
||||||
- val &= ~(L3T_EVTYPE_NONE << shift);
|
|
||||||
- val |= (type << shift);
|
|
||||||
- writel(val, l3t_pmu->base + reg);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_l3t_pmu_start_counters(struct hisi_pmu *l3t_pmu)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Set perf_enable bit in L3T_PERF_CTRL register to start counting
|
|
||||||
- * for all enabled counters.
|
|
||||||
- */
|
|
||||||
- val = readl(l3t_pmu->base + L3T_PERF_CTRL);
|
|
||||||
- val |= L3T_PERF_CTRL_EN;
|
|
||||||
- writel(val, l3t_pmu->base + L3T_PERF_CTRL);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_l3t_pmu_stop_counters(struct hisi_pmu *l3t_pmu)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Clear perf_enable bit in L3T_PERF_CTRL register to stop counting
|
|
||||||
- * for all enabled counters.
|
|
||||||
- */
|
|
||||||
- val = readl(l3t_pmu->base + L3T_PERF_CTRL);
|
|
||||||
- val &= ~(L3T_PERF_CTRL_EN);
|
|
||||||
- writel(val, l3t_pmu->base + L3T_PERF_CTRL);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_l3t_pmu_enable_counter(struct hisi_pmu *l3t_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /* Enable counter index in L3T_EVENT_CTRL register */
|
|
||||||
- val = readl(l3t_pmu->base + L3T_EVENT_CTRL);
|
|
||||||
- val |= (1 << hwc->idx);
|
|
||||||
- writel(val, l3t_pmu->base + L3T_EVENT_CTRL);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_l3t_pmu_disable_counter(struct hisi_pmu *l3t_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /* Clear counter index in L3T_EVENT_CTRL register */
|
|
||||||
- val = readl(l3t_pmu->base + L3T_EVENT_CTRL);
|
|
||||||
- val &= ~(1 << hwc->idx);
|
|
||||||
- writel(val, l3t_pmu->base + L3T_EVENT_CTRL);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_l3t_pmu_enable_counter_int(struct hisi_pmu *l3t_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- val = readl(l3t_pmu->base + L3T_INT_MASK);
|
|
||||||
- /* Write 0 to enable interrupt */
|
|
||||||
- val &= ~(1 << hwc->idx);
|
|
||||||
- writel(val, l3t_pmu->base + L3T_INT_MASK);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_l3t_pmu_disable_counter_int(struct hisi_pmu *l3t_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- val = readl(l3t_pmu->base + L3T_INT_MASK);
|
|
||||||
- /* Write 1 to mask interrupt */
|
|
||||||
- val |= (1 << hwc->idx);
|
|
||||||
- writel(val, l3t_pmu->base + L3T_INT_MASK);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static irqreturn_t hisi_l3t_pmu_isr(int irq, void *dev_id)
|
|
||||||
-{
|
|
||||||
- struct hisi_pmu *l3t_pmu = dev_id;
|
|
||||||
- struct perf_event *event;
|
|
||||||
- unsigned long overflown;
|
|
||||||
- int idx;
|
|
||||||
-
|
|
||||||
- /* Read L3T_INT_STATUS register */
|
|
||||||
- overflown = readl(l3t_pmu->base + L3T_INT_STATUS);
|
|
||||||
- if (!overflown)
|
|
||||||
- return IRQ_NONE;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Find the counter index which overflowed if the bit was set
|
|
||||||
- * and handle it.
|
|
||||||
- */
|
|
||||||
- for_each_set_bit(idx, &overflown, L3T_NR_COUNTERS) {
|
|
||||||
- /* Write 1 to clear the IRQ status flag */
|
|
||||||
- writel((1 << idx), l3t_pmu->base + L3T_INT_CLEAR);
|
|
||||||
-
|
|
||||||
- /* Get the corresponding event struct */
|
|
||||||
- event = l3t_pmu->pmu_events.hw_events[idx];
|
|
||||||
- if (!event)
|
|
||||||
- continue;
|
|
||||||
-
|
|
||||||
- hisi_uncore_pmu_event_update(event);
|
|
||||||
- hisi_uncore_pmu_set_event_period(event);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return IRQ_HANDLED;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int hisi_l3t_pmu_init_irq(struct hisi_pmu *l3t_pmu,
|
|
||||||
- struct platform_device *pdev)
|
|
||||||
-{
|
|
||||||
- int irq, ret;
|
|
||||||
-
|
|
||||||
- /* Read and init IRQ */
|
|
||||||
- irq = platform_get_irq(pdev, 0);
|
|
||||||
- if (irq < 0) {
|
|
||||||
- dev_err(&pdev->dev, "L3T PMU get irq fail; irq:%d\n", irq);
|
|
||||||
- return irq;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_l3t_pmu_isr,
|
|
||||||
- IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_SHARED,
|
|
||||||
- dev_name(&pdev->dev), l3t_pmu);
|
|
||||||
- if (ret < 0) {
|
|
||||||
- dev_err(&pdev->dev,
|
|
||||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- l3t_pmu->irq = irq;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static const struct of_device_id l3t_of_match[] = {
|
|
||||||
- { .compatible = "hisilicon,l3t-pmu", },
|
|
||||||
- {},
|
|
||||||
-};
|
|
||||||
-MODULE_DEVICE_TABLE(of, l3t_of_match);
|
|
||||||
-
|
|
||||||
-static int hisi_l3t_pmu_init_data(struct platform_device *pdev,
|
|
||||||
- struct hisi_pmu *l3t_pmu)
|
|
||||||
-{
|
|
||||||
- struct resource *res;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Use the SCCL_ID and CCL_ID to identify the L3T PMU, while
|
|
||||||
- * SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
|
|
||||||
- */
|
|
||||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
|
||||||
- &l3t_pmu->sccl_id)) {
|
|
||||||
- dev_err(&pdev->dev, "Can not read l3t sccl-id!\n");
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,ccl-id",
|
|
||||||
- &l3t_pmu->ccl_id)) {
|
|
||||||
- dev_err(&pdev->dev, "Can not read l3t ccl-id!\n");
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,index-id",
|
|
||||||
- &l3t_pmu->index_id)) {
|
|
||||||
- dev_err(&pdev->dev, "Can not read l3t index-id!\n");
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
||||||
- l3t_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
|
||||||
- if (IS_ERR(l3t_pmu->base)) {
|
|
||||||
- dev_err(&pdev->dev, "ioremap failed for l3t_pmu resource\n");
|
|
||||||
- return PTR_ERR(l3t_pmu->base);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static struct attribute *hisi_l3t_pmu_format_attr[] = {
|
|
||||||
- HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
|
||||||
- NULL,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct attribute_group hisi_l3t_pmu_format_group = {
|
|
||||||
- .name = "format",
|
|
||||||
- .attrs = hisi_l3t_pmu_format_attr,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static struct attribute *hisi_l3t_pmu_events_attr[] = {
|
|
||||||
- HISI_PMU_EVENT_ATTR(rd_cpipe, 0x00),
|
|
||||||
- HISI_PMU_EVENT_ATTR(wr_cpipe, 0x01),
|
|
||||||
- HISI_PMU_EVENT_ATTR(rd_hit_cpipe, 0x02),
|
|
||||||
- HISI_PMU_EVENT_ATTR(wr_hit_cpipe, 0x03),
|
|
||||||
- HISI_PMU_EVENT_ATTR(victim_num, 0x04),
|
|
||||||
- HISI_PMU_EVENT_ATTR(rd_spipe, 0x20),
|
|
||||||
- HISI_PMU_EVENT_ATTR(wr_spipe, 0x21),
|
|
||||||
- HISI_PMU_EVENT_ATTR(rd_hit_spipe, 0x22),
|
|
||||||
- HISI_PMU_EVENT_ATTR(wr_hit_spipe, 0x23),
|
|
||||||
- HISI_PMU_EVENT_ATTR(back_invalid, 0x29),
|
|
||||||
- HISI_PMU_EVENT_ATTR(retry_cpu, 0x40),
|
|
||||||
- HISI_PMU_EVENT_ATTR(retry_ring, 0x41),
|
|
||||||
- HISI_PMU_EVENT_ATTR(prefetch_drop, 0x42),
|
|
||||||
- NULL,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct attribute_group hisi_l3t_pmu_events_group = {
|
|
||||||
- .name = "events",
|
|
||||||
- .attrs = hisi_l3t_pmu_events_attr,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
-
|
|
||||||
-static struct attribute *hisi_l3t_pmu_cpumask_attrs[] = {
|
|
||||||
- &dev_attr_cpumask.attr,
|
|
||||||
- NULL,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct attribute_group hisi_l3t_pmu_cpumask_attr_group = {
|
|
||||||
- .attrs = hisi_l3t_pmu_cpumask_attrs,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct attribute_group *hisi_l3t_pmu_attr_groups[] = {
|
|
||||||
- &hisi_l3t_pmu_format_group,
|
|
||||||
- &hisi_l3t_pmu_events_group,
|
|
||||||
- &hisi_l3t_pmu_cpumask_attr_group,
|
|
||||||
- NULL,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct hisi_uncore_ops hisi_uncore_l3t_ops = {
|
|
||||||
- .write_evtype = hisi_l3t_pmu_write_evtype,
|
|
||||||
- .get_event_idx = hisi_uncore_pmu_get_event_idx,
|
|
||||||
- .start_counters = hisi_l3t_pmu_start_counters,
|
|
||||||
- .stop_counters = hisi_l3t_pmu_stop_counters,
|
|
||||||
- .enable_counter = hisi_l3t_pmu_enable_counter,
|
|
||||||
- .disable_counter = hisi_l3t_pmu_disable_counter,
|
|
||||||
- .enable_counter_int = hisi_l3t_pmu_enable_counter_int,
|
|
||||||
- .disable_counter_int = hisi_l3t_pmu_disable_counter_int,
|
|
||||||
- .write_counter = hisi_l3t_pmu_write_counter,
|
|
||||||
- .read_counter = hisi_l3t_pmu_read_counter,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static int hisi_l3t_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
- struct hisi_pmu *l3t_pmu)
|
|
||||||
-{
|
|
||||||
- int ret;
|
|
||||||
-
|
|
||||||
- ret = hisi_l3t_pmu_init_data(pdev, l3t_pmu);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
-
|
|
||||||
- ret = hisi_l3t_pmu_init_irq(l3t_pmu, pdev);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
-
|
|
||||||
- l3t_pmu->num_counters = L3T_NR_COUNTERS;
|
|
||||||
- l3t_pmu->counter_bits = 48;
|
|
||||||
- l3t_pmu->ops = &hisi_uncore_l3t_ops;
|
|
||||||
- l3t_pmu->dev = &pdev->dev;
|
|
||||||
- l3t_pmu->on_cpu = -1;
|
|
||||||
- l3t_pmu->check_event = 0x59;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int hisi_l3t_pmu_probe(struct platform_device *pdev)
|
|
||||||
-{
|
|
||||||
- struct hisi_pmu *l3t_pmu;
|
|
||||||
- char *name;
|
|
||||||
- int ret;
|
|
||||||
-
|
|
||||||
- l3t_pmu = devm_kzalloc(&pdev->dev, sizeof(*l3t_pmu), GFP_KERNEL);
|
|
||||||
- if (!l3t_pmu)
|
|
||||||
- return -ENOMEM;
|
|
||||||
-
|
|
||||||
- platform_set_drvdata(pdev, l3t_pmu);
|
|
||||||
-
|
|
||||||
- ret = hisi_l3t_pmu_dev_probe(pdev, l3t_pmu);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
-
|
|
||||||
- name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3t%u",
|
|
||||||
- l3t_pmu->sccl_id, l3t_pmu->index_id);
|
|
||||||
- HISI_INIT_PMU(&l3t_pmu->pmu, name, hisi_l3t_pmu_attr_groups);
|
|
||||||
-
|
|
||||||
- ret = perf_pmu_register(&l3t_pmu->pmu, name, -1);
|
|
||||||
- if (ret) {
|
|
||||||
- dev_err(l3t_pmu->dev, "L3T PMU register failed!\n");
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Pick one core to use for cpumask attributes */
|
|
||||||
- cpumask_set_cpu(smp_processor_id(), &l3t_pmu->associated_cpus);
|
|
||||||
-
|
|
||||||
- l3t_pmu->on_cpu = cpumask_first(&l3t_pmu->associated_cpus);
|
|
||||||
- if (l3t_pmu->on_cpu >= nr_cpu_ids)
|
|
||||||
- return -EINVAL;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int hisi_l3t_pmu_remove(struct platform_device *pdev)
|
|
||||||
-{
|
|
||||||
- struct hisi_pmu *l3t_pmu = platform_get_drvdata(pdev);
|
|
||||||
-
|
|
||||||
- perf_pmu_unregister(&l3t_pmu->pmu);
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static struct platform_driver hisi_l3t_pmu_driver = {
|
|
||||||
- .driver = {
|
|
||||||
- .name = "hisi_l3t_pmu",
|
|
||||||
- .of_match_table = of_match_ptr(l3t_of_match),
|
|
||||||
- },
|
|
||||||
- .probe = hisi_l3t_pmu_probe,
|
|
||||||
- .remove = hisi_l3t_pmu_remove,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static int __init hisi_l3t_pmu_module_init(void)
|
|
||||||
-{
|
|
||||||
- return platform_driver_register(&hisi_l3t_pmu_driver);
|
|
||||||
-}
|
|
||||||
-module_init(hisi_l3t_pmu_module_init);
|
|
||||||
-
|
|
||||||
-static void __exit hisi_l3t_pmu_module_exit(void)
|
|
||||||
-{
|
|
||||||
- platform_driver_unregister(&hisi_l3t_pmu_driver);
|
|
||||||
-}
|
|
||||||
-module_exit(hisi_l3t_pmu_module_exit);
|
|
||||||
-
|
|
||||||
-MODULE_DESCRIPTION("HiSilicon SoC L3T uncore PMU driver");
|
|
||||||
-MODULE_LICENSE("GPL v2");
|
|
||||||
-MODULE_AUTHOR("HUAWEI TECHNOLOGIES CO., LTD.");
|
|
||||||
-MODULE_AUTHOR("Fang Lijun <fanglijun3@huawei.com>");
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,469 +0,0 @@
|
|||||||
From a42c8f603e8d0aa7d67023014604d919227581dd Mon Sep 17 00:00:00 2001
|
|
||||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
Date: Wed, 25 Oct 2023 15:04:16 +0800
|
|
||||||
Subject: [PATCH 03/55] Revert "perf: hisi: Add support for HiSilicon SoC
|
|
||||||
LPDDRC PMU driver"
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
-------------------------------------------------------------
|
|
||||||
|
|
||||||
This reverts commit be4e2dae37269ece33d54f906323b00208a569b0.
|
|
||||||
|
|
||||||
Now, revert it, then we will inclusion the newer version of LPDRRC PMU
|
|
||||||
driver.
|
|
||||||
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/Makefile | 2 +-
|
|
||||||
.../perf/hisilicon/hisi_uncore_lpddrc_pmu.c | 429 ------------------
|
|
||||||
2 files changed, 1 insertion(+), 430 deletions(-)
|
|
||||||
delete mode 100644 drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
|
||||||
index 3651f18260e5..2621d51ae87a 100644
|
|
||||||
--- a/drivers/perf/hisilicon/Makefile
|
|
||||||
+++ b/drivers/perf/hisilicon/Makefile
|
|
||||||
@@ -1 +1 @@
|
|
||||||
-obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_lpddrc_pmu.o
|
|
||||||
+obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
|
||||||
deleted file mode 100644
|
|
||||||
index 8f8b211788e0..000000000000
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_lpddrc_pmu.c
|
|
||||||
+++ /dev/null
|
|
||||||
@@ -1,429 +0,0 @@
|
|
||||||
-// SPDX-License-Identifier: GPL-2.0
|
|
||||||
-/*
|
|
||||||
- * HiSilicon SoC LPDDRC uncore Hardware event counters support
|
|
||||||
- *
|
|
||||||
- * Copyright (C) 2021 Hisilicon Limited
|
|
||||||
- * Author: Fang Lijun <fanglijun3@huawei.com>
|
|
||||||
- * Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
- * Anurup M <anurup.m@huawei.com>
|
|
||||||
- *
|
|
||||||
- * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
|
||||||
- *
|
|
||||||
- * This program is free software; you can redistribute it and/or modify
|
|
||||||
- * it under the terms of the GNU General Public License version 2 as
|
|
||||||
- * published by the Free Software Foundation.
|
|
||||||
- */
|
|
||||||
-#include <linux/acpi.h>
|
|
||||||
-#include <linux/bug.h>
|
|
||||||
-#include <linux/cpuhotplug.h>
|
|
||||||
-#include <linux/interrupt.h>
|
|
||||||
-#include <linux/irq.h>
|
|
||||||
-#include <linux/list.h>
|
|
||||||
-#include <linux/of.h>
|
|
||||||
-#include <linux/platform_device.h>
|
|
||||||
-#include <linux/smp.h>
|
|
||||||
-
|
|
||||||
-#include "hisi_uncore_pmu.h"
|
|
||||||
-
|
|
||||||
-/* LPDDRC register definition */
|
|
||||||
-#define LPDDRC_PERF_CTRL 0x4930
|
|
||||||
-#define LPDDRC_FLUX_WR 0x4948
|
|
||||||
-#define LPDDRC_FLUX_RD 0x494c
|
|
||||||
-#define LPDDRC_FLUX_WCMD 0x4950
|
|
||||||
-#define LPDDRC_FLUX_RCMD 0x4954
|
|
||||||
-#define LPDDRC_PRE_CMD 0x4984
|
|
||||||
-#define LPDDRC_ACT_CMD 0x4988
|
|
||||||
-#define LPDDRC_RNK_CHG 0x4990
|
|
||||||
-#define LPDDRC_RW_CHG 0x4994
|
|
||||||
-#define LPDDRC_EVENT_CTRL 0x4d60
|
|
||||||
-#define LPDDRC_INT_MASK 0x6c8
|
|
||||||
-#define LPDDRC_INT_STATUS 0x6cc
|
|
||||||
-#define LPDDRC_INT_CLEAR 0x6d0
|
|
||||||
-
|
|
||||||
-/* LPDDRC has 8-counters */
|
|
||||||
-#define LPDDRC_NR_COUNTERS 0x8
|
|
||||||
-#define LPDDRC_PERF_CTRL_EN 0x1
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * For LPDDRC PMU, there are eight-events and every event has been mapped
|
|
||||||
- * to fixed-purpose counters which register offset is not consistent.
|
|
||||||
- * Therefore there is no write event type and we assume that event
|
|
||||||
- * code (0 to 7) is equal to counter index in PMU driver.
|
|
||||||
- */
|
|
||||||
-#define GET_LPDDRC_EVENTID(hwc) (hwc->config_base & 0x7)
|
|
||||||
-
|
|
||||||
-static const u32 lpddrc_reg_off[] = {
|
|
||||||
- LPDDRC_FLUX_WR, LPDDRC_FLUX_RD, LPDDRC_FLUX_WCMD, LPDDRC_FLUX_RCMD,
|
|
||||||
- LPDDRC_PRE_CMD, LPDDRC_ACT_CMD, LPDDRC_RNK_CHG, LPDDRC_RW_CHG
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * Select the counter register offset using the counter index.
|
|
||||||
- * In LPDDRC there are no programmable counter, the count
|
|
||||||
- * is readed form the statistics counter register itself.
|
|
||||||
- */
|
|
||||||
-static u32 hisi_lpddrc_pmu_get_counter_offset(int cntr_idx)
|
|
||||||
-{
|
|
||||||
- return lpddrc_reg_off[cntr_idx];
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static u64 hisi_lpddrc_pmu_read_counter(struct hisi_pmu *lpddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- /* Use event code as counter index */
|
|
||||||
- u32 idx = GET_LPDDRC_EVENTID(hwc);
|
|
||||||
-
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(lpddrc_pmu, idx)) {
|
|
||||||
- dev_err(lpddrc_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return readl(lpddrc_pmu->base + hisi_lpddrc_pmu_get_counter_offset(idx));
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * For LPDDRC PMU, event counter should be reset when start counters,
|
|
||||||
- * reset the prev_count by software, because the counter register was RO.
|
|
||||||
- */
|
|
||||||
-static void hisi_lpddrc_pmu_write_counter(struct hisi_pmu *lpddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc, u64 val)
|
|
||||||
-{
|
|
||||||
- local64_set(&hwc->prev_count, 0);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-/*
|
|
||||||
- * For LPDDRC PMU, event has been mapped to fixed-purpose counter by hardware,
|
|
||||||
- * so there is no need to write event type.
|
|
||||||
- */
|
|
||||||
-static void hisi_lpddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
|
|
||||||
- u32 type)
|
|
||||||
-{
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_lpddrc_pmu_start_counters(struct hisi_pmu *lpddrc_pmu)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /* Set perf_enable in LPDDRC_PERF_CTRL to start event counting */
|
|
||||||
- val = readl(lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
|
||||||
- val |= LPDDRC_PERF_CTRL_EN;
|
|
||||||
- writel(val, lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_lpddrc_pmu_stop_counters(struct hisi_pmu *lpddrc_pmu)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /* Clear perf_enable in LPDDRC_PERF_CTRL to stop event counting */
|
|
||||||
- val = readl(lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
|
||||||
- val &= ~LPDDRC_PERF_CTRL_EN;
|
|
||||||
- writel(val, lpddrc_pmu->base + LPDDRC_PERF_CTRL);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_lpddrc_pmu_enable_counter(struct hisi_pmu *lpddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /* Set counter index(event code) in LPDDRC_EVENT_CTRL register */
|
|
||||||
- val = readl(lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
|
||||||
- val |= (1 << GET_LPDDRC_EVENTID(hwc));
|
|
||||||
- writel(val, lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_lpddrc_pmu_disable_counter(struct hisi_pmu *lpddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /* Clear counter index(event code) in LPDDRC_EVENT_CTRL register */
|
|
||||||
- val = readl(lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
|
||||||
- val &= ~(1 << GET_LPDDRC_EVENTID(hwc));
|
|
||||||
- writel(val, lpddrc_pmu->base + LPDDRC_EVENT_CTRL);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int hisi_lpddrc_pmu_get_event_idx(struct perf_event *event)
|
|
||||||
-{
|
|
||||||
- struct hisi_pmu *lpddrc_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
- unsigned long *used_mask = lpddrc_pmu->pmu_events.used_mask;
|
|
||||||
- struct hw_perf_event *hwc = &event->hw;
|
|
||||||
- /* For LPDDRC PMU, we use event code as counter index */
|
|
||||||
- int idx = GET_LPDDRC_EVENTID(hwc);
|
|
||||||
-
|
|
||||||
- if (test_bit(idx, used_mask))
|
|
||||||
- return -EAGAIN;
|
|
||||||
-
|
|
||||||
- set_bit(idx, used_mask);
|
|
||||||
-
|
|
||||||
- return idx;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_lpddrc_pmu_enable_counter_int(struct hisi_pmu *lpddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /* Write 0 to enable interrupt */
|
|
||||||
- val = readl(lpddrc_pmu->base + LPDDRC_INT_MASK);
|
|
||||||
- val &= ~(1 << GET_LPDDRC_EVENTID(hwc));
|
|
||||||
- writel(val, lpddrc_pmu->base + LPDDRC_INT_MASK);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static void hisi_lpddrc_pmu_disable_counter_int(struct hisi_pmu *lpddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
-{
|
|
||||||
- u32 val;
|
|
||||||
-
|
|
||||||
- /* Write 1 to mask interrupt */
|
|
||||||
- val = readl(lpddrc_pmu->base + LPDDRC_INT_MASK);
|
|
||||||
- val |= (1 << GET_LPDDRC_EVENTID(hwc));
|
|
||||||
- writel(val, lpddrc_pmu->base + LPDDRC_INT_MASK);
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static irqreturn_t hisi_lpddrc_pmu_isr(int irq, void *dev_id)
|
|
||||||
-{
|
|
||||||
- struct hisi_pmu *lpddrc_pmu = dev_id;
|
|
||||||
- struct perf_event *event;
|
|
||||||
- unsigned long overflown;
|
|
||||||
- int idx;
|
|
||||||
-
|
|
||||||
- /* Read the LPDDRC_INT_STATUS register */
|
|
||||||
- overflown = readl(lpddrc_pmu->base + LPDDRC_INT_STATUS);
|
|
||||||
- if (!overflown)
|
|
||||||
- return IRQ_NONE;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Find the counter index which overflowed if the bit was set
|
|
||||||
- * and handle it
|
|
||||||
- */
|
|
||||||
- for_each_set_bit(idx, &overflown, LPDDRC_NR_COUNTERS) {
|
|
||||||
- /* Write 1 to clear the IRQ status flag */
|
|
||||||
- writel((1 << idx), lpddrc_pmu->base + LPDDRC_INT_CLEAR);
|
|
||||||
-
|
|
||||||
- /* Get the corresponding event struct */
|
|
||||||
- event = lpddrc_pmu->pmu_events.hw_events[idx];
|
|
||||||
- if (!event)
|
|
||||||
- continue;
|
|
||||||
-
|
|
||||||
- hisi_uncore_pmu_event_update(event);
|
|
||||||
- hisi_uncore_pmu_set_event_period(event);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return IRQ_HANDLED;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int hisi_lpddrc_pmu_init_irq(struct hisi_pmu *lpddrc_pmu,
|
|
||||||
- struct platform_device *pdev)
|
|
||||||
-{
|
|
||||||
- int irq, ret;
|
|
||||||
-
|
|
||||||
- /* Read and init IRQ */
|
|
||||||
- irq = platform_get_irq(pdev, 0);
|
|
||||||
- if (irq < 0) {
|
|
||||||
- dev_err(&pdev->dev, "LPDDRC PMU get irq fail; irq:%d\n", irq);
|
|
||||||
- return irq;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_lpddrc_pmu_isr,
|
|
||||||
- IRQF_NOBALANCING | IRQF_NO_THREAD | IRQF_SHARED,
|
|
||||||
- dev_name(&pdev->dev), lpddrc_pmu);
|
|
||||||
- if (ret < 0) {
|
|
||||||
- dev_err(&pdev->dev,
|
|
||||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- lpddrc_pmu->irq = irq;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static const struct of_device_id lpddrc_of_match[] = {
|
|
||||||
- { .compatible = "hisilicon,lpddrc-pmu", },
|
|
||||||
- {},
|
|
||||||
-}
|
|
||||||
-MODULE_DEVICE_TABLE(of, lpddrc_of_match);
|
|
||||||
-
|
|
||||||
-static int hisi_lpddrc_pmu_init_data(struct platform_device *pdev,
|
|
||||||
- struct hisi_pmu *lpddrc_pmu)
|
|
||||||
-{
|
|
||||||
- struct resource *res;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Use the SCCL_ID and LPDDRC channel ID to identify the
|
|
||||||
- * LPDDRC PMU, while SCCL_ID is in MPIDR[aff2].
|
|
||||||
- */
|
|
||||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,ch-id",
|
|
||||||
- &lpddrc_pmu->index_id)) {
|
|
||||||
- dev_err(&pdev->dev, "Can not read lpddrc channel-id!\n");
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
|
||||||
- &lpddrc_pmu->sccl_id)) {
|
|
||||||
- dev_err(&pdev->dev, "Can not read lpddrc sccl-id!\n");
|
|
||||||
- return -EINVAL;
|
|
||||||
- }
|
|
||||||
- /* LPDDRC PMUs only share the same SCCL */
|
|
||||||
- lpddrc_pmu->ccl_id = -1;
|
|
||||||
-
|
|
||||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
||||||
- lpddrc_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
|
||||||
- if (IS_ERR(lpddrc_pmu->base)) {
|
|
||||||
- dev_err(&pdev->dev, "ioremap failed for lpddrc_pmu resource\n");
|
|
||||||
- return PTR_ERR(lpddrc_pmu->base);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static struct attribute *hisi_lpddrc_pmu_format_attr[] = {
|
|
||||||
- HISI_PMU_FORMAT_ATTR(event, "config:0-4"),
|
|
||||||
- NULL,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct attribute_group hisi_lpddrc_pmu_format_group = {
|
|
||||||
- .name = "format",
|
|
||||||
- .attrs = hisi_lpddrc_pmu_format_attr,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static struct attribute *hisi_lpddrc_pmu_events_attr[] = {
|
|
||||||
- HISI_PMU_EVENT_ATTR(flux_wr, 0x00),
|
|
||||||
- HISI_PMU_EVENT_ATTR(flux_rd, 0x01),
|
|
||||||
- HISI_PMU_EVENT_ATTR(flux_wcmd, 0x02),
|
|
||||||
- HISI_PMU_EVENT_ATTR(flux_rcmd, 0x03),
|
|
||||||
- HISI_PMU_EVENT_ATTR(pre_cmd, 0x04),
|
|
||||||
- HISI_PMU_EVENT_ATTR(act_cmd, 0x05),
|
|
||||||
- HISI_PMU_EVENT_ATTR(rnk_chg, 0x06),
|
|
||||||
- HISI_PMU_EVENT_ATTR(rw_chg, 0x07),
|
|
||||||
- NULL,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct attribute_group hisi_lpddrc_pmu_events_group = {
|
|
||||||
- .name = "events",
|
|
||||||
- .attrs = hisi_lpddrc_pmu_events_attr,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
-
|
|
||||||
-static struct attribute *hisi_lpddrc_pmu_cpumask_attrs[] = {
|
|
||||||
- &dev_attr_cpumask.attr,
|
|
||||||
- NULL,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct attribute_group hisi_lpddrc_pmu_cpumask_attr_group = {
|
|
||||||
- .attrs = hisi_lpddrc_pmu_cpumask_attrs,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct attribute_group *hisi_lpddrc_pmu_attr_groups[] = {
|
|
||||||
- &hisi_lpddrc_pmu_format_group,
|
|
||||||
- &hisi_lpddrc_pmu_events_group,
|
|
||||||
- &hisi_lpddrc_pmu_cpumask_attr_group,
|
|
||||||
- NULL,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static const struct hisi_uncore_ops hisi_uncore_lpddrc_ops = {
|
|
||||||
- .write_evtype = hisi_lpddrc_pmu_write_evtype,
|
|
||||||
- .get_event_idx = hisi_lpddrc_pmu_get_event_idx,
|
|
||||||
- .start_counters = hisi_lpddrc_pmu_start_counters,
|
|
||||||
- .stop_counters = hisi_lpddrc_pmu_stop_counters,
|
|
||||||
- .enable_counter = hisi_lpddrc_pmu_enable_counter,
|
|
||||||
- .disable_counter = hisi_lpddrc_pmu_disable_counter,
|
|
||||||
- .enable_counter_int = hisi_lpddrc_pmu_enable_counter_int,
|
|
||||||
- .disable_counter_int = hisi_lpddrc_pmu_disable_counter_int,
|
|
||||||
- .write_counter = hisi_lpddrc_pmu_write_counter,
|
|
||||||
- .read_counter = hisi_lpddrc_pmu_read_counter,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static int hisi_lpddrc_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
- struct hisi_pmu *lpddrc_pmu)
|
|
||||||
-{
|
|
||||||
- int ret;
|
|
||||||
-
|
|
||||||
- ret = hisi_lpddrc_pmu_init_data(pdev, lpddrc_pmu);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
-
|
|
||||||
- ret = hisi_lpddrc_pmu_init_irq(lpddrc_pmu, pdev);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
-
|
|
||||||
- lpddrc_pmu->num_counters = LPDDRC_NR_COUNTERS;
|
|
||||||
- lpddrc_pmu->counter_bits = 32;
|
|
||||||
- lpddrc_pmu->ops = &hisi_uncore_lpddrc_ops;
|
|
||||||
- lpddrc_pmu->dev = &pdev->dev;
|
|
||||||
- lpddrc_pmu->on_cpu = -1;
|
|
||||||
- lpddrc_pmu->check_event = 7;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int hisi_lpddrc_pmu_probe(struct platform_device *pdev)
|
|
||||||
-{
|
|
||||||
- struct hisi_pmu *lpddrc_pmu;
|
|
||||||
- char *name;
|
|
||||||
- int ret;
|
|
||||||
-
|
|
||||||
- lpddrc_pmu = devm_kzalloc(&pdev->dev, sizeof(*lpddrc_pmu), GFP_KERNEL);
|
|
||||||
- if (!lpddrc_pmu)
|
|
||||||
- return -ENOMEM;
|
|
||||||
-
|
|
||||||
- platform_set_drvdata(pdev, lpddrc_pmu);
|
|
||||||
-
|
|
||||||
- ret = hisi_lpddrc_pmu_dev_probe(pdev, lpddrc_pmu);
|
|
||||||
- if (ret)
|
|
||||||
- return ret;
|
|
||||||
-
|
|
||||||
- name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_lpddrc%u",
|
|
||||||
- lpddrc_pmu->sccl_id, lpddrc_pmu->index_id);
|
|
||||||
- HISI_INIT_PMU(&lpddrc_pmu->pmu, name, hisi_lpddrc_pmu_attr_groups);
|
|
||||||
- ret = perf_pmu_register(&lpddrc_pmu->pmu, name, -1);
|
|
||||||
- if (ret) {
|
|
||||||
- dev_err(lpddrc_pmu->dev, "LPDDRC PMU register failed!\n");
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- /* Pick one core to use for cpumask attributes */
|
|
||||||
- cpumask_set_cpu(smp_processor_id(), &lpddrc_pmu->associated_cpus);
|
|
||||||
-
|
|
||||||
- lpddrc_pmu->on_cpu = cpumask_first(&lpddrc_pmu->associated_cpus);
|
|
||||||
- if (lpddrc_pmu->on_cpu >= nr_cpu_ids)
|
|
||||||
- return -EINVAL;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static int hisi_lpddrc_pmu_remove(struct platform_device *pdev)
|
|
||||||
-{
|
|
||||||
- struct hisi_pmu *lpddrc_pmu = platform_get_drvdata(pdev);
|
|
||||||
-
|
|
||||||
- perf_pmu_unregister(&lpddrc_pmu->pmu);
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
-static struct platform_driver hisi_lpddrc_pmu_driver = {
|
|
||||||
- .driver = {
|
|
||||||
- .name = "hisi_lpddrc_pmu",
|
|
||||||
- .of_match_table = lpddrc_of_match,
|
|
||||||
- },
|
|
||||||
- .probe = hisi_lpddrc_pmu_probe,
|
|
||||||
- .remove = hisi_lpddrc_pmu_remove,
|
|
||||||
-};
|
|
||||||
-
|
|
||||||
-static int __init hisi_lpddrc_pmu_module_init(void)
|
|
||||||
-{
|
|
||||||
- return platform_driver_register(&hisi_lpddrc_pmu_driver);
|
|
||||||
-}
|
|
||||||
-module_init(hisi_lpddrc_pmu_module_init);
|
|
||||||
-
|
|
||||||
-static void __exit hisi_lpddrc_pmu_module_exit(void)
|
|
||||||
-{
|
|
||||||
- platform_driver_unregister(&hisi_lpddrc_pmu_driver);
|
|
||||||
-}
|
|
||||||
-module_exit(hisi_lpddrc_pmu_module_exit);
|
|
||||||
-
|
|
||||||
-MODULE_DESCRIPTION("HiSilicon SoC LPDDRC uncore PMU driver");
|
|
||||||
-MODULE_LICENSE("GPL v2");
|
|
||||||
-MODULE_AUTHOR("Fang Lijun <fanglijun3@huawei.com>");
|
|
||||||
-MODULE_AUTHOR("HUAWEI TECHNOLOGIES CO., LTD.");
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,142 +0,0 @@
|
|||||||
From 368cbff964ef136c493a3f06b88ff7e35454073d Mon Sep 17 00:00:00 2001
|
|
||||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
Date: Wed, 25 Oct 2023 15:21:52 +0800
|
|
||||||
Subject: [PATCH 04/55] Revert "perf: hisi: Add support for HiSilicon SoC PMU
|
|
||||||
driver dt probe"
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
|
|
||||||
This reverts commit 31067ca7ca856eee32857bdc618e89d3b9a3261a.
|
|
||||||
|
|
||||||
In newer version of PMU drivers that we will inclusion them later,
|
|
||||||
the acpi_evaluate_integer was removed, so this problem is gone.
|
|
||||||
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/perf/Kconfig
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 -
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 23 ++++---------------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 20 +++-------------
|
|
||||||
3 files changed, 7 insertions(+), 37 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index 8d1c48bc9812..f2a144ba3724 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -17,7 +17,6 @@
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
-#include <linux/of.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index 52286739c8b9..540f664463a8 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -17,7 +17,6 @@
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
-#include <linux/of.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
|
|
||||||
@@ -236,34 +235,20 @@ static const struct acpi_device_id hisi_hha_pmu_acpi_match[] = {
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(acpi, hisi_hha_pmu_acpi_match);
|
|
||||||
|
|
||||||
-#ifdef CONFIG_ACPI
|
|
||||||
-static int hisi_hha_pmu_init_index(struct platform_device *pdev,
|
|
||||||
+static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|
||||||
struct hisi_pmu *hha_pmu)
|
|
||||||
{
|
|
||||||
- acpi_status status;
|
|
||||||
unsigned long long id;
|
|
||||||
+ struct resource *res;
|
|
||||||
+ acpi_status status;
|
|
||||||
|
|
||||||
status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
|
||||||
- "_UID", NULL, &id);
|
|
||||||
+ "_UID", NULL, &id);
|
|
||||||
if (ACPI_FAILURE(status))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
hha_pmu->index_id = id;
|
|
||||||
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
-static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|
||||||
- struct hisi_pmu *hha_pmu)
|
|
||||||
-{
|
|
||||||
- struct resource *res;
|
|
||||||
-
|
|
||||||
-#ifdef CONFIG_ACPI
|
|
||||||
- if (hisi_hha_pmu_init_index(pdev, hha_pmu))
|
|
||||||
- dev_info(&pdev->dev, "Can not init index id by acpi!\n");
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Use SCCL_ID and UID to identify the HHA PMU, while
|
|
||||||
* SCCL_ID is in MPIDR[aff2].
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index 0e766cea4a11..117edd114445 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -17,7 +17,6 @@
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
-#include <linux/of.h>
|
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
|
|
||||||
@@ -235,33 +234,20 @@ static const struct acpi_device_id hisi_l3c_pmu_acpi_match[] = {
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(acpi, hisi_l3c_pmu_acpi_match);
|
|
||||||
|
|
||||||
-#ifdef CONFIG_ACPI
|
|
||||||
-static int hisi_l3c_pmu_init_index(struct platform_device *pdev,
|
|
||||||
+static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
|
||||||
struct hisi_pmu *l3c_pmu)
|
|
||||||
{
|
|
||||||
unsigned long long id;
|
|
||||||
+ struct resource *res;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
|
||||||
- "_UID", NULL, &id);
|
|
||||||
+ "_UID", NULL, &id);
|
|
||||||
if (ACPI_FAILURE(status))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
l3c_pmu->index_id = id;
|
|
||||||
|
|
||||||
- return 0;
|
|
||||||
-}
|
|
||||||
-#endif
|
|
||||||
-
|
|
||||||
-static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
|
||||||
- struct hisi_pmu *l3c_pmu)
|
|
||||||
-{
|
|
||||||
- struct resource *res;
|
|
||||||
-
|
|
||||||
-#ifdef CONFIG_ACPI
|
|
||||||
- if (hisi_l3c_pmu_init_index(pdev, l3c_pmu))
|
|
||||||
- dev_info(&pdev->dev, "Can not init index id by acpi!");
|
|
||||||
-#endif
|
|
||||||
/*
|
|
||||||
* Use the SCCL_ID and CCL_ID to identify the L3C PMU, while
|
|
||||||
* SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
From 05df62b6b7f9e92e9f25b8a0bcd5c99c4ae02165 Mon Sep 17 00:00:00 2001
|
|
||||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
Date: Wed, 25 Oct 2023 15:26:10 +0800
|
|
||||||
Subject: [PATCH 05/55] Revert "drivers/perf: Fix kernel panic when rmmod PMU
|
|
||||||
modules during perf sampling"
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
--------------------------------------------------------------
|
|
||||||
|
|
||||||
This reverts commit 525a3927062f89be41f1b23ae33ad0638c13bf8e.
|
|
||||||
|
|
||||||
revert it, and inclusion the upstream version later.
|
|
||||||
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 1 -
|
|
||||||
1 file changed, 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
index 129896662cf2..8445ee581e46 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
@@ -105,7 +105,6 @@ static inline void HISI_INIT_PMU(struct pmu *pmu, const char *name,
|
|
||||||
const struct attribute_group **attr_groups)
|
|
||||||
{
|
|
||||||
pmu->name = name;
|
|
||||||
- pmu->module = THIS_MODULE;
|
|
||||||
pmu->task_ctx_nr = perf_invalid_context;
|
|
||||||
pmu->event_init = hisi_uncore_pmu_event_init;
|
|
||||||
pmu->pmu_enable = hisi_uncore_pmu_enable;
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,129 +0,0 @@
|
|||||||
From 41ea05f9ac69e7cbae775862e5c3e0dad2e1e4ca Mon Sep 17 00:00:00 2001
|
|
||||||
From: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
Date: Wed, 25 Oct 2023 15:26:31 +0800
|
|
||||||
Subject: [PATCH 06/55] Revert "perf: hisi: remove duplicated code"
|
|
||||||
|
|
||||||
driver inclusion
|
|
||||||
category: cleanup
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
----------------------------------------------------------
|
|
||||||
|
|
||||||
This reverts commit de1ea4e7f5209c7f84965c38bf37287c11db02dc.
|
|
||||||
|
|
||||||
revert it, and inclusion the newer version of commit c38992d67c15(perf: hisi: Extract hisi_pmu_init) later.
|
|
||||||
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 15 ++++++++++++++-
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 15 ++++++++++++++-
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 14 +++++++++++++-
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 17 -----------------
|
|
||||||
4 files changed, 41 insertions(+), 20 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index f2a144ba3724..b3488ae1f2b8 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -384,7 +384,20 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
|
||||||
|
|
||||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_ddrc%u",
|
|
||||||
ddrc_pmu->sccl_id, ddrc_pmu->index_id);
|
|
||||||
- HISI_INIT_PMU(&ddrc_pmu->pmu, name, hisi_ddrc_pmu_attr_groups);
|
|
||||||
+ ddrc_pmu->pmu = (struct pmu) {
|
|
||||||
+ .name = name,
|
|
||||||
+ .task_ctx_nr = perf_invalid_context,
|
|
||||||
+ .event_init = hisi_uncore_pmu_event_init,
|
|
||||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
|
||||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
|
||||||
+ .add = hisi_uncore_pmu_add,
|
|
||||||
+ .del = hisi_uncore_pmu_del,
|
|
||||||
+ .start = hisi_uncore_pmu_start,
|
|
||||||
+ .stop = hisi_uncore_pmu_stop,
|
|
||||||
+ .read = hisi_uncore_pmu_read,
|
|
||||||
+ .attr_groups = hisi_ddrc_pmu_attr_groups,
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(ddrc_pmu->dev, "DDRC PMU register failed!\n");
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index 540f664463a8..f0215d50d84d 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -395,7 +395,20 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
|
||||||
|
|
||||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_hha%u",
|
|
||||||
hha_pmu->sccl_id, hha_pmu->index_id);
|
|
||||||
- HISI_INIT_PMU(&hha_pmu->pmu, name, hisi_hha_pmu_attr_groups);
|
|
||||||
+ hha_pmu->pmu = (struct pmu) {
|
|
||||||
+ .name = name,
|
|
||||||
+ .task_ctx_nr = perf_invalid_context,
|
|
||||||
+ .event_init = hisi_uncore_pmu_event_init,
|
|
||||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
|
||||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
|
||||||
+ .add = hisi_uncore_pmu_add,
|
|
||||||
+ .del = hisi_uncore_pmu_del,
|
|
||||||
+ .start = hisi_uncore_pmu_start,
|
|
||||||
+ .stop = hisi_uncore_pmu_stop,
|
|
||||||
+ .read = hisi_uncore_pmu_read,
|
|
||||||
+ .attr_groups = hisi_hha_pmu_attr_groups,
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(hha_pmu->dev, "HHA PMU register failed!\n");
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index 117edd114445..11563e29d983 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -385,7 +385,19 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
|
||||||
|
|
||||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
|
|
||||||
l3c_pmu->sccl_id, l3c_pmu->index_id);
|
|
||||||
- HISI_INIT_PMU(&l3c_pmu->pmu, name, hisi_l3c_pmu_attr_groups);
|
|
||||||
+ l3c_pmu->pmu = (struct pmu) {
|
|
||||||
+ .name = name,
|
|
||||||
+ .task_ctx_nr = perf_invalid_context,
|
|
||||||
+ .event_init = hisi_uncore_pmu_event_init,
|
|
||||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
|
||||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
|
||||||
+ .add = hisi_uncore_pmu_add,
|
|
||||||
+ .del = hisi_uncore_pmu_del,
|
|
||||||
+ .start = hisi_uncore_pmu_start,
|
|
||||||
+ .stop = hisi_uncore_pmu_stop,
|
|
||||||
+ .read = hisi_uncore_pmu_read,
|
|
||||||
+ .attr_groups = hisi_l3c_pmu_attr_groups,
|
|
||||||
+ };
|
|
||||||
|
|
||||||
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
|
|
||||||
if (ret) {
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
index 8445ee581e46..8f2f2fc5dde4 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
@@ -100,21 +100,4 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
|
|
||||||
struct device_attribute *attr, char *buf);
|
|
||||||
int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node);
|
|
||||||
int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node);
|
|
||||||
-
|
|
||||||
-static inline void HISI_INIT_PMU(struct pmu *pmu, const char *name,
|
|
||||||
- const struct attribute_group **attr_groups)
|
|
||||||
-{
|
|
||||||
- pmu->name = name;
|
|
||||||
- pmu->task_ctx_nr = perf_invalid_context;
|
|
||||||
- pmu->event_init = hisi_uncore_pmu_event_init;
|
|
||||||
- pmu->pmu_enable = hisi_uncore_pmu_enable;
|
|
||||||
- pmu->pmu_disable = hisi_uncore_pmu_disable;
|
|
||||||
- pmu->add = hisi_uncore_pmu_add;
|
|
||||||
- pmu->del = hisi_uncore_pmu_del;
|
|
||||||
- pmu->start = hisi_uncore_pmu_start;
|
|
||||||
- pmu->stop = hisi_uncore_pmu_stop;
|
|
||||||
- pmu->read = hisi_uncore_pmu_read;
|
|
||||||
- pmu->attr_groups = attr_groups;
|
|
||||||
-}
|
|
||||||
-
|
|
||||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,315 +0,0 @@
|
|||||||
From 926642e8644c860c77141b8251767e1485c6427c Mon Sep 17 00:00:00 2001
|
|
||||||
From: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
||||||
Date: Thu, 18 Apr 2019 17:35:40 -0300
|
|
||||||
Subject: [PATCH 07/55] docs: perf: convert to ReST
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.3-rc1
|
|
||||||
commit 6baec31591cee0f2f6d446abb81c828499a6ed23
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6baec31591cee0f2f6d446abb81c828499a6ed23
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
Rename the perf documentation files to ReST, add an
|
|
||||||
index for them and adjust in order to produce a nice html
|
|
||||||
output via the Sphinx build system.
|
|
||||||
|
|
||||||
At its new index.rst, let's add a :orphan: while this is not linked to
|
|
||||||
the main index.rst file, in order to avoid build warnings.
|
|
||||||
|
|
||||||
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
.../perf/{arm-ccn.txt => arm-ccn.rst} | 18 +++++----
|
|
||||||
.../perf/{arm_dsu_pmu.txt => arm_dsu_pmu.rst} | 5 ++-
|
|
||||||
.../perf/{hisi-pmu.txt => hisi-pmu.rst} | 37 +++++++++++--------
|
|
||||||
Documentation/perf/index.rst | 16 ++++++++
|
|
||||||
.../perf/{qcom_l2_pmu.txt => qcom_l2_pmu.rst} | 3 +-
|
|
||||||
.../perf/{qcom_l3_pmu.txt => qcom_l3_pmu.rst} | 3 +-
|
|
||||||
.../perf/{xgene-pmu.txt => xgene-pmu.rst} | 3 +-
|
|
||||||
MAINTAINERS | 4 +-
|
|
||||||
drivers/perf/qcom_l3_pmu.c | 2 +-
|
|
||||||
9 files changed, 60 insertions(+), 31 deletions(-)
|
|
||||||
rename Documentation/perf/{arm-ccn.txt => arm-ccn.rst} (86%)
|
|
||||||
rename Documentation/perf/{arm_dsu_pmu.txt => arm_dsu_pmu.rst} (92%)
|
|
||||||
rename Documentation/perf/{hisi-pmu.txt => hisi-pmu.rst} (73%)
|
|
||||||
create mode 100644 Documentation/perf/index.rst
|
|
||||||
rename Documentation/perf/{qcom_l2_pmu.txt => qcom_l2_pmu.rst} (94%)
|
|
||||||
rename Documentation/perf/{qcom_l3_pmu.txt => qcom_l3_pmu.rst} (93%)
|
|
||||||
rename Documentation/perf/{xgene-pmu.txt => xgene-pmu.rst} (96%)
|
|
||||||
|
|
||||||
diff --git a/Documentation/perf/arm-ccn.txt b/Documentation/perf/arm-ccn.rst
|
|
||||||
similarity index 86%
|
|
||||||
rename from Documentation/perf/arm-ccn.txt
|
|
||||||
rename to Documentation/perf/arm-ccn.rst
|
|
||||||
index 15cdb7bc57c3..832b0c64023a 100644
|
|
||||||
--- a/Documentation/perf/arm-ccn.txt
|
|
||||||
+++ b/Documentation/perf/arm-ccn.rst
|
|
||||||
@@ -1,3 +1,4 @@
|
|
||||||
+==========================
|
|
||||||
ARM Cache Coherent Network
|
|
||||||
==========================
|
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ Crosspoint watchpoint-based events (special "event" value 0xfe)
|
|
||||||
require "xp" and "vc" as as above plus "port" (device port index),
|
|
||||||
"dir" (transmit/receive direction), comparator values ("cmp_l"
|
|
||||||
and "cmp_h") and "mask", being index of the comparator mask.
|
|
||||||
+
|
|
||||||
Masks are defined separately from the event description
|
|
||||||
(due to limited number of the config values) in the "cmp_mask"
|
|
||||||
directory, with first 8 configurable by user and additional
|
|
||||||
@@ -44,16 +46,16 @@ request the events on this processor (if not, the perf_event->cpu value
|
|
||||||
will be overwritten anyway). In case of this processor being offlined,
|
|
||||||
the events are migrated to another one and the attribute is updated.
|
|
||||||
|
|
||||||
-Example of perf tool use:
|
|
||||||
+Example of perf tool use::
|
|
||||||
|
|
||||||
-/ # perf list | grep ccn
|
|
||||||
- ccn/cycles/ [Kernel PMU event]
|
|
||||||
-<...>
|
|
||||||
- ccn/xp_valid_flit,xp=?,port=?,vc=?,dir=?/ [Kernel PMU event]
|
|
||||||
-<...>
|
|
||||||
+ / # perf list | grep ccn
|
|
||||||
+ ccn/cycles/ [Kernel PMU event]
|
|
||||||
+ <...>
|
|
||||||
+ ccn/xp_valid_flit,xp=?,port=?,vc=?,dir=?/ [Kernel PMU event]
|
|
||||||
+ <...>
|
|
||||||
|
|
||||||
-/ # perf stat -a -e ccn/cycles/,ccn/xp_valid_flit,xp=1,port=0,vc=1,dir=1/ \
|
|
||||||
- sleep 1
|
|
||||||
+ / # perf stat -a -e ccn/cycles/,ccn/xp_valid_flit,xp=1,port=0,vc=1,dir=1/ \
|
|
||||||
+ sleep 1
|
|
||||||
|
|
||||||
The driver does not support sampling, therefore "perf record" will
|
|
||||||
not work. Per-task (without "-a") perf sessions are not supported.
|
|
||||||
diff --git a/Documentation/perf/arm_dsu_pmu.txt b/Documentation/perf/arm_dsu_pmu.rst
|
|
||||||
similarity index 92%
|
|
||||||
rename from Documentation/perf/arm_dsu_pmu.txt
|
|
||||||
rename to Documentation/perf/arm_dsu_pmu.rst
|
|
||||||
index d611e15f5add..7fd34db75d13 100644
|
|
||||||
--- a/Documentation/perf/arm_dsu_pmu.txt
|
|
||||||
+++ b/Documentation/perf/arm_dsu_pmu.rst
|
|
||||||
@@ -1,3 +1,4 @@
|
|
||||||
+==================================
|
|
||||||
ARM DynamIQ Shared Unit (DSU) PMU
|
|
||||||
==================================
|
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ PMU doesn't support process specific events and cannot be used in sampling mode.
|
|
||||||
The DSU provides a bitmap for a subset of implemented events via hardware
|
|
||||||
registers. There is no way for the driver to determine if the other events
|
|
||||||
are available or not. Hence the driver exposes only those events advertised
|
|
||||||
-by the DSU, in "events" directory under :
|
|
||||||
+by the DSU, in "events" directory under::
|
|
||||||
|
|
||||||
/sys/bus/event_sources/devices/arm_dsu_<N>/
|
|
||||||
|
|
||||||
@@ -23,6 +24,6 @@ and use the raw event code for the unlisted events.
|
|
||||||
The driver also exposes the CPUs connected to the DSU instance in "associated_cpus".
|
|
||||||
|
|
||||||
|
|
||||||
-e.g usage :
|
|
||||||
+e.g usage::
|
|
||||||
|
|
||||||
perf stat -a -e arm_dsu_0/cycles/
|
|
||||||
diff --git a/Documentation/perf/hisi-pmu.txt b/Documentation/perf/hisi-pmu.rst
|
|
||||||
similarity index 73%
|
|
||||||
rename from Documentation/perf/hisi-pmu.txt
|
|
||||||
rename to Documentation/perf/hisi-pmu.rst
|
|
||||||
index 267a028b2741..404a5c3d9d00 100644
|
|
||||||
--- a/Documentation/perf/hisi-pmu.txt
|
|
||||||
+++ b/Documentation/perf/hisi-pmu.rst
|
|
||||||
@@ -1,5 +1,7 @@
|
|
||||||
+======================================================
|
|
||||||
HiSilicon SoC uncore Performance Monitoring Unit (PMU)
|
|
||||||
======================================================
|
|
||||||
+
|
|
||||||
The HiSilicon SoC chip includes various independent system device PMUs
|
|
||||||
such as L3 cache (L3C), Hydra Home Agent (HHA) and DDRC. These PMUs are
|
|
||||||
independent and have hardware logic to gather statistics and performance
|
|
||||||
@@ -11,11 +13,13 @@ called Super CPU cluster (SCCL) and is made up of 6 CCLs. Each SCCL has
|
|
||||||
two HHAs (0 - 1) and four DDRCs (0 - 3), respectively.
|
|
||||||
|
|
||||||
HiSilicon SoC uncore PMU driver
|
|
||||||
----------------------------------------
|
|
||||||
+-------------------------------
|
|
||||||
+
|
|
||||||
Each device PMU has separate registers for event counting, control and
|
|
||||||
interrupt, and the PMU driver shall register perf PMU drivers like L3C,
|
|
||||||
HHA and DDRC etc. The available events and configuration options shall
|
|
||||||
-be described in the sysfs, see :
|
|
||||||
+be described in the sysfs, see:
|
|
||||||
+
|
|
||||||
/sys/devices/hisi_sccl{X}_<l3c{Y}/hha{Y}/ddrc{Y}>/, or
|
|
||||||
/sys/bus/event_source/devices/hisi_sccl{X}_<l3c{Y}/hha{Y}/ddrc{Y}>.
|
|
||||||
The "perf list" command shall list the available events from sysfs.
|
|
||||||
@@ -24,27 +28,30 @@ Each L3C, HHA and DDRC is registered as a separate PMU with perf. The PMU
|
|
||||||
name will appear in event listing as hisi_sccl<sccl-id>_module<index-id>.
|
|
||||||
where "sccl-id" is the identifier of the SCCL and "index-id" is the index of
|
|
||||||
module.
|
|
||||||
+
|
|
||||||
e.g. hisi_sccl3_l3c0/rd_hit_cpipe is READ_HIT_CPIPE event of L3C index #0 in
|
|
||||||
SCCL ID #3.
|
|
||||||
+
|
|
||||||
e.g. hisi_sccl1_hha0/rx_operations is RX_OPERATIONS event of HHA index #0 in
|
|
||||||
SCCL ID #1.
|
|
||||||
|
|
||||||
The driver also provides a "cpumask" sysfs attribute, which shows the CPU core
|
|
||||||
ID used to count the uncore PMU event.
|
|
||||||
|
|
||||||
-Example usage of perf:
|
|
||||||
-$# perf list
|
|
||||||
-hisi_sccl3_l3c0/rd_hit_cpipe/ [kernel PMU event]
|
|
||||||
-------------------------------------------
|
|
||||||
-hisi_sccl3_l3c0/wr_hit_cpipe/ [kernel PMU event]
|
|
||||||
-------------------------------------------
|
|
||||||
-hisi_sccl1_l3c0/rd_hit_cpipe/ [kernel PMU event]
|
|
||||||
-------------------------------------------
|
|
||||||
-hisi_sccl1_l3c0/wr_hit_cpipe/ [kernel PMU event]
|
|
||||||
-------------------------------------------
|
|
||||||
-
|
|
||||||
-$# perf stat -a -e hisi_sccl3_l3c0/rd_hit_cpipe/ sleep 5
|
|
||||||
-$# perf stat -a -e hisi_sccl3_l3c0/config=0x02/ sleep 5
|
|
||||||
+Example usage of perf::
|
|
||||||
+
|
|
||||||
+ $# perf list
|
|
||||||
+ hisi_sccl3_l3c0/rd_hit_cpipe/ [kernel PMU event]
|
|
||||||
+ ------------------------------------------
|
|
||||||
+ hisi_sccl3_l3c0/wr_hit_cpipe/ [kernel PMU event]
|
|
||||||
+ ------------------------------------------
|
|
||||||
+ hisi_sccl1_l3c0/rd_hit_cpipe/ [kernel PMU event]
|
|
||||||
+ ------------------------------------------
|
|
||||||
+ hisi_sccl1_l3c0/wr_hit_cpipe/ [kernel PMU event]
|
|
||||||
+ ------------------------------------------
|
|
||||||
+
|
|
||||||
+ $# perf stat -a -e hisi_sccl3_l3c0/rd_hit_cpipe/ sleep 5
|
|
||||||
+ $# perf stat -a -e hisi_sccl3_l3c0/config=0x02/ sleep 5
|
|
||||||
|
|
||||||
The current driver does not support sampling. So "perf record" is unsupported.
|
|
||||||
Also attach to a task is unsupported as the events are all uncore.
|
|
||||||
diff --git a/Documentation/perf/index.rst b/Documentation/perf/index.rst
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..4bf848e27f26
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/Documentation/perf/index.rst
|
|
||||||
@@ -0,0 +1,16 @@
|
|
||||||
+:orphan:
|
|
||||||
+
|
|
||||||
+===========================
|
|
||||||
+Performance monitor support
|
|
||||||
+===========================
|
|
||||||
+
|
|
||||||
+.. toctree::
|
|
||||||
+ :maxdepth: 1
|
|
||||||
+
|
|
||||||
+ hisi-pmu
|
|
||||||
+ qcom_l2_pmu
|
|
||||||
+ qcom_l3_pmu
|
|
||||||
+ arm-ccn
|
|
||||||
+ xgene-pmu
|
|
||||||
+ arm_dsu_pmu
|
|
||||||
+ thunderx2-pmu
|
|
||||||
diff --git a/Documentation/perf/qcom_l2_pmu.txt b/Documentation/perf/qcom_l2_pmu.rst
|
|
||||||
similarity index 94%
|
|
||||||
rename from Documentation/perf/qcom_l2_pmu.txt
|
|
||||||
rename to Documentation/perf/qcom_l2_pmu.rst
|
|
||||||
index b25b97659ab9..c130178a4a55 100644
|
|
||||||
--- a/Documentation/perf/qcom_l2_pmu.txt
|
|
||||||
+++ b/Documentation/perf/qcom_l2_pmu.rst
|
|
||||||
@@ -1,3 +1,4 @@
|
|
||||||
+=====================================================================
|
|
||||||
Qualcomm Technologies Level-2 Cache Performance Monitoring Unit (PMU)
|
|
||||||
=====================================================================
|
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ The driver provides a "cpumask" sysfs attribute which contains a mask
|
|
||||||
consisting of one CPU per cluster which will be used to handle all the PMU
|
|
||||||
events on that cluster.
|
|
||||||
|
|
||||||
-Examples for use with perf:
|
|
||||||
+Examples for use with perf::
|
|
||||||
|
|
||||||
perf stat -e l2cache_0/config=0x001/,l2cache_0/config=0x042/ -a sleep 1
|
|
||||||
|
|
||||||
diff --git a/Documentation/perf/qcom_l3_pmu.txt b/Documentation/perf/qcom_l3_pmu.rst
|
|
||||||
similarity index 93%
|
|
||||||
rename from Documentation/perf/qcom_l3_pmu.txt
|
|
||||||
rename to Documentation/perf/qcom_l3_pmu.rst
|
|
||||||
index 96b3a9444a0d..a3d014a46bfd 100644
|
|
||||||
--- a/Documentation/perf/qcom_l3_pmu.txt
|
|
||||||
+++ b/Documentation/perf/qcom_l3_pmu.rst
|
|
||||||
@@ -1,3 +1,4 @@
|
|
||||||
+===========================================================================
|
|
||||||
Qualcomm Datacenter Technologies L3 Cache Performance Monitoring Unit (PMU)
|
|
||||||
===========================================================================
|
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ The hardware implements 32bit event counters and has a flat 8bit event space
|
|
||||||
exposed via the "event" format attribute. In addition to the 32bit physical
|
|
||||||
counters the driver supports virtual 64bit hardware counters by using hardware
|
|
||||||
counter chaining. This feature is exposed via the "lc" (long counter) format
|
|
||||||
-flag. E.g.:
|
|
||||||
+flag. E.g.::
|
|
||||||
|
|
||||||
perf stat -e l3cache_0_0/read-miss,lc/
|
|
||||||
|
|
||||||
diff --git a/Documentation/perf/xgene-pmu.txt b/Documentation/perf/xgene-pmu.rst
|
|
||||||
similarity index 96%
|
|
||||||
rename from Documentation/perf/xgene-pmu.txt
|
|
||||||
rename to Documentation/perf/xgene-pmu.rst
|
|
||||||
index d7cff4454e5b..644f8ed89152 100644
|
|
||||||
--- a/Documentation/perf/xgene-pmu.txt
|
|
||||||
+++ b/Documentation/perf/xgene-pmu.rst
|
|
||||||
@@ -1,3 +1,4 @@
|
|
||||||
+================================================
|
|
||||||
APM X-Gene SoC Performance Monitoring Unit (PMU)
|
|
||||||
================================================
|
|
||||||
|
|
||||||
@@ -33,7 +34,7 @@ each PMU, please refer to APM X-Gene User Manual.
|
|
||||||
Each perf driver also provides a "cpumask" sysfs attribute, which contains a
|
|
||||||
single CPU ID of the processor which will be used to handle all the PMU events.
|
|
||||||
|
|
||||||
-Example for perf tool use:
|
|
||||||
+Example for perf tool use::
|
|
||||||
|
|
||||||
/ # perf list | grep -e l3c -e iob -e mcb -e mc
|
|
||||||
l3c0/ackq-full/ [Kernel PMU event]
|
|
||||||
diff --git a/MAINTAINERS b/MAINTAINERS
|
|
||||||
index 5d0b782c973c..0b2a68401b0e 100644
|
|
||||||
--- a/MAINTAINERS
|
|
||||||
+++ b/MAINTAINERS
|
|
||||||
@@ -1040,7 +1040,7 @@ APPLIED MICRO (APM) X-GENE SOC PMU
|
|
||||||
M: Tai Nguyen <ttnguyen@apm.com>
|
|
||||||
S: Supported
|
|
||||||
F: drivers/perf/xgene_pmu.c
|
|
||||||
-F: Documentation/perf/xgene-pmu.txt
|
|
||||||
+F: Documentation/perf/xgene-pmu.rst
|
|
||||||
F: Documentation/devicetree/bindings/perf/apm-xgene-pmu.txt
|
|
||||||
|
|
||||||
APTINA CAMERA SENSOR PLL
|
|
||||||
@@ -6663,7 +6663,7 @@ M: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
W: http://www.hisilicon.com
|
|
||||||
S: Supported
|
|
||||||
F: drivers/perf/hisilicon
|
|
||||||
-F: Documentation/perf/hisi-pmu.txt
|
|
||||||
+F: Documentation/perf/hisi-pmu.rst
|
|
||||||
|
|
||||||
HISILICON PTT DRIVER
|
|
||||||
M: Yicong Yang <yangyicong@hisilicon.com>
|
|
||||||
diff --git a/drivers/perf/qcom_l3_pmu.c b/drivers/perf/qcom_l3_pmu.c
|
|
||||||
index b349e7bf4dd9..cc88dc92577e 100644
|
|
||||||
--- a/drivers/perf/qcom_l3_pmu.c
|
|
||||||
+++ b/drivers/perf/qcom_l3_pmu.c
|
|
||||||
@@ -7,7 +7,7 @@
|
|
||||||
* the slices. User space needs to aggregate to individual counts to provide
|
|
||||||
* a global picture.
|
|
||||||
*
|
|
||||||
- * See Documentation/perf/qcom_l3_pmu.txt for more details.
|
|
||||||
+ * See Documentation/perf/qcom_l3_pmu.rst for more details.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
|
|
||||||
*
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
From 7901f6e0c3c188badd67a49ba546df8da2f0a123 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Date: Thu, 16 Jul 2020 17:19:25 +0800
|
|
||||||
Subject: [PATCH 08/55] drivers/perf: Fix kernel panic when rmmod PMU modules
|
|
||||||
during perf sampling
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.8-rc1
|
|
||||||
commit bdc5c744c7b6457d18a95c26769dad0e7f480a08
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=bdc5c744c7b6457d18a95c26769dad0e7f480a08
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
When users try to remove PMU modules during perf sampling, kernel panic
|
|
||||||
will happen because the pmu->read() is a NULL pointer here.
|
|
||||||
|
|
||||||
INFO on HiSilicon hip08 platform as follow:
|
|
||||||
pc : hisi_uncore_pmu_event_update+0x30/0xa4 [hisi_uncore_pmu]
|
|
||||||
lr : hisi_uncore_pmu_read+0x20/0x2c [hisi_uncore_pmu]
|
|
||||||
sp : ffff800010103e90
|
|
||||||
x29: ffff800010103e90 x28: ffff0027db0c0e40
|
|
||||||
x27: ffffa29a76f129d8 x26: ffffa29a77ceb000
|
|
||||||
x25: ffffa29a773a5000 x24: ffffa29a77392000
|
|
||||||
x23: ffffddffe5943f08 x22: ffff002784285960
|
|
||||||
x21: ffff002784285800 x20: ffff0027d2e76c80
|
|
||||||
x19: ffff0027842859e0 x18: ffff80003498bcc8
|
|
||||||
x17: ffffa29a76afe910 x16: ffffa29a7583f530
|
|
||||||
x15: 16151a1512061a1e x14: 0000000000000000
|
|
||||||
x13: ffffa29a76f1e238 x12: 0000000000000001
|
|
||||||
x11: 0000000000000400 x10: 00000000000009f0
|
|
||||||
x9 : ffff8000107b3e70 x8 : ffff0027db0c1890
|
|
||||||
x7 : ffffa29a773a7000 x6 : 00000007f5131013
|
|
||||||
x5 : 00000007f5131013 x4 : 09f257d417c00000
|
|
||||||
x3 : 00000002187bd7ce x2 : ffffa29a38f0f0d8
|
|
||||||
x1 : ffffa29a38eae268 x0 : ffff0027d2e76c80
|
|
||||||
Call trace:
|
|
||||||
hisi_uncore_pmu_event_update+0x30/0xa4 [hisi_uncore_pmu]
|
|
||||||
hisi_uncore_pmu_read+0x20/0x2c [hisi_uncore_pmu]
|
|
||||||
__perf_event_read+0x1a0/0x1f8
|
|
||||||
flush_smp_call_function_queue+0xa0/0x160
|
|
||||||
generic_smp_call_function_single_interrupt+0x18/0x20
|
|
||||||
handle_IPI+0x31c/0x4dc
|
|
||||||
gic_handle_irq+0x2c8/0x310
|
|
||||||
el1_irq+0xcc/0x180
|
|
||||||
arch_cpu_idle+0x4c/0x20c
|
|
||||||
default_idle_call+0x20/0x30
|
|
||||||
do_idle+0x1b4/0x270
|
|
||||||
cpu_startup_entry+0x28/0x30
|
|
||||||
secondary_start_kernel+0x1a4/0x1fc
|
|
||||||
|
|
||||||
To solve the above issue, current module should be registered to kernel,
|
|
||||||
so that try_module_get() can be invoked when perf sampling starts. This
|
|
||||||
adds the reference counting of module and could prevent users from removing
|
|
||||||
modules during sampling.
|
|
||||||
|
|
||||||
Reported-by: Haifeng Wang <wang.wanghaifeng@huawei.com>
|
|
||||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/1594891165-8228-1-git-send-email-liuqi115@huawei.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/perf/fsl_imx8_ddr_perf.c
|
|
||||||
drivers/perf/arm_smmuv3_pmu.c
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 +
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 1 +
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 1 +
|
|
||||||
3 files changed, 3 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index b3488ae1f2b8..620fa1345150 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -386,6 +386,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
|
||||||
ddrc_pmu->sccl_id, ddrc_pmu->index_id);
|
|
||||||
ddrc_pmu->pmu = (struct pmu) {
|
|
||||||
.name = name,
|
|
||||||
+ .module = THIS_MODULE,
|
|
||||||
.task_ctx_nr = perf_invalid_context,
|
|
||||||
.event_init = hisi_uncore_pmu_event_init,
|
|
||||||
.pmu_enable = hisi_uncore_pmu_enable,
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index f0215d50d84d..33a0da941be2 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -397,6 +397,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
|
||||||
hha_pmu->sccl_id, hha_pmu->index_id);
|
|
||||||
hha_pmu->pmu = (struct pmu) {
|
|
||||||
.name = name,
|
|
||||||
+ .module = THIS_MODULE,
|
|
||||||
.task_ctx_nr = perf_invalid_context,
|
|
||||||
.event_init = hisi_uncore_pmu_event_init,
|
|
||||||
.pmu_enable = hisi_uncore_pmu_enable,
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index 11563e29d983..92485f00dcc8 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -387,6 +387,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
|
||||||
l3c_pmu->sccl_id, l3c_pmu->index_id);
|
|
||||||
l3c_pmu->pmu = (struct pmu) {
|
|
||||||
.name = name,
|
|
||||||
+ .module = THIS_MODULE,
|
|
||||||
.task_ctx_nr = perf_invalid_context,
|
|
||||||
.event_init = hisi_uncore_pmu_event_init,
|
|
||||||
.pmu_enable = hisi_uncore_pmu_enable,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,194 +0,0 @@
|
|||||||
From 6d7245609c516aae8719e8d27b737337635ad8c3 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Andrew Murray <andrew.murray@arm.com>
|
|
||||||
Date: Thu, 10 Jan 2019 13:53:29 +0000
|
|
||||||
Subject: [PATCH 09/55] For drivers that do not support context exclusion let's
|
|
||||||
advertise the PERF_PMU_CAP_NO_EXCLUDE capability. This ensures that perf will
|
|
||||||
prevent us from handling events where any exclusion flags are set. Let's also
|
|
||||||
remove the now unnecessary check for exclusion flags.
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.1-rc1
|
|
||||||
commit 306563985819ed2af9df0a26ae368ed12cf28f41
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?=306563985819ed2af9df0a26ae368ed12cf28f41
|
|
||||||
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
|
|
||||||
Signed-off-by: Andrew Murray <andrew.murray@arm.com>
|
|
||||||
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
|
|
||||||
Acked-by: Will Deacon <will.deacon@arm.com>
|
|
||||||
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
|
|
||||||
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
|
||||||
Cc: Borislav Petkov <bp@alien8.de>
|
|
||||||
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
|
|
||||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Matt Turner <mattst88@gmail.com>
|
|
||||||
Cc: Michael Ellerman <mpe@ellerman.id.au>
|
|
||||||
Cc: Paul Mackerras <paulus@samba.org>
|
|
||||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
|
||||||
Cc: Richard Henderson <rth@twiddle.net>
|
|
||||||
Cc: Russell King <linux@armlinux.org.uk>
|
|
||||||
Cc: Sascha Hauer <s.hauer@pengutronix.de>
|
|
||||||
Cc: Shawn Guo <shawnguo@kernel.org>
|
|
||||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
|
||||||
Cc: linux-arm-kernel@lists.infradead.org
|
|
||||||
Cc: linuxppc-dev@lists.ozlabs.org
|
|
||||||
Cc: robin.murphy@arm.com
|
|
||||||
Cc: suzuki.poulose@arm.com
|
|
||||||
Link: https://lkml.kernel.org/r/1547128414-50693-8-git-send-email-andrew.murray@arm.com
|
|
||||||
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/perf/thunderx2_pmu.c
|
|
||||||
---
|
|
||||||
drivers/perf/arm-cci.c | 10 +---------
|
|
||||||
drivers/perf/arm-ccn.c | 6 ++----
|
|
||||||
drivers/perf/arm_dsu_pmu.c | 9 ++-------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 1 +
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 1 +
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 1 +
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 9 ---------
|
|
||||||
7 files changed, 8 insertions(+), 29 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/arm-cci.c b/drivers/perf/arm-cci.c
|
|
||||||
index 3bbc853dc12f..aca4570f78a8 100644
|
|
||||||
--- a/drivers/perf/arm-cci.c
|
|
||||||
+++ b/drivers/perf/arm-cci.c
|
|
||||||
@@ -1327,15 +1327,6 @@ static int cci_pmu_event_init(struct perf_event *event)
|
|
||||||
if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
- /* We have no filtering of any kind */
|
|
||||||
- if (event->attr.exclude_user ||
|
|
||||||
- event->attr.exclude_kernel ||
|
|
||||||
- event->attr.exclude_hv ||
|
|
||||||
- event->attr.exclude_idle ||
|
|
||||||
- event->attr.exclude_host ||
|
|
||||||
- event->attr.exclude_guest)
|
|
||||||
- return -EINVAL;
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Following the example set by other "uncore" PMUs, we accept any CPU
|
|
||||||
* and rewrite its affinity dynamically rather than having perf core
|
|
||||||
@@ -1433,6 +1424,7 @@ static int cci_pmu_init(struct cci_pmu *cci_pmu, struct platform_device *pdev)
|
|
||||||
.stop = cci_pmu_stop,
|
|
||||||
.read = pmu_read,
|
|
||||||
.attr_groups = pmu_attr_groups,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
cci_pmu->plat_device = pdev;
|
|
||||||
diff --git a/drivers/perf/arm-ccn.c b/drivers/perf/arm-ccn.c
|
|
||||||
index e4e06d2fbe29..e13ff765b362 100644
|
|
||||||
--- a/drivers/perf/arm-ccn.c
|
|
||||||
+++ b/drivers/perf/arm-ccn.c
|
|
||||||
@@ -741,10 +741,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (has_branch_stack(event) || event->attr.exclude_user ||
|
|
||||||
- event->attr.exclude_kernel || event->attr.exclude_hv ||
|
|
||||||
- event->attr.exclude_idle || event->attr.exclude_host ||
|
|
||||||
- event->attr.exclude_guest) {
|
|
||||||
+ if (has_branch_stack(event)) {
|
|
||||||
dev_dbg(ccn->dev, "Can't exclude execution levels!\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
@@ -1290,6 +1287,7 @@ static int arm_ccn_pmu_init(struct arm_ccn *ccn)
|
|
||||||
.read = arm_ccn_pmu_event_read,
|
|
||||||
.pmu_enable = arm_ccn_pmu_enable,
|
|
||||||
.pmu_disable = arm_ccn_pmu_disable,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* No overflow interrupt? Have to use a timer instead. */
|
|
||||||
diff --git a/drivers/perf/arm_dsu_pmu.c b/drivers/perf/arm_dsu_pmu.c
|
|
||||||
index f1cb7a910394..87573eaa7fdd 100644
|
|
||||||
--- a/drivers/perf/arm_dsu_pmu.c
|
|
||||||
+++ b/drivers/perf/arm_dsu_pmu.c
|
|
||||||
@@ -562,13 +562,7 @@ static int dsu_pmu_event_init(struct perf_event *event)
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (has_branch_stack(event) ||
|
|
||||||
- event->attr.exclude_user ||
|
|
||||||
- event->attr.exclude_kernel ||
|
|
||||||
- event->attr.exclude_hv ||
|
|
||||||
- event->attr.exclude_idle ||
|
|
||||||
- event->attr.exclude_host ||
|
|
||||||
- event->attr.exclude_guest) {
|
|
||||||
+ if (has_branch_stack(event)) {
|
|
||||||
dev_dbg(dsu_pmu->pmu.dev, "Can't support filtering\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
@@ -735,6 +729,7 @@ static int dsu_pmu_device_probe(struct platform_device *pdev)
|
|
||||||
.read = dsu_pmu_read,
|
|
||||||
|
|
||||||
.attr_groups = dsu_pmu_attr_groups,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
rc = perf_pmu_register(&dsu_pmu->pmu, name, -1);
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index 620fa1345150..4bab34504425 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -397,6 +397,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
|
||||||
.stop = hisi_uncore_pmu_stop,
|
|
||||||
.read = hisi_uncore_pmu_read,
|
|
||||||
.attr_groups = hisi_ddrc_pmu_attr_groups,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
ret = perf_pmu_register(&ddrc_pmu->pmu, name, -1);
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index 33a0da941be2..53711b945551 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -408,6 +408,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
|
||||||
.stop = hisi_uncore_pmu_stop,
|
|
||||||
.read = hisi_uncore_pmu_read,
|
|
||||||
.attr_groups = hisi_hha_pmu_attr_groups,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
ret = perf_pmu_register(&hha_pmu->pmu, name, -1);
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index 92485f00dcc8..171cf74405b3 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -398,6 +398,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
|
||||||
.stop = hisi_uncore_pmu_stop,
|
|
||||||
.read = hisi_uncore_pmu_read,
|
|
||||||
.attr_groups = hisi_l3c_pmu_attr_groups,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
ret = perf_pmu_register(&l3c_pmu->pmu, name, -1);
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
index 53f623ac4cc6..50b654a13305 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
@@ -148,15 +148,6 @@ int hisi_uncore_pmu_event_init(struct perf_event *event)
|
|
||||||
if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
|
|
||||||
return -EOPNOTSUPP;
|
|
||||||
|
|
||||||
- /* counters do not have these bits */
|
|
||||||
- if (event->attr.exclude_user ||
|
|
||||||
- event->attr.exclude_kernel ||
|
|
||||||
- event->attr.exclude_host ||
|
|
||||||
- event->attr.exclude_guest ||
|
|
||||||
- event->attr.exclude_hv ||
|
|
||||||
- event->attr.exclude_idle)
|
|
||||||
- return -EINVAL;
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* The uncore counters not specific to any CPU, so cannot
|
|
||||||
* support per-task
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,78 +0,0 @@
|
|||||||
From 9adb641d4a64e0ed52ba63ea401a9858efe8976d Mon Sep 17 00:00:00 2001
|
|
||||||
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
|
|
||||||
Date: Wed, 20 Feb 2019 11:12:39 +0000
|
|
||||||
Subject: [PATCH 10/55] drivers: provide devm_platform_ioremap_resource()
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.1-rc1
|
|
||||||
commit 306563985819ed2af9df0a26ae368ed12cf28f41
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=306563985819ed2af9df0a26ae368ed12cf28f41
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
|
|
||||||
There are currently 1200+ instances of using platform_get_resource()
|
|
||||||
and devm_ioremap_resource() together in the kernel tree.
|
|
||||||
|
|
||||||
This patch wraps these two calls in a single helper. Thanks to that
|
|
||||||
we don't have to declare a local variable for struct resource * and can
|
|
||||||
omit the redundant argument for resource type. We also have one
|
|
||||||
function call less.
|
|
||||||
|
|
||||||
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
|
|
||||||
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
||||||
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
|
|
||||||
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/base/platform.c | 18 ++++++++++++++++++
|
|
||||||
include/linux/platform_device.h | 3 +++
|
|
||||||
2 files changed, 21 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
|
|
||||||
index be8c82cc4445..23ec70ef6897 100644
|
|
||||||
--- a/drivers/base/platform.c
|
|
||||||
+++ b/drivers/base/platform.c
|
|
||||||
@@ -80,6 +80,24 @@ struct resource *platform_get_resource(struct platform_device *dev,
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(platform_get_resource);
|
|
||||||
|
|
||||||
+/**
|
|
||||||
+ * devm_platform_ioremap_resource - call devm_ioremap_resource() for a platform
|
|
||||||
+ * device
|
|
||||||
+ *
|
|
||||||
+ * @pdev: platform device to use both for memory resource lookup as well as
|
|
||||||
+ * resource managemend
|
|
||||||
+ * @index: resource index
|
|
||||||
+ */
|
|
||||||
+void __iomem *devm_platform_ioremap_resource(struct platform_device *pdev,
|
|
||||||
+ unsigned int index)
|
|
||||||
+{
|
|
||||||
+ struct resource *res;
|
|
||||||
+
|
|
||||||
+ res = platform_get_resource(pdev, IORESOURCE_MEM, index);
|
|
||||||
+ return devm_ioremap_resource(&pdev->dev, res);
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(devm_platform_ioremap_resource);
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* platform_get_irq - get an IRQ for a device
|
|
||||||
* @dev: platform device
|
|
||||||
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
|
|
||||||
index 1a9f38f27f65..9e5c98fcea8c 100644
|
|
||||||
--- a/include/linux/platform_device.h
|
|
||||||
+++ b/include/linux/platform_device.h
|
|
||||||
@@ -51,6 +51,9 @@ extern struct device platform_bus;
|
|
||||||
extern void arch_setup_pdev_archdata(struct platform_device *);
|
|
||||||
extern struct resource *platform_get_resource(struct platform_device *,
|
|
||||||
unsigned int, unsigned int);
|
|
||||||
+extern void __iomem *
|
|
||||||
+devm_platform_ioremap_resource(struct platform_device *pdev,
|
|
||||||
+ unsigned int index);
|
|
||||||
extern int platform_get_irq(struct platform_device *, unsigned int);
|
|
||||||
extern int platform_irq_count(struct platform_device *);
|
|
||||||
extern struct resource *platform_get_resource_byname(struct platform_device *,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,97 +0,0 @@
|
|||||||
From ce76ffbdbb8cf7dcdc4bbd2988971202f4ab7e0f Mon Sep 17 00:00:00 2001
|
|
||||||
From: YueHaibing <yuehaibing@huawei.com>
|
|
||||||
Date: Fri, 6 Sep 2019 22:36:44 +0800
|
|
||||||
Subject: [PATCH 11/55] perf: hisi: use devm_platform_ioremap_resource() to
|
|
||||||
simplify code
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.5-rc1
|
|
||||||
commit 42c184ade43a79d36f50a0b3394b3326633f53f5
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=42c184ade43a79d36f50a0b3394b3326633f53f5
|
|
||||||
|
|
||||||
---------------------------------------------------------------
|
|
||||||
|
|
||||||
Use devm_platform_ioremap_resource() to simplify the code a bit.
|
|
||||||
This is detected by coccinelle.
|
|
||||||
|
|
||||||
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 5 +----
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 4 +---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 4 +---
|
|
||||||
3 files changed, 3 insertions(+), 10 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index 4bab34504425..5d9dd4078994 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -248,8 +248,6 @@ MODULE_DEVICE_TABLE(acpi, hisi_ddrc_pmu_acpi_match);
|
|
||||||
static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
|
||||||
struct hisi_pmu *ddrc_pmu)
|
|
||||||
{
|
|
||||||
- struct resource *res;
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Use the SCCL_ID and DDRC channel ID to identify the
|
|
||||||
* DDRC PMU, while SCCL_ID is in MPIDR[aff2].
|
|
||||||
@@ -268,8 +266,7 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
|
||||||
/* DDRC PMUs only share the same SCCL */
|
|
||||||
ddrc_pmu->ccl_id = -1;
|
|
||||||
|
|
||||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
||||||
- ddrc_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
|
||||||
+ ddrc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
|
||||||
if (IS_ERR(ddrc_pmu->base)) {
|
|
||||||
dev_err(&pdev->dev, "ioremap failed for ddrc_pmu resource\n");
|
|
||||||
return PTR_ERR(ddrc_pmu->base);
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index 53711b945551..d3c517325a3f 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -239,7 +239,6 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|
||||||
struct hisi_pmu *hha_pmu)
|
|
||||||
{
|
|
||||||
unsigned long long id;
|
|
||||||
- struct resource *res;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
|
||||||
@@ -261,8 +260,7 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|
||||||
/* HHA PMUs only share the same SCCL */
|
|
||||||
hha_pmu->ccl_id = -1;
|
|
||||||
|
|
||||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
||||||
- hha_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
|
||||||
+ hha_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
|
||||||
if (IS_ERR(hha_pmu->base)) {
|
|
||||||
dev_err(&pdev->dev, "ioremap failed for hha_pmu resource\n");
|
|
||||||
return PTR_ERR(hha_pmu->base);
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index 171cf74405b3..cbbf73ea66e6 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -238,7 +238,6 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
|
||||||
struct hisi_pmu *l3c_pmu)
|
|
||||||
{
|
|
||||||
unsigned long long id;
|
|
||||||
- struct resource *res;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
|
||||||
@@ -264,8 +263,7 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
|
||||||
- l3c_pmu->base = devm_ioremap_resource(&pdev->dev, res);
|
|
||||||
+ l3c_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
|
||||||
if (IS_ERR(l3c_pmu->base)) {
|
|
||||||
dev_err(&pdev->dev, "ioremap failed for l3c_pmu resource\n");
|
|
||||||
return PTR_ERR(l3c_pmu->base);
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,218 +0,0 @@
|
|||||||
From 7da4fb60563da82f9b482af152909d29818b5d9e Mon Sep 17 00:00:00 2001
|
|
||||||
From: John Garry <john.garry@huawei.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:43:58 +0800
|
|
||||||
Subject: [PATCH 12/55] drivers/perf: hisi: Add identifier sysfs file
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.10-rc3
|
|
||||||
commit ac4511c9364c9a6390e8585cdd4596103bca16eb
|
|
||||||
category: feature
|
|
||||||
bugzilla: https://gitee.com/openeuler/kernel/issues/I8AU2M
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ac4511c9364c9a6390e8585cdd4596103bca16eb
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
To allow userspace to identify the specific implementation of the device,
|
|
||||||
add an "identifier" sysfs file.
|
|
||||||
|
|
||||||
Encoding is as follows (same for all uncore drivers):
|
|
||||||
hi1620: 0x0
|
|
||||||
hi1630: 0x30
|
|
||||||
|
|
||||||
Signed-off-by: John Garry <john.garry@huawei.com>
|
|
||||||
Link: https://lore.kernel.org/r/1602149181-237415-2-git-send-email-john.garry@huawei.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 16 ++++++++++++++++
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 16 ++++++++++++++++
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 16 ++++++++++++++++
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 10 ++++++++++
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 7 +++++++
|
|
||||||
5 files changed, 65 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index 5d9dd4078994..a88c7d840d38 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -36,6 +36,7 @@
|
|
||||||
#define DDRC_INT_MASK 0x6c8
|
|
||||||
#define DDRC_INT_STATUS 0x6cc
|
|
||||||
#define DDRC_INT_CLEAR 0x6d0
|
|
||||||
+#define DDRC_VERSION 0x710
|
|
||||||
|
|
||||||
/* DDRC has 8-counters */
|
|
||||||
#define DDRC_NR_COUNTERS 0x8
|
|
||||||
@@ -272,6 +273,8 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
|
||||||
return PTR_ERR(ddrc_pmu->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -313,10 +316,23 @@ static const struct attribute_group hisi_ddrc_pmu_cpumask_attr_group = {
|
|
||||||
.attrs = hisi_ddrc_pmu_cpumask_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct device_attribute hisi_ddrc_pmu_identifier_attr =
|
|
||||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_ddrc_pmu_identifier_attrs[] = {
|
|
||||||
+ &hisi_ddrc_pmu_identifier_attr.attr,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute_group hisi_ddrc_pmu_identifier_group = {
|
|
||||||
+ .attrs = hisi_ddrc_pmu_identifier_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const struct attribute_group *hisi_ddrc_pmu_attr_groups[] = {
|
|
||||||
&hisi_ddrc_pmu_format_group,
|
|
||||||
&hisi_ddrc_pmu_events_group,
|
|
||||||
&hisi_ddrc_pmu_cpumask_attr_group,
|
|
||||||
+ &hisi_ddrc_pmu_identifier_group,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index d3c517325a3f..1e0138bbe6e7 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -26,6 +26,7 @@
|
|
||||||
#define HHA_INT_MASK 0x0804
|
|
||||||
#define HHA_INT_STATUS 0x0808
|
|
||||||
#define HHA_INT_CLEAR 0x080C
|
|
||||||
+#define HHA_VERSION 0x1cf0
|
|
||||||
#define HHA_PERF_CTRL 0x1E00
|
|
||||||
#define HHA_EVENT_CTRL 0x1E04
|
|
||||||
#define HHA_EVENT_TYPE0 0x1E80
|
|
||||||
@@ -266,6 +267,8 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|
||||||
return PTR_ERR(hha_pmu->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ hha_pmu->identifier = readl(hha_pmu->base + HHA_VERSION);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -325,10 +328,23 @@ static const struct attribute_group hisi_hha_pmu_cpumask_attr_group = {
|
|
||||||
.attrs = hisi_hha_pmu_cpumask_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct device_attribute hisi_hha_pmu_identifier_attr =
|
|
||||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_hha_pmu_identifier_attrs[] = {
|
|
||||||
+ &hisi_hha_pmu_identifier_attr.attr,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute_group hisi_hha_pmu_identifier_group = {
|
|
||||||
+ .attrs = hisi_hha_pmu_identifier_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const struct attribute_group *hisi_hha_pmu_attr_groups[] = {
|
|
||||||
&hisi_hha_pmu_format_group,
|
|
||||||
&hisi_hha_pmu_events_group,
|
|
||||||
&hisi_hha_pmu_cpumask_attr_group,
|
|
||||||
+ &hisi_hha_pmu_identifier_group,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index cbbf73ea66e6..1707ae551ece 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -28,6 +28,7 @@
|
|
||||||
#define L3C_INT_STATUS 0x0808
|
|
||||||
#define L3C_INT_CLEAR 0x080c
|
|
||||||
#define L3C_EVENT_CTRL 0x1c00
|
|
||||||
+#define L3C_VERSION 0x1cf0
|
|
||||||
#define L3C_EVENT_TYPE0 0x1d00
|
|
||||||
/*
|
|
||||||
* Each counter is 48-bits and [48:63] are reserved
|
|
||||||
@@ -269,6 +270,8 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
|
||||||
return PTR_ERR(l3c_pmu->base);
|
|
||||||
}
|
|
||||||
|
|
||||||
+ l3c_pmu->identifier = readl(l3c_pmu->base + L3C_VERSION);
|
|
||||||
+
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -315,10 +318,23 @@ static const struct attribute_group hisi_l3c_pmu_cpumask_attr_group = {
|
|
||||||
.attrs = hisi_l3c_pmu_cpumask_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct device_attribute hisi_l3c_pmu_identifier_attr =
|
|
||||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_l3c_pmu_identifier_attrs[] = {
|
|
||||||
+ &hisi_l3c_pmu_identifier_attr.attr,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute_group hisi_l3c_pmu_identifier_group = {
|
|
||||||
+ .attrs = hisi_l3c_pmu_identifier_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const struct attribute_group *hisi_l3c_pmu_attr_groups[] = {
|
|
||||||
&hisi_l3c_pmu_format_group,
|
|
||||||
&hisi_l3c_pmu_events_group,
|
|
||||||
&hisi_l3c_pmu_cpumask_attr_group,
|
|
||||||
+ &hisi_l3c_pmu_identifier_group,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
index 50b654a13305..f6a992da24bf 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
@@ -122,6 +122,16 @@ int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(hisi_uncore_pmu_get_event_idx);
|
|
||||||
|
|
||||||
+ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
|
||||||
+ struct device_attribute *attr,
|
|
||||||
+ char *page)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *hisi_pmu = to_hisi_pmu(dev_get_drvdata(dev));
|
|
||||||
+
|
|
||||||
+ return snprintf(page, PAGE_SIZE, "0x%08x\n", hisi_pmu->identifier);
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(hisi_uncore_pmu_identifier_attr_show);
|
|
||||||
+
|
|
||||||
static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
|
|
||||||
{
|
|
||||||
if (!hisi_uncore_pmu_counter_valid(hisi_pmu, idx)) {
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
index 8f2f2fc5dde4..098a8f6dc7ee 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
@@ -78,6 +78,7 @@ struct hisi_pmu {
|
|
||||||
int counter_bits;
|
|
||||||
/* check event code range */
|
|
||||||
int check_event;
|
|
||||||
+ u32 identifier;
|
|
||||||
};
|
|
||||||
|
|
||||||
int hisi_uncore_pmu_counter_valid(struct hisi_pmu *hisi_pmu, int idx);
|
|
||||||
@@ -100,4 +101,10 @@ ssize_t hisi_cpumask_sysfs_show(struct device *dev,
|
|
||||||
struct device_attribute *attr, char *buf);
|
|
||||||
int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node);
|
|
||||||
int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node);
|
|
||||||
+
|
|
||||||
+ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
|
||||||
+ struct device_attribute *attr,
|
|
||||||
+ char *page);
|
|
||||||
+
|
|
||||||
+
|
|
||||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,193 +0,0 @@
|
|||||||
From 34861133469cfd5c5851f7f4ab05e3d3af1dd13a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:02 +0800
|
|
||||||
Subject: [PATCH 13/55] drivers/perf: hisi: Remove unnecessary check of counter
|
|
||||||
index
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.12-rc3
|
|
||||||
commit 4e4cb8ca48bd68c00df67c10ff867016abb7391f
|
|
||||||
category: cleanup
|
|
||||||
bugzilla: 175148
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=4e4cb8ca48bd68c00df67c10ff867016abb7391f
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The sanity check for counter index has been done in the function
|
|
||||||
hisi_uncore_pmu_get_event_idx, so remove the redundant interface
|
|
||||||
hisi_uncore_pmu_counter_valid() and sanity check.
|
|
||||||
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Will Deacon <will@kernel.org>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Link: https://lore.kernel.org/r/1615186237-22263-2-git-send-email-zhangshaokun@hisilicon.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 20 +++----------------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 18 ++---------------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 18 ++---------------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 11 ----------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 1 -
|
|
||||||
5 files changed, 7 insertions(+), 61 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index a88c7d840d38..bcb2c2d66b7f 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -68,29 +68,15 @@ static u32 hisi_ddrc_pmu_get_counter_offset(int cntr_idx)
|
|
||||||
static u64 hisi_ddrc_pmu_read_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
- /* Use event code as counter index */
|
|
||||||
- u32 idx = GET_DDRC_EVENTID(hwc);
|
|
||||||
-
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(ddrc_pmu, idx)) {
|
|
||||||
- dev_err(ddrc_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return readl(ddrc_pmu->base + hisi_ddrc_pmu_get_counter_offset(idx));
|
|
||||||
+ return readl(ddrc_pmu->base +
|
|
||||||
+ hisi_ddrc_pmu_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hisi_ddrc_pmu_write_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
struct hw_perf_event *hwc, u64 val)
|
|
||||||
{
|
|
||||||
- u32 idx = GET_DDRC_EVENTID(hwc);
|
|
||||||
-
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(ddrc_pmu, idx)) {
|
|
||||||
- dev_err(ddrc_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
writel((u32)val,
|
|
||||||
- ddrc_pmu->base + hisi_ddrc_pmu_get_counter_offset(idx));
|
|
||||||
+ ddrc_pmu->base + hisi_ddrc_pmu_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index 1e0138bbe6e7..de1766342b4e 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -54,29 +54,15 @@ static u32 hisi_hha_pmu_get_counter_offset(u32 cntr_idx)
|
|
||||||
static u64 hisi_hha_pmu_read_counter(struct hisi_pmu *hha_pmu,
|
|
||||||
struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
- u32 idx = hwc->idx;
|
|
||||||
-
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(hha_pmu, idx)) {
|
|
||||||
- dev_err(hha_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
/* Read 64 bits and like L3C, top 16 bits are RAZ */
|
|
||||||
- return readq(hha_pmu->base + hisi_hha_pmu_get_counter_offset(idx));
|
|
||||||
+ return readq(hha_pmu->base + hisi_hha_pmu_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hisi_hha_pmu_write_counter(struct hisi_pmu *hha_pmu,
|
|
||||||
struct hw_perf_event *hwc, u64 val)
|
|
||||||
{
|
|
||||||
- u32 idx = hwc->idx;
|
|
||||||
-
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(hha_pmu, idx)) {
|
|
||||||
- dev_err(hha_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
/* Write 64 bits and like L3C, top 16 bits are WI */
|
|
||||||
- writeq(val, hha_pmu->base + hisi_hha_pmu_get_counter_offset(idx));
|
|
||||||
+ writeq(val, hha_pmu->base + hisi_hha_pmu_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hisi_hha_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index 1707ae551ece..c4afeaaaa3a4 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -53,29 +53,15 @@ static u32 hisi_l3c_pmu_get_counter_offset(u32 cntr_idx)
|
|
||||||
static u64 hisi_l3c_pmu_read_counter(struct hisi_pmu *l3c_pmu,
|
|
||||||
struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
- u32 idx = hwc->idx;
|
|
||||||
-
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(l3c_pmu, idx)) {
|
|
||||||
- dev_err(l3c_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return 0;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
/* Read 64-bits and the upper 16 bits are RAZ */
|
|
||||||
- return readq(l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(idx));
|
|
||||||
+ return readq(l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hisi_l3c_pmu_write_counter(struct hisi_pmu *l3c_pmu,
|
|
||||||
struct hw_perf_event *hwc, u64 val)
|
|
||||||
{
|
|
||||||
- u32 idx = hwc->idx;
|
|
||||||
-
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(l3c_pmu, idx)) {
|
|
||||||
- dev_err(l3c_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
/* Write 64-bits and the upper 16 bits are WI */
|
|
||||||
- writeq(val, l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(idx));
|
|
||||||
+ writeq(val, l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hisi_l3c_pmu_write_evtype(struct hisi_pmu *l3c_pmu, int idx,
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
index f6a992da24bf..9ebdb76dd3a4 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
@@ -99,12 +99,6 @@ static bool hisi_validate_event_group(struct perf_event *event)
|
|
||||||
return counters <= hisi_pmu->num_counters;
|
|
||||||
}
|
|
||||||
|
|
||||||
-int hisi_uncore_pmu_counter_valid(struct hisi_pmu *hisi_pmu, int idx)
|
|
||||||
-{
|
|
||||||
- return idx >= 0 && idx < hisi_pmu->num_counters;
|
|
||||||
-}
|
|
||||||
-EXPORT_SYMBOL_GPL(hisi_uncore_pmu_counter_valid);
|
|
||||||
-
|
|
||||||
int hisi_uncore_pmu_get_event_idx(struct perf_event *event)
|
|
||||||
{
|
|
||||||
struct hisi_pmu *hisi_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
@@ -134,11 +128,6 @@ EXPORT_SYMBOL_GPL(hisi_uncore_pmu_identifier_attr_show);
|
|
||||||
|
|
||||||
static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
|
|
||||||
{
|
|
||||||
- if (!hisi_uncore_pmu_counter_valid(hisi_pmu, idx)) {
|
|
||||||
- dev_err(hisi_pmu->dev, "Unsupported event index:%d!\n", idx);
|
|
||||||
- return;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
clear_bit(idx, hisi_pmu->pmu_events.used_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
index 098a8f6dc7ee..d71a6c86b282 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
@@ -81,7 +81,6 @@ struct hisi_pmu {
|
|
||||||
u32 identifier;
|
|
||||||
};
|
|
||||||
|
|
||||||
-int hisi_uncore_pmu_counter_valid(struct hisi_pmu *hisi_pmu, int idx);
|
|
||||||
int hisi_uncore_pmu_get_event_idx(struct perf_event *event);
|
|
||||||
void hisi_uncore_pmu_read(struct perf_event *event);
|
|
||||||
int hisi_uncore_pmu_add(struct perf_event *event, int flags);
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,448 +0,0 @@
|
|||||||
From 990f0977794c7bc3a78dbea66e3b5e276eccaad4 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:03 +0800
|
|
||||||
Subject: [PATCH 14/55] drivers/perf: hisi: Refactor code for more uncore PMUs
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.12-rc3
|
|
||||||
commit baff06c315a146a6943b4fcabb4fe4fa36167413
|
|
||||||
category: cleanup
|
|
||||||
bugzilla: 175148
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=baff06c315a146a6943b4fcabb4fe4fa36167413
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
On HiSilicon uncore PMU drivers, interrupt handling function and interrupt
|
|
||||||
registration function are very similar in differents PMU modules. Let's
|
|
||||||
refactor the frame.
|
|
||||||
|
|
||||||
Two new callbacks are added for the HW accessors:
|
|
||||||
|
|
||||||
* hisi_uncore_ops::get_int_status returns a bitmap of events which
|
|
||||||
have overflowed and raised an interrupt
|
|
||||||
|
|
||||||
* hisi_uncore_ops::clear_int_status clears the overflow status for a
|
|
||||||
specific event
|
|
||||||
|
|
||||||
These callback functions are used by a common IRQ handler,
|
|
||||||
hisi_uncore_pmu_isr().
|
|
||||||
|
|
||||||
One more function hisi_uncore_pmu_init_irq() is added to replace each
|
|
||||||
PMU initialization IRQ interface and simplify the code.
|
|
||||||
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Will Deacon <will@kernel.org>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Link: https://lore.kernel.org/r/1615186237-22263-3-git-send-email-zhangshaokun@hisilicon.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 61 +++----------------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 61 +++----------------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 61 +++----------------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 54 ++++++++++++++++
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 6 +-
|
|
||||||
5 files changed, 80 insertions(+), 163 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index bcb2c2d66b7f..a03e3f8058b3 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -17,7 +17,6 @@
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
-#include <linux/platform_device.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
|
|
||||||
#include "hisi_uncore_pmu.h"
|
|
||||||
@@ -168,62 +167,14 @@ static void hisi_ddrc_pmu_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static irqreturn_t hisi_ddrc_pmu_isr(int irq, void *dev_id)
|
|
||||||
+static u32 hisi_ddrc_pmu_get_int_status(struct hisi_pmu *ddrc_pmu)
|
|
||||||
{
|
|
||||||
- struct hisi_pmu *ddrc_pmu = dev_id;
|
|
||||||
- struct perf_event *event;
|
|
||||||
- unsigned long overflown;
|
|
||||||
- int idx;
|
|
||||||
-
|
|
||||||
- /* Read the DDRC_INT_STATUS register */
|
|
||||||
- overflown = readl(ddrc_pmu->base + DDRC_INT_STATUS);
|
|
||||||
- if (!overflown)
|
|
||||||
- return IRQ_NONE;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Find the counter index which overflowed if the bit was set
|
|
||||||
- * and handle it
|
|
||||||
- */
|
|
||||||
- for_each_set_bit(idx, &overflown, DDRC_NR_COUNTERS) {
|
|
||||||
- /* Write 1 to clear the IRQ status flag */
|
|
||||||
- writel((1 << idx), ddrc_pmu->base + DDRC_INT_CLEAR);
|
|
||||||
-
|
|
||||||
- /* Get the corresponding event struct */
|
|
||||||
- event = ddrc_pmu->pmu_events.hw_events[idx];
|
|
||||||
- if (!event)
|
|
||||||
- continue;
|
|
||||||
-
|
|
||||||
- hisi_uncore_pmu_event_update(event);
|
|
||||||
- hisi_uncore_pmu_set_event_period(event);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return IRQ_HANDLED;
|
|
||||||
+ return readl(ddrc_pmu->base + DDRC_INT_STATUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int hisi_ddrc_pmu_init_irq(struct hisi_pmu *ddrc_pmu,
|
|
||||||
- struct platform_device *pdev)
|
|
||||||
+static void hisi_ddrc_pmu_clear_int_status(struct hisi_pmu *ddrc_pmu, int idx)
|
|
||||||
{
|
|
||||||
- int irq, ret;
|
|
||||||
-
|
|
||||||
- /* Read and init IRQ */
|
|
||||||
- irq = platform_get_irq(pdev, 0);
|
|
||||||
- if (irq < 0) {
|
|
||||||
- dev_err(&pdev->dev, "DDRC PMU get irq fail; irq:%d\n", irq);
|
|
||||||
- return irq;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_ddrc_pmu_isr,
|
|
||||||
- IRQF_NOBALANCING | IRQF_NO_THREAD,
|
|
||||||
- dev_name(&pdev->dev), ddrc_pmu);
|
|
||||||
- if (ret < 0) {
|
|
||||||
- dev_err(&pdev->dev,
|
|
||||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ddrc_pmu->irq = irq;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
+ writel(1 << idx, ddrc_pmu->base + DDRC_INT_CLEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct acpi_device_id hisi_ddrc_pmu_acpi_match[] = {
|
|
||||||
@@ -333,6 +284,8 @@ static const struct hisi_uncore_ops hisi_uncore_ddrc_ops = {
|
|
||||||
.disable_counter_int = hisi_ddrc_pmu_disable_counter_int,
|
|
||||||
.write_counter = hisi_ddrc_pmu_write_counter,
|
|
||||||
.read_counter = hisi_ddrc_pmu_read_counter,
|
|
||||||
+ .get_int_status = hisi_ddrc_pmu_get_int_status,
|
|
||||||
+ .clear_int_status = hisi_ddrc_pmu_clear_int_status,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
@@ -344,7 +297,7 @@ static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- ret = hisi_ddrc_pmu_init_irq(ddrc_pmu, pdev);
|
|
||||||
+ ret = hisi_uncore_pmu_init_irq(ddrc_pmu, pdev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index de1766342b4e..536d1f637fa7 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -17,7 +17,6 @@
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
-#include <linux/platform_device.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
|
|
||||||
#include "hisi_uncore_pmu.h"
|
|
||||||
@@ -158,62 +157,14 @@ static void hisi_hha_pmu_disable_counter_int(struct hisi_pmu *hha_pmu,
|
|
||||||
writel(val, hha_pmu->base + HHA_INT_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static irqreturn_t hisi_hha_pmu_isr(int irq, void *dev_id)
|
|
||||||
+static u32 hisi_hha_pmu_get_int_status(struct hisi_pmu *hha_pmu)
|
|
||||||
{
|
|
||||||
- struct hisi_pmu *hha_pmu = dev_id;
|
|
||||||
- struct perf_event *event;
|
|
||||||
- unsigned long overflown;
|
|
||||||
- int idx;
|
|
||||||
-
|
|
||||||
- /* Read HHA_INT_STATUS register */
|
|
||||||
- overflown = readl(hha_pmu->base + HHA_INT_STATUS);
|
|
||||||
- if (!overflown)
|
|
||||||
- return IRQ_NONE;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Find the counter index which overflowed if the bit was set
|
|
||||||
- * and handle it
|
|
||||||
- */
|
|
||||||
- for_each_set_bit(idx, &overflown, HHA_NR_COUNTERS) {
|
|
||||||
- /* Write 1 to clear the IRQ status flag */
|
|
||||||
- writel((1 << idx), hha_pmu->base + HHA_INT_CLEAR);
|
|
||||||
-
|
|
||||||
- /* Get the corresponding event struct */
|
|
||||||
- event = hha_pmu->pmu_events.hw_events[idx];
|
|
||||||
- if (!event)
|
|
||||||
- continue;
|
|
||||||
-
|
|
||||||
- hisi_uncore_pmu_event_update(event);
|
|
||||||
- hisi_uncore_pmu_set_event_period(event);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return IRQ_HANDLED;
|
|
||||||
+ return readl(hha_pmu->base + HHA_INT_STATUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int hisi_hha_pmu_init_irq(struct hisi_pmu *hha_pmu,
|
|
||||||
- struct platform_device *pdev)
|
|
||||||
+static void hisi_hha_pmu_clear_int_status(struct hisi_pmu *hha_pmu, int idx)
|
|
||||||
{
|
|
||||||
- int irq, ret;
|
|
||||||
-
|
|
||||||
- /* Read and init IRQ */
|
|
||||||
- irq = platform_get_irq(pdev, 0);
|
|
||||||
- if (irq < 0) {
|
|
||||||
- dev_err(&pdev->dev, "HHA PMU get irq fail; irq:%d\n", irq);
|
|
||||||
- return irq;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_hha_pmu_isr,
|
|
||||||
- IRQF_NOBALANCING | IRQF_NO_THREAD,
|
|
||||||
- dev_name(&pdev->dev), hha_pmu);
|
|
||||||
- if (ret < 0) {
|
|
||||||
- dev_err(&pdev->dev,
|
|
||||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- hha_pmu->irq = irq;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
+ writel(1 << idx, hha_pmu->base + HHA_INT_CLEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct acpi_device_id hisi_hha_pmu_acpi_match[] = {
|
|
||||||
@@ -345,6 +296,8 @@ static const struct hisi_uncore_ops hisi_uncore_hha_ops = {
|
|
||||||
.disable_counter_int = hisi_hha_pmu_disable_counter_int,
|
|
||||||
.write_counter = hisi_hha_pmu_write_counter,
|
|
||||||
.read_counter = hisi_hha_pmu_read_counter,
|
|
||||||
+ .get_int_status = hisi_hha_pmu_get_int_status,
|
|
||||||
+ .clear_int_status = hisi_hha_pmu_clear_int_status,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
@@ -356,7 +309,7 @@ static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- ret = hisi_hha_pmu_init_irq(hha_pmu, pdev);
|
|
||||||
+ ret = hisi_uncore_pmu_init_irq(hha_pmu, pdev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index c4afeaaaa3a4..5256e4ce3384 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -17,7 +17,6 @@
|
|
||||||
#include <linux/interrupt.h>
|
|
||||||
#include <linux/irq.h>
|
|
||||||
#include <linux/list.h>
|
|
||||||
-#include <linux/platform_device.h>
|
|
||||||
#include <linux/smp.h>
|
|
||||||
|
|
||||||
#include "hisi_uncore_pmu.h"
|
|
||||||
@@ -157,62 +156,14 @@ static void hisi_l3c_pmu_disable_counter_int(struct hisi_pmu *l3c_pmu,
|
|
||||||
writel(val, l3c_pmu->base + L3C_INT_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static irqreturn_t hisi_l3c_pmu_isr(int irq, void *dev_id)
|
|
||||||
+static u32 hisi_l3c_pmu_get_int_status(struct hisi_pmu *l3c_pmu)
|
|
||||||
{
|
|
||||||
- struct hisi_pmu *l3c_pmu = dev_id;
|
|
||||||
- struct perf_event *event;
|
|
||||||
- unsigned long overflown;
|
|
||||||
- int idx;
|
|
||||||
-
|
|
||||||
- /* Read L3C_INT_STATUS register */
|
|
||||||
- overflown = readl(l3c_pmu->base + L3C_INT_STATUS);
|
|
||||||
- if (!overflown)
|
|
||||||
- return IRQ_NONE;
|
|
||||||
-
|
|
||||||
- /*
|
|
||||||
- * Find the counter index which overflowed if the bit was set
|
|
||||||
- * and handle it.
|
|
||||||
- */
|
|
||||||
- for_each_set_bit(idx, &overflown, L3C_NR_COUNTERS) {
|
|
||||||
- /* Write 1 to clear the IRQ status flag */
|
|
||||||
- writel((1 << idx), l3c_pmu->base + L3C_INT_CLEAR);
|
|
||||||
-
|
|
||||||
- /* Get the corresponding event struct */
|
|
||||||
- event = l3c_pmu->pmu_events.hw_events[idx];
|
|
||||||
- if (!event)
|
|
||||||
- continue;
|
|
||||||
-
|
|
||||||
- hisi_uncore_pmu_event_update(event);
|
|
||||||
- hisi_uncore_pmu_set_event_period(event);
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- return IRQ_HANDLED;
|
|
||||||
+ return readl(l3c_pmu->base + L3C_INT_STATUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int hisi_l3c_pmu_init_irq(struct hisi_pmu *l3c_pmu,
|
|
||||||
- struct platform_device *pdev)
|
|
||||||
+static void hisi_l3c_pmu_clear_int_status(struct hisi_pmu *l3c_pmu, int idx)
|
|
||||||
{
|
|
||||||
- int irq, ret;
|
|
||||||
-
|
|
||||||
- /* Read and init IRQ */
|
|
||||||
- irq = platform_get_irq(pdev, 0);
|
|
||||||
- if (irq < 0) {
|
|
||||||
- dev_err(&pdev->dev, "L3C PMU get irq fail; irq:%d\n", irq);
|
|
||||||
- return irq;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- ret = devm_request_irq(&pdev->dev, irq, hisi_l3c_pmu_isr,
|
|
||||||
- IRQF_NOBALANCING | IRQF_NO_THREAD,
|
|
||||||
- dev_name(&pdev->dev), l3c_pmu);
|
|
||||||
- if (ret < 0) {
|
|
||||||
- dev_err(&pdev->dev,
|
|
||||||
- "Fail to request IRQ:%d ret:%d\n", irq, ret);
|
|
||||||
- return ret;
|
|
||||||
- }
|
|
||||||
-
|
|
||||||
- l3c_pmu->irq = irq;
|
|
||||||
-
|
|
||||||
- return 0;
|
|
||||||
+ writel(1 << idx, l3c_pmu->base + L3C_INT_CLEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct acpi_device_id hisi_l3c_pmu_acpi_match[] = {
|
|
||||||
@@ -335,6 +286,8 @@ static const struct hisi_uncore_ops hisi_uncore_l3c_ops = {
|
|
||||||
.disable_counter_int = hisi_l3c_pmu_disable_counter_int,
|
|
||||||
.write_counter = hisi_l3c_pmu_write_counter,
|
|
||||||
.read_counter = hisi_l3c_pmu_read_counter,
|
|
||||||
+ .get_int_status = hisi_l3c_pmu_get_int_status,
|
|
||||||
+ .clear_int_status = hisi_l3c_pmu_clear_int_status,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
@@ -346,7 +299,7 @@ static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- ret = hisi_l3c_pmu_init_irq(l3c_pmu, pdev);
|
|
||||||
+ ret = hisi_uncore_pmu_init_irq(l3c_pmu, pdev);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
index 9ebdb76dd3a4..53ac9f062c0f 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
@@ -131,6 +131,60 @@ static void hisi_uncore_pmu_clear_event_idx(struct hisi_pmu *hisi_pmu, int idx)
|
|
||||||
clear_bit(idx, hisi_pmu->pmu_events.used_mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static irqreturn_t hisi_uncore_pmu_isr(int irq, void *data)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *hisi_pmu = data;
|
|
||||||
+ struct perf_event *event;
|
|
||||||
+ unsigned long overflown;
|
|
||||||
+ int idx;
|
|
||||||
+
|
|
||||||
+ overflown = hisi_pmu->ops->get_int_status(hisi_pmu);
|
|
||||||
+ if (!overflown)
|
|
||||||
+ return IRQ_NONE;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Find the counter index which overflowed if the bit was set
|
|
||||||
+ * and handle it.
|
|
||||||
+ */
|
|
||||||
+ for_each_set_bit(idx, &overflown, hisi_pmu->num_counters) {
|
|
||||||
+ /* Write 1 to clear the IRQ status flag */
|
|
||||||
+ hisi_pmu->ops->clear_int_status(hisi_pmu, idx);
|
|
||||||
+ /* Get the corresponding event struct */
|
|
||||||
+ event = hisi_pmu->pmu_events.hw_events[idx];
|
|
||||||
+ if (!event)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ hisi_uncore_pmu_event_update(event);
|
|
||||||
+ hisi_uncore_pmu_set_event_period(event);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return IRQ_HANDLED;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
|
|
||||||
+ struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ int irq, ret;
|
|
||||||
+
|
|
||||||
+ irq = platform_get_irq(pdev, 0);
|
|
||||||
+ if (irq < 0)
|
|
||||||
+ return irq;
|
|
||||||
+
|
|
||||||
+ ret = devm_request_irq(&pdev->dev, irq, hisi_uncore_pmu_isr,
|
|
||||||
+ IRQF_NOBALANCING | IRQF_NO_THREAD,
|
|
||||||
+ dev_name(&pdev->dev), hisi_pmu);
|
|
||||||
+ if (ret < 0) {
|
|
||||||
+ dev_err(&pdev->dev,
|
|
||||||
+ "Fail to request IRQ: %d ret: %d.\n", irq, ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ hisi_pmu->irq = irq;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+EXPORT_SYMBOL_GPL(hisi_uncore_pmu_init_irq);
|
|
||||||
+
|
|
||||||
int hisi_uncore_pmu_event_init(struct perf_event *event)
|
|
||||||
{
|
|
||||||
struct hw_perf_event *hwc = &event->hw;
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
index d71a6c86b282..3336723e8cf6 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
@@ -19,6 +19,7 @@
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/module.h>
|
|
||||||
#include <linux/perf_event.h>
|
|
||||||
+#include <linux/platform_device.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
|
|
||||||
#undef pr_fmt
|
|
||||||
@@ -50,6 +51,8 @@ struct hisi_uncore_ops {
|
|
||||||
void (*disable_counter_int)(struct hisi_pmu *, struct hw_perf_event *);
|
|
||||||
void (*start_counters)(struct hisi_pmu *);
|
|
||||||
void (*stop_counters)(struct hisi_pmu *);
|
|
||||||
+ u32 (*get_int_status)(struct hisi_pmu *hisi_pmu);
|
|
||||||
+ void (*clear_int_status)(struct hisi_pmu *hisi_pmu, int idx);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hisi_pmu_hwevents {
|
|
||||||
@@ -104,6 +107,7 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node);
|
|
||||||
ssize_t hisi_uncore_pmu_identifier_attr_show(struct device *dev,
|
|
||||||
struct device_attribute *attr,
|
|
||||||
char *page);
|
|
||||||
-
|
|
||||||
+int hisi_uncore_pmu_init_irq(struct hisi_pmu *hisi_pmu,
|
|
||||||
+ struct platform_device *pdev);
|
|
||||||
|
|
||||||
#endif /* __HISI_UNCORE_PMU_H__ */
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,448 +0,0 @@
|
|||||||
From 3d5c7ff8c993e8f570d32755ba43ae17e02b007e Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:04 +0800
|
|
||||||
Subject: [PATCH 15/55] drivers/perf: hisi: Add PMU version for uncore PMU
|
|
||||||
drivers.
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.12-rc3
|
|
||||||
commit 3da582df575c3b2910e09e0445c27c3ebc8096e5
|
|
||||||
category: feature
|
|
||||||
bugzilla: 175148
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3da582df575c3b2910e09e0445c27c3ebc8096e5
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
For HiSilicon uncore PMU, more versions are supported and some variables
|
|
||||||
shall be added suffix to distinguish the version which are prepared for
|
|
||||||
the new drivers.
|
|
||||||
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Will Deacon <will@kernel.org>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Acked-by: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Link: https://lore.kernel.org/r/1615186237-22263-4-git-send-email-zhangshaokun@hisilicon.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 96 ++++++++++---------
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 27 +++---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 23 ++---
|
|
||||||
3 files changed, 75 insertions(+), 71 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index a03e3f8058b3..1d1c8e9f417e 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -39,7 +39,8 @@
|
|
||||||
|
|
||||||
/* DDRC has 8-counters */
|
|
||||||
#define DDRC_NR_COUNTERS 0x8
|
|
||||||
-#define DDRC_PERF_CTRL_EN 0x2
|
|
||||||
+#define DDRC_V1_PERF_CTRL_EN 0x2
|
|
||||||
+#define DDRC_V1_NR_EVENTS 0x7
|
|
||||||
|
|
||||||
/*
|
|
||||||
* For DDRC PMU, there are eight-events and every event has been mapped
|
|
||||||
@@ -56,26 +57,26 @@ static const u32 ddrc_reg_off[] = {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Select the counter register offset using the counter index.
|
|
||||||
- * In DDRC there are no programmable counter, the count
|
|
||||||
- * is readed form the statistics counter register itself.
|
|
||||||
+ * In PMU v1, there are no programmable counter, the count
|
|
||||||
+ * is read form the statistics counter register itself.
|
|
||||||
*/
|
|
||||||
-static u32 hisi_ddrc_pmu_get_counter_offset(int cntr_idx)
|
|
||||||
+static u32 hisi_ddrc_pmu_v1_get_counter_offset(int cntr_idx)
|
|
||||||
{
|
|
||||||
return ddrc_reg_off[cntr_idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
-static u64 hisi_ddrc_pmu_read_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+static u64 hisi_ddrc_pmu_v1_read_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
return readl(ddrc_pmu->base +
|
|
||||||
- hisi_ddrc_pmu_get_counter_offset(hwc->idx));
|
|
||||||
+ hisi_ddrc_pmu_v1_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void hisi_ddrc_pmu_write_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+static void hisi_ddrc_pmu_v1_write_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
struct hw_perf_event *hwc, u64 val)
|
|
||||||
{
|
|
||||||
writel((u32)val,
|
|
||||||
- ddrc_pmu->base + hisi_ddrc_pmu_get_counter_offset(hwc->idx));
|
|
||||||
+ ddrc_pmu->base + hisi_ddrc_pmu_v1_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
@@ -87,28 +88,28 @@ static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void hisi_ddrc_pmu_start_counters(struct hisi_pmu *ddrc_pmu)
|
|
||||||
+static void hisi_ddrc_pmu_v1_start_counters(struct hisi_pmu *ddrc_pmu)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
/* Set perf_enable in DDRC_PERF_CTRL to start event counting */
|
|
||||||
val = readl(ddrc_pmu->base + DDRC_PERF_CTRL);
|
|
||||||
- val |= DDRC_PERF_CTRL_EN;
|
|
||||||
+ val |= DDRC_V1_PERF_CTRL_EN;
|
|
||||||
writel(val, ddrc_pmu->base + DDRC_PERF_CTRL);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void hisi_ddrc_pmu_stop_counters(struct hisi_pmu *ddrc_pmu)
|
|
||||||
+static void hisi_ddrc_pmu_v1_stop_counters(struct hisi_pmu *ddrc_pmu)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
/* Clear perf_enable in DDRC_PERF_CTRL to stop event counting */
|
|
||||||
val = readl(ddrc_pmu->base + DDRC_PERF_CTRL);
|
|
||||||
- val &= ~DDRC_PERF_CTRL_EN;
|
|
||||||
+ val &= ~DDRC_V1_PERF_CTRL_EN;
|
|
||||||
writel(val, ddrc_pmu->base + DDRC_PERF_CTRL);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void hisi_ddrc_pmu_enable_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
+static void hisi_ddrc_pmu_v1_enable_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
@@ -118,8 +119,8 @@ static void hisi_ddrc_pmu_enable_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
writel(val, ddrc_pmu->base + DDRC_EVENT_CTRL);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void hisi_ddrc_pmu_disable_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
+static void hisi_ddrc_pmu_v1_disable_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
@@ -129,7 +130,7 @@ static void hisi_ddrc_pmu_disable_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
writel(val, ddrc_pmu->base + DDRC_EVENT_CTRL);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static int hisi_ddrc_pmu_get_event_idx(struct perf_event *event)
|
|
||||||
+static int hisi_ddrc_pmu_v1_get_event_idx(struct perf_event *event)
|
|
||||||
{
|
|
||||||
struct hisi_pmu *ddrc_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
unsigned long *used_mask = ddrc_pmu->pmu_events.used_mask;
|
|
||||||
@@ -145,8 +146,8 @@ static int hisi_ddrc_pmu_get_event_idx(struct perf_event *event)
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void hisi_ddrc_pmu_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
+static void hisi_ddrc_pmu_v1_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
@@ -156,8 +157,8 @@ static void hisi_ddrc_pmu_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void hisi_ddrc_pmu_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
- struct hw_perf_event *hwc)
|
|
||||||
+static void hisi_ddrc_pmu_v1_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
@@ -167,12 +168,13 @@ static void hisi_ddrc_pmu_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static u32 hisi_ddrc_pmu_get_int_status(struct hisi_pmu *ddrc_pmu)
|
|
||||||
+static u32 hisi_ddrc_pmu_v1_get_int_status(struct hisi_pmu *ddrc_pmu)
|
|
||||||
{
|
|
||||||
return readl(ddrc_pmu->base + DDRC_INT_STATUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void hisi_ddrc_pmu_clear_int_status(struct hisi_pmu *ddrc_pmu, int idx)
|
|
||||||
+static void hisi_ddrc_pmu_v1_clear_int_status(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ int idx)
|
|
||||||
{
|
|
||||||
writel(1 << idx, ddrc_pmu->base + DDRC_INT_CLEAR);
|
|
||||||
}
|
|
||||||
@@ -215,17 +217,17 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct attribute *hisi_ddrc_pmu_format_attr[] = {
|
|
||||||
+static struct attribute *hisi_ddrc_pmu_v1_format_attr[] = {
|
|
||||||
HISI_PMU_FORMAT_ATTR(event, "config:0-4"),
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct attribute_group hisi_ddrc_pmu_format_group = {
|
|
||||||
+static const struct attribute_group hisi_ddrc_pmu_v1_format_group = {
|
|
||||||
.name = "format",
|
|
||||||
- .attrs = hisi_ddrc_pmu_format_attr,
|
|
||||||
+ .attrs = hisi_ddrc_pmu_v1_format_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct attribute *hisi_ddrc_pmu_events_attr[] = {
|
|
||||||
+static struct attribute *hisi_ddrc_pmu_v1_events_attr[] = {
|
|
||||||
HISI_PMU_EVENT_ATTR(flux_wr, 0x00),
|
|
||||||
HISI_PMU_EVENT_ATTR(flux_rd, 0x01),
|
|
||||||
HISI_PMU_EVENT_ATTR(flux_wcmd, 0x02),
|
|
||||||
@@ -237,9 +239,9 @@ static struct attribute *hisi_ddrc_pmu_events_attr[] = {
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct attribute_group hisi_ddrc_pmu_events_group = {
|
|
||||||
+static const struct attribute_group hisi_ddrc_pmu_v1_events_group = {
|
|
||||||
.name = "events",
|
|
||||||
- .attrs = hisi_ddrc_pmu_events_attr,
|
|
||||||
+ .attrs = hisi_ddrc_pmu_v1_events_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
@@ -265,27 +267,27 @@ static struct attribute_group hisi_ddrc_pmu_identifier_group = {
|
|
||||||
.attrs = hisi_ddrc_pmu_identifier_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct attribute_group *hisi_ddrc_pmu_attr_groups[] = {
|
|
||||||
- &hisi_ddrc_pmu_format_group,
|
|
||||||
- &hisi_ddrc_pmu_events_group,
|
|
||||||
+static const struct attribute_group *hisi_ddrc_pmu_v1_attr_groups[] = {
|
|
||||||
+ &hisi_ddrc_pmu_v1_format_group,
|
|
||||||
+ &hisi_ddrc_pmu_v1_events_group,
|
|
||||||
&hisi_ddrc_pmu_cpumask_attr_group,
|
|
||||||
&hisi_ddrc_pmu_identifier_group,
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct hisi_uncore_ops hisi_uncore_ddrc_ops = {
|
|
||||||
+static const struct hisi_uncore_ops hisi_uncore_ddrc_v1_ops = {
|
|
||||||
.write_evtype = hisi_ddrc_pmu_write_evtype,
|
|
||||||
- .get_event_idx = hisi_ddrc_pmu_get_event_idx,
|
|
||||||
- .start_counters = hisi_ddrc_pmu_start_counters,
|
|
||||||
- .stop_counters = hisi_ddrc_pmu_stop_counters,
|
|
||||||
- .enable_counter = hisi_ddrc_pmu_enable_counter,
|
|
||||||
- .disable_counter = hisi_ddrc_pmu_disable_counter,
|
|
||||||
- .enable_counter_int = hisi_ddrc_pmu_enable_counter_int,
|
|
||||||
- .disable_counter_int = hisi_ddrc_pmu_disable_counter_int,
|
|
||||||
- .write_counter = hisi_ddrc_pmu_write_counter,
|
|
||||||
- .read_counter = hisi_ddrc_pmu_read_counter,
|
|
||||||
- .get_int_status = hisi_ddrc_pmu_get_int_status,
|
|
||||||
- .clear_int_status = hisi_ddrc_pmu_clear_int_status,
|
|
||||||
+ .get_event_idx = hisi_ddrc_pmu_v1_get_event_idx,
|
|
||||||
+ .start_counters = hisi_ddrc_pmu_v1_start_counters,
|
|
||||||
+ .stop_counters = hisi_ddrc_pmu_v1_stop_counters,
|
|
||||||
+ .enable_counter = hisi_ddrc_pmu_v1_enable_counter,
|
|
||||||
+ .disable_counter = hisi_ddrc_pmu_v1_disable_counter,
|
|
||||||
+ .enable_counter_int = hisi_ddrc_pmu_v1_enable_counter_int,
|
|
||||||
+ .disable_counter_int = hisi_ddrc_pmu_v1_disable_counter_int,
|
|
||||||
+ .write_counter = hisi_ddrc_pmu_v1_write_counter,
|
|
||||||
+ .read_counter = hisi_ddrc_pmu_v1_read_counter,
|
|
||||||
+ .get_int_status = hisi_ddrc_pmu_v1_get_int_status,
|
|
||||||
+ .clear_int_status = hisi_ddrc_pmu_v1_clear_int_status,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
@@ -303,10 +305,10 @@ static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
|
|
||||||
ddrc_pmu->num_counters = DDRC_NR_COUNTERS;
|
|
||||||
ddrc_pmu->counter_bits = 32;
|
|
||||||
- ddrc_pmu->ops = &hisi_uncore_ddrc_ops;
|
|
||||||
+ ddrc_pmu->ops = &hisi_uncore_ddrc_v1_ops;
|
|
||||||
ddrc_pmu->dev = &pdev->dev;
|
|
||||||
ddrc_pmu->on_cpu = -1;
|
|
||||||
- ddrc_pmu->check_event = 7;
|
|
||||||
+ ddrc_pmu->check_event = DDRC_V1_NR_EVENTS;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -348,7 +350,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
|
||||||
.start = hisi_uncore_pmu_start,
|
|
||||||
.stop = hisi_uncore_pmu_stop,
|
|
||||||
.read = hisi_uncore_pmu_read,
|
|
||||||
- .attr_groups = hisi_ddrc_pmu_attr_groups,
|
|
||||||
+ .attr_groups = hisi_ddrc_pmu_v1_attr_groups,
|
|
||||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index 536d1f637fa7..7941900ea667 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -36,10 +36,11 @@
|
|
||||||
#define HHA_CNT0_LOWER 0x1F00
|
|
||||||
|
|
||||||
/* HHA has 16-counters */
|
|
||||||
-#define HHA_NR_COUNTERS 0x10
|
|
||||||
+#define HHA_V1_NR_COUNTERS 0x10
|
|
||||||
|
|
||||||
#define HHA_PERF_CTRL_EN 0x1
|
|
||||||
#define HHA_EVTYPE_NONE 0xff
|
|
||||||
+#define HHA_V1_NR_EVENT 0x65
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Select the counter register offset using the counter index
|
|
||||||
@@ -209,17 +210,17 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct attribute *hisi_hha_pmu_format_attr[] = {
|
|
||||||
+static struct attribute *hisi_hha_pmu_v1_format_attr[] = {
|
|
||||||
HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct attribute_group hisi_hha_pmu_format_group = {
|
|
||||||
+static const struct attribute_group hisi_hha_pmu_v1_format_group = {
|
|
||||||
.name = "format",
|
|
||||||
- .attrs = hisi_hha_pmu_format_attr,
|
|
||||||
+ .attrs = hisi_hha_pmu_v1_format_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct attribute *hisi_hha_pmu_events_attr[] = {
|
|
||||||
+static struct attribute *hisi_hha_pmu_v1_events_attr[] = {
|
|
||||||
HISI_PMU_EVENT_ATTR(rx_ops_num, 0x00),
|
|
||||||
HISI_PMU_EVENT_ATTR(rx_outer, 0x01),
|
|
||||||
HISI_PMU_EVENT_ATTR(rx_sccl, 0x02),
|
|
||||||
@@ -249,9 +250,9 @@ static struct attribute *hisi_hha_pmu_events_attr[] = {
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct attribute_group hisi_hha_pmu_events_group = {
|
|
||||||
+static const struct attribute_group hisi_hha_pmu_v1_events_group = {
|
|
||||||
.name = "events",
|
|
||||||
- .attrs = hisi_hha_pmu_events_attr,
|
|
||||||
+ .attrs = hisi_hha_pmu_v1_events_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
@@ -277,9 +278,9 @@ static struct attribute_group hisi_hha_pmu_identifier_group = {
|
|
||||||
.attrs = hisi_hha_pmu_identifier_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct attribute_group *hisi_hha_pmu_attr_groups[] = {
|
|
||||||
- &hisi_hha_pmu_format_group,
|
|
||||||
- &hisi_hha_pmu_events_group,
|
|
||||||
+static const struct attribute_group *hisi_hha_pmu_v1_attr_groups[] = {
|
|
||||||
+ &hisi_hha_pmu_v1_format_group,
|
|
||||||
+ &hisi_hha_pmu_v1_events_group,
|
|
||||||
&hisi_hha_pmu_cpumask_attr_group,
|
|
||||||
&hisi_hha_pmu_identifier_group,
|
|
||||||
NULL,
|
|
||||||
@@ -313,12 +314,12 @@ static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- hha_pmu->num_counters = HHA_NR_COUNTERS;
|
|
||||||
+ hha_pmu->num_counters = HHA_V1_NR_COUNTERS;
|
|
||||||
hha_pmu->counter_bits = 48;
|
|
||||||
hha_pmu->ops = &hisi_uncore_hha_ops;
|
|
||||||
hha_pmu->dev = &pdev->dev;
|
|
||||||
hha_pmu->on_cpu = -1;
|
|
||||||
- hha_pmu->check_event = 0x65;
|
|
||||||
+ hha_pmu->check_event = HHA_V1_NR_EVENT;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -360,7 +361,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
|
||||||
.start = hisi_uncore_pmu_start,
|
|
||||||
.stop = hisi_uncore_pmu_stop,
|
|
||||||
.read = hisi_uncore_pmu_read,
|
|
||||||
- .attr_groups = hisi_hha_pmu_attr_groups,
|
|
||||||
+ .attr_groups = hisi_hha_pmu_v1_attr_groups,
|
|
||||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index 5256e4ce3384..5a4975e64368 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -40,6 +40,7 @@
|
|
||||||
|
|
||||||
#define L3C_PERF_CTRL_EN 0x10000
|
|
||||||
#define L3C_EVTYPE_NONE 0xff
|
|
||||||
+#define L3C_V1_NR_EVENTS 0x59
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Select the counter register offset using the counter index
|
|
||||||
@@ -212,17 +213,17 @@ static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static struct attribute *hisi_l3c_pmu_format_attr[] = {
|
|
||||||
+static struct attribute *hisi_l3c_pmu_v1_format_attr[] = {
|
|
||||||
HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct attribute_group hisi_l3c_pmu_format_group = {
|
|
||||||
+static const struct attribute_group hisi_l3c_pmu_v1_format_group = {
|
|
||||||
.name = "format",
|
|
||||||
- .attrs = hisi_l3c_pmu_format_attr,
|
|
||||||
+ .attrs = hisi_l3c_pmu_v1_format_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static struct attribute *hisi_l3c_pmu_events_attr[] = {
|
|
||||||
+static struct attribute *hisi_l3c_pmu_v1_events_attr[] = {
|
|
||||||
HISI_PMU_EVENT_ATTR(rd_cpipe, 0x00),
|
|
||||||
HISI_PMU_EVENT_ATTR(wr_cpipe, 0x01),
|
|
||||||
HISI_PMU_EVENT_ATTR(rd_hit_cpipe, 0x02),
|
|
||||||
@@ -239,9 +240,9 @@ static struct attribute *hisi_l3c_pmu_events_attr[] = {
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct attribute_group hisi_l3c_pmu_events_group = {
|
|
||||||
+static const struct attribute_group hisi_l3c_pmu_v1_events_group = {
|
|
||||||
.name = "events",
|
|
||||||
- .attrs = hisi_l3c_pmu_events_attr,
|
|
||||||
+ .attrs = hisi_l3c_pmu_v1_events_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
@@ -267,9 +268,9 @@ static struct attribute_group hisi_l3c_pmu_identifier_group = {
|
|
||||||
.attrs = hisi_l3c_pmu_identifier_attrs,
|
|
||||||
};
|
|
||||||
|
|
||||||
-static const struct attribute_group *hisi_l3c_pmu_attr_groups[] = {
|
|
||||||
- &hisi_l3c_pmu_format_group,
|
|
||||||
- &hisi_l3c_pmu_events_group,
|
|
||||||
+static const struct attribute_group *hisi_l3c_pmu_v1_attr_groups[] = {
|
|
||||||
+ &hisi_l3c_pmu_v1_format_group,
|
|
||||||
+ &hisi_l3c_pmu_v1_events_group,
|
|
||||||
&hisi_l3c_pmu_cpumask_attr_group,
|
|
||||||
&hisi_l3c_pmu_identifier_group,
|
|
||||||
NULL,
|
|
||||||
@@ -308,7 +309,7 @@ static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
l3c_pmu->ops = &hisi_uncore_l3c_ops;
|
|
||||||
l3c_pmu->dev = &pdev->dev;
|
|
||||||
l3c_pmu->on_cpu = -1;
|
|
||||||
- l3c_pmu->check_event = 0x59;
|
|
||||||
+ l3c_pmu->check_event = L3C_V1_NR_EVENTS;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -350,7 +351,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
|
||||||
.start = hisi_uncore_pmu_start,
|
|
||||||
.stop = hisi_uncore_pmu_stop,
|
|
||||||
.read = hisi_uncore_pmu_read,
|
|
||||||
- .attr_groups = hisi_l3c_pmu_attr_groups,
|
|
||||||
+ .attr_groups = hisi_l3c_pmu_v1_attr_groups,
|
|
||||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,505 +0,0 @@
|
|||||||
From d4d47e781c088759005a0a6dc4e843a8bfeb5bdd Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:05 +0800
|
|
||||||
Subject: [PATCH 16/55] drivers/perf: hisi: Add new functions for L3C PMU
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.12-rc3
|
|
||||||
commit 486a7f46b966a825484808d4edf53bbe02698fb3
|
|
||||||
category: feature
|
|
||||||
bugzilla: 175148
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=486a7f46b966a825484808d4edf53bbe02698fb3
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
On HiSilicon Hip09 platform, some new functions are enhanced on L3C PMU:
|
|
||||||
|
|
||||||
* tt_req: it is the abbreviation of tracetag request and allows user to
|
|
||||||
count only read/write/atomic operations. tt_req is 3-bit and details are
|
|
||||||
listed in the hisi-pmu document.
|
|
||||||
$# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_req=0x4/ sleep 5
|
|
||||||
|
|
||||||
* tt_core: it is the abbreviation of tracetag core and allows user to
|
|
||||||
filter by core/thread within the cluster, it is a 8-bit bitmap that each
|
|
||||||
bit represents the corresponding core/thread in this L3C.
|
|
||||||
$# perf stat -a -e hisi_sccl3_l3c0/config=0x02,tt_core=0xf/ sleep 5
|
|
||||||
|
|
||||||
* datasrc_cfg: it is the abbreviation of data source configuration and
|
|
||||||
allows user to check where the data comes from, such as: from local DDR,
|
|
||||||
cross-die DDR or cross-socket DDR. Its is 5-bit and represents different
|
|
||||||
data source in the SoC.
|
|
||||||
$# perf stat -a -e hisi_sccl3_l3c0/dat_access,datasrc_cfg=0xe/ sleep 5
|
|
||||||
|
|
||||||
* datasrc_skt: it is the abbreviation of data source from another socket
|
|
||||||
and is used in the multi-chips, if user wants to check the cross-socket
|
|
||||||
datat source, it shall be added in perf command. Only one bit is used to
|
|
||||||
control this.
|
|
||||||
$# perf stat -a -e hisi_sccl3_l3c0/dat_access,datasrc_cfg=0x10,datasrc_skt=1/ sleep 5
|
|
||||||
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Will Deacon <will@kernel.org>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Link: https://lore.kernel.org/r/1615186237-22263-5-git-send-email-zhangshaokun@hisilicon.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 259 +++++++++++++++++--
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 8 +-
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 11 +
|
|
||||||
3 files changed, 258 insertions(+), 20 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index 5a4975e64368..87ca2a9ca8c5 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -26,12 +26,17 @@
|
|
||||||
#define L3C_INT_MASK 0x0800
|
|
||||||
#define L3C_INT_STATUS 0x0808
|
|
||||||
#define L3C_INT_CLEAR 0x080c
|
|
||||||
+#define L3C_CORE_CTRL 0x1b04
|
|
||||||
+#define L3C_TRACETAG_CTRL 0x1b20
|
|
||||||
+#define L3C_DATSRC_TYPE 0x1b48
|
|
||||||
+#define L3C_DATSRC_CTRL 0x1bf0
|
|
||||||
#define L3C_EVENT_CTRL 0x1c00
|
|
||||||
#define L3C_VERSION 0x1cf0
|
|
||||||
#define L3C_EVENT_TYPE0 0x1d00
|
|
||||||
/*
|
|
||||||
- * Each counter is 48-bits and [48:63] are reserved
|
|
||||||
- * which are Read-As-Zero and Writes-Ignored.
|
|
||||||
+ * If the HW version only supports a 48-bit counter, then
|
|
||||||
+ * bits [63:48] are reserved, which are Read-As-Zero and
|
|
||||||
+ * Writes-Ignored.
|
|
||||||
*/
|
|
||||||
#define L3C_CNTR0_LOWER 0x1e00
|
|
||||||
|
|
||||||
@@ -39,8 +44,186 @@
|
|
||||||
#define L3C_NR_COUNTERS 0x8
|
|
||||||
|
|
||||||
#define L3C_PERF_CTRL_EN 0x10000
|
|
||||||
+#define L3C_TRACETAG_EN BIT(31)
|
|
||||||
+#define L3C_TRACETAG_REQ_SHIFT 7
|
|
||||||
+#define L3C_TRACETAG_MARK_EN BIT(0)
|
|
||||||
+#define L3C_TRACETAG_REQ_EN (L3C_TRACETAG_MARK_EN | BIT(2))
|
|
||||||
+#define L3C_TRACETAG_CORE_EN (L3C_TRACETAG_MARK_EN | BIT(3))
|
|
||||||
+#define L3C_CORE_EN BIT(20)
|
|
||||||
+#define L3C_COER_NONE 0x0
|
|
||||||
+#define L3C_DATSRC_MASK 0xFF
|
|
||||||
+#define L3C_DATSRC_SKT_EN BIT(23)
|
|
||||||
+#define L3C_DATSRC_NONE 0x0
|
|
||||||
#define L3C_EVTYPE_NONE 0xff
|
|
||||||
#define L3C_V1_NR_EVENTS 0x59
|
|
||||||
+#define L3C_V2_NR_EVENTS 0xFF
|
|
||||||
+
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tt_core, config1, 7, 0);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tt_req, config1, 10, 8);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(datasrc_cfg, config1, 15, 11);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(datasrc_skt, config1, 16, 16);
|
|
||||||
+
|
|
||||||
+static void hisi_l3c_pmu_config_req_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 tt_req = hisi_get_tt_req(event);
|
|
||||||
+
|
|
||||||
+ if (tt_req) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ /* Set request-type for tracetag */
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_TRACETAG_CTRL);
|
|
||||||
+ val |= tt_req << L3C_TRACETAG_REQ_SHIFT;
|
|
||||||
+ val |= L3C_TRACETAG_REQ_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_TRACETAG_CTRL);
|
|
||||||
+
|
|
||||||
+ /* Enable request-tracetag statistics */
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_PERF_CTRL);
|
|
||||||
+ val |= L3C_TRACETAG_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_PERF_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_l3c_pmu_clear_req_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 tt_req = hisi_get_tt_req(event);
|
|
||||||
+
|
|
||||||
+ if (tt_req) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ /* Clear request-type */
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_TRACETAG_CTRL);
|
|
||||||
+ val &= ~(tt_req << L3C_TRACETAG_REQ_SHIFT);
|
|
||||||
+ val &= ~L3C_TRACETAG_REQ_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_TRACETAG_CTRL);
|
|
||||||
+
|
|
||||||
+ /* Disable request-tracetag statistics */
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_PERF_CTRL);
|
|
||||||
+ val &= ~L3C_TRACETAG_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_PERF_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_l3c_pmu_write_ds(struct perf_event *event, u32 ds_cfg)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ struct hw_perf_event *hwc = &event->hw;
|
|
||||||
+ u32 reg, reg_idx, shift, val;
|
|
||||||
+ int idx = hwc->idx;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Select the appropriate datasource register(L3C_DATSRC_TYPE0/1).
|
|
||||||
+ * There are 2 datasource ctrl register for the 8 hardware counters.
|
|
||||||
+ * Datasrc is 8-bits and for the former 4 hardware counters,
|
|
||||||
+ * L3C_DATSRC_TYPE0 is chosen. For the latter 4 hardware counters,
|
|
||||||
+ * L3C_DATSRC_TYPE1 is chosen.
|
|
||||||
+ */
|
|
||||||
+ reg = L3C_DATSRC_TYPE + (idx / 4) * 4;
|
|
||||||
+ reg_idx = idx % 4;
|
|
||||||
+ shift = 8 * reg_idx;
|
|
||||||
+
|
|
||||||
+ val = readl(l3c_pmu->base + reg);
|
|
||||||
+ val &= ~(L3C_DATSRC_MASK << shift);
|
|
||||||
+ val |= ds_cfg << shift;
|
|
||||||
+ writel(val, l3c_pmu->base + reg);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_l3c_pmu_config_ds(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 ds_cfg = hisi_get_datasrc_cfg(event);
|
|
||||||
+ u32 ds_skt = hisi_get_datasrc_skt(event);
|
|
||||||
+
|
|
||||||
+ if (ds_cfg)
|
|
||||||
+ hisi_l3c_pmu_write_ds(event, ds_cfg);
|
|
||||||
+
|
|
||||||
+ if (ds_skt) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_DATSRC_CTRL);
|
|
||||||
+ val |= L3C_DATSRC_SKT_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_DATSRC_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_l3c_pmu_clear_ds(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 ds_cfg = hisi_get_datasrc_cfg(event);
|
|
||||||
+ u32 ds_skt = hisi_get_datasrc_skt(event);
|
|
||||||
+
|
|
||||||
+ if (ds_cfg)
|
|
||||||
+ hisi_l3c_pmu_write_ds(event, L3C_DATSRC_NONE);
|
|
||||||
+
|
|
||||||
+ if (ds_skt) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_DATSRC_CTRL);
|
|
||||||
+ val &= ~L3C_DATSRC_SKT_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_DATSRC_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_l3c_pmu_config_core_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 core = hisi_get_tt_core(event);
|
|
||||||
+
|
|
||||||
+ if (core) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ /* Config and enable core information */
|
|
||||||
+ writel(core, l3c_pmu->base + L3C_CORE_CTRL);
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_PERF_CTRL);
|
|
||||||
+ val |= L3C_CORE_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_PERF_CTRL);
|
|
||||||
+
|
|
||||||
+ /* Enable core-tracetag statistics */
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_TRACETAG_CTRL);
|
|
||||||
+ val |= L3C_TRACETAG_CORE_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_TRACETAG_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_l3c_pmu_clear_core_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *l3c_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 core = hisi_get_tt_core(event);
|
|
||||||
+
|
|
||||||
+ if (core) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ /* Clear core information */
|
|
||||||
+ writel(L3C_COER_NONE, l3c_pmu->base + L3C_CORE_CTRL);
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_PERF_CTRL);
|
|
||||||
+ val &= ~L3C_CORE_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_PERF_CTRL);
|
|
||||||
+
|
|
||||||
+ /* Disable core-tracetag statistics */
|
|
||||||
+ val = readl(l3c_pmu->base + L3C_TRACETAG_CTRL);
|
|
||||||
+ val &= ~L3C_TRACETAG_CORE_EN;
|
|
||||||
+ writel(val, l3c_pmu->base + L3C_TRACETAG_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_l3c_pmu_enable_filter(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ if (event->attr.config1 != 0x0) {
|
|
||||||
+ hisi_l3c_pmu_config_req_tracetag(event);
|
|
||||||
+ hisi_l3c_pmu_config_core_tracetag(event);
|
|
||||||
+ hisi_l3c_pmu_config_ds(event);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_l3c_pmu_disable_filter(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ if (event->attr.config1 != 0x0) {
|
|
||||||
+ hisi_l3c_pmu_clear_ds(event);
|
|
||||||
+ hisi_l3c_pmu_clear_core_tracetag(event);
|
|
||||||
+ hisi_l3c_pmu_clear_req_tracetag(event);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Select the counter register offset using the counter index
|
|
||||||
@@ -53,14 +236,12 @@ static u32 hisi_l3c_pmu_get_counter_offset(u32 cntr_idx)
|
|
||||||
static u64 hisi_l3c_pmu_read_counter(struct hisi_pmu *l3c_pmu,
|
|
||||||
struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
- /* Read 64-bits and the upper 16 bits are RAZ */
|
|
||||||
return readq(l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hisi_l3c_pmu_write_counter(struct hisi_pmu *l3c_pmu,
|
|
||||||
struct hw_perf_event *hwc, u64 val)
|
|
||||||
{
|
|
||||||
- /* Write 64-bits and the upper 16 bits are WI */
|
|
||||||
writeq(val, l3c_pmu->base + hisi_l3c_pmu_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -169,23 +350,14 @@ static void hisi_l3c_pmu_clear_int_status(struct hisi_pmu *l3c_pmu, int idx)
|
|
||||||
|
|
||||||
static const struct acpi_device_id hisi_l3c_pmu_acpi_match[] = {
|
|
||||||
{ "HISI0213", },
|
|
||||||
- {},
|
|
||||||
+ { "HISI0214", },
|
|
||||||
+ {}
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(acpi, hisi_l3c_pmu_acpi_match);
|
|
||||||
|
|
||||||
static int hisi_l3c_pmu_init_data(struct platform_device *pdev,
|
|
||||||
struct hisi_pmu *l3c_pmu)
|
|
||||||
{
|
|
||||||
- unsigned long long id;
|
|
||||||
- acpi_status status;
|
|
||||||
-
|
|
||||||
- status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
|
||||||
- "_UID", NULL, &id);
|
|
||||||
- if (ACPI_FAILURE(status))
|
|
||||||
- return -EINVAL;
|
|
||||||
-
|
|
||||||
- l3c_pmu->index_id = id;
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Use the SCCL_ID and CCL_ID to identify the L3C PMU, while
|
|
||||||
* SCCL_ID is in MPIDR[aff2] and CCL_ID is in MPIDR[aff1].
|
|
||||||
@@ -223,6 +395,20 @@ static const struct attribute_group hisi_l3c_pmu_v1_format_group = {
|
|
||||||
.attrs = hisi_l3c_pmu_v1_format_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct attribute *hisi_l3c_pmu_v2_format_attr[] = {
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(tt_core, "config1:0-7"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(tt_req, "config1:8-10"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(datasrc_cfg, "config1:11-15"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(datasrc_skt, "config1:16"),
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_l3c_pmu_v2_format_group = {
|
|
||||||
+ .name = "format",
|
|
||||||
+ .attrs = hisi_l3c_pmu_v2_format_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static struct attribute *hisi_l3c_pmu_v1_events_attr[] = {
|
|
||||||
HISI_PMU_EVENT_ATTR(rd_cpipe, 0x00),
|
|
||||||
HISI_PMU_EVENT_ATTR(wr_cpipe, 0x01),
|
|
||||||
@@ -245,6 +431,19 @@ static const struct attribute_group hisi_l3c_pmu_v1_events_group = {
|
|
||||||
.attrs = hisi_l3c_pmu_v1_events_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct attribute *hisi_l3c_pmu_v2_events_attr[] = {
|
|
||||||
+ HISI_PMU_EVENT_ATTR(l3c_hit, 0x48),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(cycles, 0x7f),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(l3c_ref, 0xb8),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(dat_access, 0xb9),
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_l3c_pmu_v2_events_group = {
|
|
||||||
+ .name = "events",
|
|
||||||
+ .attrs = hisi_l3c_pmu_v2_events_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
|
|
||||||
static struct attribute *hisi_l3c_pmu_cpumask_attrs[] = {
|
|
||||||
@@ -276,6 +475,14 @@ static const struct attribute_group *hisi_l3c_pmu_v1_attr_groups[] = {
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const struct attribute_group *hisi_l3c_pmu_v2_attr_groups[] = {
|
|
||||||
+ &hisi_l3c_pmu_v2_format_group,
|
|
||||||
+ &hisi_l3c_pmu_v2_events_group,
|
|
||||||
+ &hisi_l3c_pmu_cpumask_attr_group,
|
|
||||||
+ &hisi_l3c_pmu_identifier_group,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const struct hisi_uncore_ops hisi_uncore_l3c_ops = {
|
|
||||||
.write_evtype = hisi_l3c_pmu_write_evtype,
|
|
||||||
.get_event_idx = hisi_uncore_pmu_get_event_idx,
|
|
||||||
@@ -289,6 +496,8 @@ static const struct hisi_uncore_ops hisi_uncore_l3c_ops = {
|
|
||||||
.read_counter = hisi_l3c_pmu_read_counter,
|
|
||||||
.get_int_status = hisi_l3c_pmu_get_int_status,
|
|
||||||
.clear_int_status = hisi_l3c_pmu_clear_int_status,
|
|
||||||
+ .enable_filter = hisi_l3c_pmu_enable_filter,
|
|
||||||
+ .disable_filter = hisi_l3c_pmu_disable_filter,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
@@ -304,12 +513,20 @@ static int hisi_l3c_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
+ if (l3c_pmu->identifier >= HISI_PMU_V2) {
|
|
||||||
+ l3c_pmu->counter_bits = 64;
|
|
||||||
+ l3c_pmu->check_event = L3C_V2_NR_EVENTS;
|
|
||||||
+ l3c_pmu->pmu_events.attr_groups = hisi_l3c_pmu_v2_attr_groups;
|
|
||||||
+ } else {
|
|
||||||
+ l3c_pmu->counter_bits = 48;
|
|
||||||
+ l3c_pmu->check_event = L3C_V1_NR_EVENTS;
|
|
||||||
+ l3c_pmu->pmu_events.attr_groups = hisi_l3c_pmu_v1_attr_groups;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
l3c_pmu->num_counters = L3C_NR_COUNTERS;
|
|
||||||
- l3c_pmu->counter_bits = 48;
|
|
||||||
l3c_pmu->ops = &hisi_uncore_l3c_ops;
|
|
||||||
l3c_pmu->dev = &pdev->dev;
|
|
||||||
l3c_pmu->on_cpu = -1;
|
|
||||||
- l3c_pmu->check_event = L3C_V1_NR_EVENTS;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -337,8 +554,12 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ /*
|
|
||||||
+ * CCL_ID is used to identify the L3C in the same SCCL which was
|
|
||||||
+ * used _UID by mistake.
|
|
||||||
+ */
|
|
||||||
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_l3c%u",
|
|
||||||
- l3c_pmu->sccl_id, l3c_pmu->index_id);
|
|
||||||
+ l3c_pmu->sccl_id, l3c_pmu->ccl_id);
|
|
||||||
l3c_pmu->pmu = (struct pmu) {
|
|
||||||
.name = name,
|
|
||||||
.module = THIS_MODULE,
|
|
||||||
@@ -351,7 +572,7 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
|
||||||
.start = hisi_uncore_pmu_start,
|
|
||||||
.stop = hisi_uncore_pmu_stop,
|
|
||||||
.read = hisi_uncore_pmu_read,
|
|
||||||
- .attr_groups = hisi_l3c_pmu_v1_attr_groups,
|
|
||||||
+ .attr_groups = l3c_pmu->pmu_events.attr_groups,
|
|
||||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
index 53ac9f062c0f..c0f221e39aff 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
@@ -24,7 +24,7 @@
|
|
||||||
#include "hisi_uncore_pmu.h"
|
|
||||||
|
|
||||||
#define HISI_GET_EVENTID(ev) (ev->hw.config_base & 0xff)
|
|
||||||
-#define HISI_MAX_PERIOD(nr) (BIT_ULL(nr) - 1)
|
|
||||||
+#define HISI_MAX_PERIOD(nr) (GENMASK_ULL((nr) - 1, 0))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PMU format attributes
|
|
||||||
@@ -248,6 +248,9 @@ static void hisi_uncore_pmu_enable_event(struct perf_event *event)
|
|
||||||
hisi_pmu->ops->write_evtype(hisi_pmu, hwc->idx,
|
|
||||||
HISI_GET_EVENTID(event));
|
|
||||||
|
|
||||||
+ if (hisi_pmu->ops->enable_filter)
|
|
||||||
+ hisi_pmu->ops->enable_filter(event);
|
|
||||||
+
|
|
||||||
hisi_pmu->ops->enable_counter_int(hisi_pmu, hwc);
|
|
||||||
hisi_pmu->ops->enable_counter(hisi_pmu, hwc);
|
|
||||||
}
|
|
||||||
@@ -262,6 +265,9 @@ static void hisi_uncore_pmu_disable_event(struct perf_event *event)
|
|
||||||
|
|
||||||
hisi_pmu->ops->disable_counter(hisi_pmu, hwc);
|
|
||||||
hisi_pmu->ops->disable_counter_int(hisi_pmu, hwc);
|
|
||||||
+
|
|
||||||
+ if (hisi_pmu->ops->disable_filter)
|
|
||||||
+ hisi_pmu->ops->disable_filter(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void hisi_uncore_pmu_set_event_period(struct perf_event *event)
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
index 3336723e8cf6..1147dbd25344 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
@@ -14,6 +14,7 @@
|
|
||||||
#ifndef __HISI_UNCORE_PMU_H__
|
|
||||||
#define __HISI_UNCORE_PMU_H__
|
|
||||||
|
|
||||||
+#include <linux/bitfield.h>
|
|
||||||
#include <linux/cpumask.h>
|
|
||||||
#include <linux/device.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
@@ -25,6 +26,7 @@
|
|
||||||
#undef pr_fmt
|
|
||||||
#define pr_fmt(fmt) "hisi_pmu: " fmt
|
|
||||||
|
|
||||||
+#define HISI_PMU_V2 0x30
|
|
||||||
#define HISI_MAX_COUNTERS 0x10
|
|
||||||
#define to_hisi_pmu(p) (container_of(p, struct hisi_pmu, pmu))
|
|
||||||
|
|
||||||
@@ -38,6 +40,12 @@
|
|
||||||
#define HISI_PMU_EVENT_ATTR(_name, _config) \
|
|
||||||
HISI_PMU_ATTR(_name, hisi_event_sysfs_show, (unsigned long)_config)
|
|
||||||
|
|
||||||
+#define HISI_PMU_EVENT_ATTR_EXTRACTOR(name, config, hi, lo) \
|
|
||||||
+ static inline u32 hisi_get_##name(struct perf_event *event) \
|
|
||||||
+ { \
|
|
||||||
+ return FIELD_GET(GENMASK_ULL(hi, lo), event->attr.config); \
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
struct hisi_pmu;
|
|
||||||
|
|
||||||
struct hisi_uncore_ops {
|
|
||||||
@@ -53,11 +61,14 @@ struct hisi_uncore_ops {
|
|
||||||
void (*stop_counters)(struct hisi_pmu *);
|
|
||||||
u32 (*get_int_status)(struct hisi_pmu *hisi_pmu);
|
|
||||||
void (*clear_int_status)(struct hisi_pmu *hisi_pmu, int idx);
|
|
||||||
+ void (*enable_filter)(struct perf_event *event);
|
|
||||||
+ void (*disable_filter)(struct perf_event *event);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hisi_pmu_hwevents {
|
|
||||||
struct perf_event *hw_events[HISI_MAX_COUNTERS];
|
|
||||||
DECLARE_BITMAP(used_mask, HISI_MAX_COUNTERS);
|
|
||||||
+ const struct attribute_group **attr_groups;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Generic pmu struct for different pmu types */
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,340 +0,0 @@
|
|||||||
From 77e91e65e043b7cec81e193b005ead3183316bb6 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:06 +0800
|
|
||||||
Subject: [PATCH 17/55] drivers/perf: hisi: Add new functions for HHA PMU
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.12-rc3
|
|
||||||
commit 932f6a99f9b0c6b7039a5e2ce961009a8dc8c07c
|
|
||||||
category: feature
|
|
||||||
bugzilla: 175148
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=932f6a99f9b0c6b7039a5e2ce961009a8dc8c07c
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
On HiSilicon Hip09 platform, some new functions are also supported on
|
|
||||||
HHA PMU.
|
|
||||||
|
|
||||||
* tracetag_en: it is the abbreviation of tracetag enable and allows user
|
|
||||||
to count events according to tt_req or tt_core set in L3C PMU.
|
|
||||||
|
|
||||||
* datasrc_skt: it is the abbreviation of data source from another
|
|
||||||
socket and it is used in the multi-chips. It's the same as L3C PMU.
|
|
||||||
|
|
||||||
* srcid_cmd & srcid_msk: pair of the fields are used to filter
|
|
||||||
statistics that come from the specific CCL/ICL by the configuration.
|
|
||||||
These are the abbreviation of source ID command and mask. The source
|
|
||||||
ID is 11-bit and detailed descriptions are documented in
|
|
||||||
Documentation/admin-guide/perf/hisi-pmu.rst.
|
|
||||||
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Will Deacon <will@kernel.org>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Link: https://lore.kernel.org/r/1615186237-22263-6-git-send-email-zhangshaokun@hisilicon.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 203 +++++++++++++++++--
|
|
||||||
1 file changed, 188 insertions(+), 15 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index 7941900ea667..a7e1749fc3e4 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -28,19 +28,136 @@
|
|
||||||
#define HHA_VERSION 0x1cf0
|
|
||||||
#define HHA_PERF_CTRL 0x1E00
|
|
||||||
#define HHA_EVENT_CTRL 0x1E04
|
|
||||||
+#define HHA_SRCID_CTRL 0x1E08
|
|
||||||
+#define HHA_DATSRC_CTRL 0x1BF0
|
|
||||||
#define HHA_EVENT_TYPE0 0x1E80
|
|
||||||
/*
|
|
||||||
- * Each counter is 48-bits and [48:63] are reserved
|
|
||||||
- * which are Read-As-Zero and Writes-Ignored.
|
|
||||||
+ * If the HW version only supports a 48-bit counter, then
|
|
||||||
+ * bits [63:48] are reserved, which are Read-As-Zero and
|
|
||||||
+ * Writes-Ignored.
|
|
||||||
*/
|
|
||||||
#define HHA_CNT0_LOWER 0x1F00
|
|
||||||
|
|
||||||
-/* HHA has 16-counters */
|
|
||||||
+/* HHA PMU v1 has 16 counters and v2 only has 8 counters */
|
|
||||||
#define HHA_V1_NR_COUNTERS 0x10
|
|
||||||
+#define HHA_V2_NR_COUNTERS 0x8
|
|
||||||
|
|
||||||
#define HHA_PERF_CTRL_EN 0x1
|
|
||||||
+#define HHA_TRACETAG_EN BIT(31)
|
|
||||||
+#define HHA_SRCID_EN BIT(2)
|
|
||||||
+#define HHA_SRCID_CMD_SHIFT 6
|
|
||||||
+#define HHA_SRCID_MSK_SHIFT 20
|
|
||||||
+#define HHA_SRCID_CMD GENMASK(16, 6)
|
|
||||||
+#define HHA_SRCID_MSK GENMASK(30, 20)
|
|
||||||
+#define HHA_DATSRC_SKT_EN BIT(23)
|
|
||||||
#define HHA_EVTYPE_NONE 0xff
|
|
||||||
#define HHA_V1_NR_EVENT 0x65
|
|
||||||
+#define HHA_V2_NR_EVENT 0xCE
|
|
||||||
+
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_cmd, config1, 10, 0);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_msk, config1, 21, 11);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tracetag_en, config1, 22, 22);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(datasrc_skt, config1, 23, 23);
|
|
||||||
+
|
|
||||||
+static void hisi_hha_pmu_enable_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
|
||||||
+
|
|
||||||
+ if (tt_en) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(hha_pmu->base + HHA_SRCID_CTRL);
|
|
||||||
+ val |= HHA_TRACETAG_EN;
|
|
||||||
+ writel(val, hha_pmu->base + HHA_SRCID_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_hha_pmu_clear_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(hha_pmu->base + HHA_SRCID_CTRL);
|
|
||||||
+ val &= ~HHA_TRACETAG_EN;
|
|
||||||
+ writel(val, hha_pmu->base + HHA_SRCID_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_hha_pmu_config_ds(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 ds_skt = hisi_get_datasrc_skt(event);
|
|
||||||
+
|
|
||||||
+ if (ds_skt) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(hha_pmu->base + HHA_DATSRC_CTRL);
|
|
||||||
+ val |= HHA_DATSRC_SKT_EN;
|
|
||||||
+ writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_hha_pmu_clear_ds(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 ds_skt = hisi_get_datasrc_skt(event);
|
|
||||||
+
|
|
||||||
+ if (ds_skt) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(hha_pmu->base + HHA_DATSRC_CTRL);
|
|
||||||
+ val &= ~HHA_DATSRC_SKT_EN;
|
|
||||||
+ writel(ds_skt, hha_pmu->base + HHA_DATSRC_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_hha_pmu_config_srcid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
|
||||||
+
|
|
||||||
+ if (cmd) {
|
|
||||||
+ u32 val, msk;
|
|
||||||
+
|
|
||||||
+ msk = hisi_get_srcid_msk(event);
|
|
||||||
+ val = readl(hha_pmu->base + HHA_SRCID_CTRL);
|
|
||||||
+ val |= HHA_SRCID_EN | (cmd << HHA_SRCID_CMD_SHIFT) |
|
|
||||||
+ (msk << HHA_SRCID_MSK_SHIFT);
|
|
||||||
+ writel(val, hha_pmu->base + HHA_SRCID_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_hha_pmu_disable_srcid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *hha_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
|
||||||
+
|
|
||||||
+ if (cmd) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(hha_pmu->base + HHA_SRCID_CTRL);
|
|
||||||
+ val &= ~(HHA_SRCID_EN | HHA_SRCID_MSK | HHA_SRCID_CMD);
|
|
||||||
+ writel(val, hha_pmu->base + HHA_SRCID_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_hha_pmu_enable_filter(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ if (event->attr.config1 != 0x0) {
|
|
||||||
+ hisi_hha_pmu_enable_tracetag(event);
|
|
||||||
+ hisi_hha_pmu_config_ds(event);
|
|
||||||
+ hisi_hha_pmu_config_srcid(event);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_hha_pmu_disable_filter(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ if (event->attr.config1 != 0x0) {
|
|
||||||
+ hisi_hha_pmu_disable_srcid(event);
|
|
||||||
+ hisi_hha_pmu_clear_ds(event);
|
|
||||||
+ hisi_hha_pmu_clear_tracetag(event);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Select the counter register offset using the counter index
|
|
||||||
@@ -170,7 +287,8 @@ static void hisi_hha_pmu_clear_int_status(struct hisi_pmu *hha_pmu, int idx)
|
|
||||||
|
|
||||||
static const struct acpi_device_id hisi_hha_pmu_acpi_match[] = {
|
|
||||||
{ "HISI0243", },
|
|
||||||
- {},
|
|
||||||
+ { "HISI0244", },
|
|
||||||
+ {}
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(acpi, hisi_hha_pmu_acpi_match);
|
|
||||||
|
|
||||||
@@ -180,13 +298,6 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|
||||||
unsigned long long id;
|
|
||||||
acpi_status status;
|
|
||||||
|
|
||||||
- status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
|
||||||
- "_UID", NULL, &id);
|
|
||||||
- if (ACPI_FAILURE(status))
|
|
||||||
- return -EINVAL;
|
|
||||||
-
|
|
||||||
- hha_pmu->index_id = id;
|
|
||||||
-
|
|
||||||
/*
|
|
||||||
* Use SCCL_ID and UID to identify the HHA PMU, while
|
|
||||||
* SCCL_ID is in MPIDR[aff2].
|
|
||||||
@@ -196,6 +307,22 @@ static int hisi_hha_pmu_init_data(struct platform_device *pdev,
|
|
||||||
dev_err(&pdev->dev, "Can not read hha sccl-id!\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Early versions of BIOS support _UID by mistake, so we support
|
|
||||||
+ * both "hisilicon, idx-id" as preference, if available.
|
|
||||||
+ */
|
|
||||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
|
||||||
+ &hha_pmu->index_id)) {
|
|
||||||
+ status = acpi_evaluate_integer(ACPI_HANDLE(&pdev->dev),
|
|
||||||
+ "_UID", NULL, &id);
|
|
||||||
+ if (ACPI_FAILURE(status)) {
|
|
||||||
+ dev_err(&pdev->dev, "Cannot read idx-id!\n");
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ hha_pmu->index_id = id;
|
|
||||||
+ }
|
|
||||||
/* HHA PMUs only share the same SCCL */
|
|
||||||
hha_pmu->ccl_id = -1;
|
|
||||||
|
|
||||||
@@ -220,6 +347,20 @@ static const struct attribute_group hisi_hha_pmu_v1_format_group = {
|
|
||||||
.attrs = hisi_hha_pmu_v1_format_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct attribute *hisi_hha_pmu_v2_format_attr[] = {
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(srcid_cmd, "config1:0-10"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(srcid_msk, "config1:11-21"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(tracetag_en, "config1:22"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(datasrc_skt, "config1:23"),
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_hha_pmu_v2_format_group = {
|
|
||||||
+ .name = "format",
|
|
||||||
+ .attrs = hisi_hha_pmu_v2_format_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static struct attribute *hisi_hha_pmu_v1_events_attr[] = {
|
|
||||||
HISI_PMU_EVENT_ATTR(rx_ops_num, 0x00),
|
|
||||||
HISI_PMU_EVENT_ATTR(rx_outer, 0x01),
|
|
||||||
@@ -255,6 +396,20 @@ static const struct attribute_group hisi_hha_pmu_v1_events_group = {
|
|
||||||
.attrs = hisi_hha_pmu_v1_events_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct attribute *hisi_hha_pmu_v2_events_attr[] = {
|
|
||||||
+ HISI_PMU_EVENT_ATTR(rx_ops_num, 0x00),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(rx_outer, 0x01),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(rx_sccl, 0x02),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(hha_retry, 0x2e),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(cycles, 0x55),
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_hha_pmu_v2_events_group = {
|
|
||||||
+ .name = "events",
|
|
||||||
+ .attrs = hisi_hha_pmu_v2_events_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
|
|
||||||
static struct attribute *hisi_hha_pmu_cpumask_attrs[] = {
|
|
||||||
@@ -286,6 +441,14 @@ static const struct attribute_group *hisi_hha_pmu_v1_attr_groups[] = {
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const struct attribute_group *hisi_hha_pmu_v2_attr_groups[] = {
|
|
||||||
+ &hisi_hha_pmu_v2_format_group,
|
|
||||||
+ &hisi_hha_pmu_v2_events_group,
|
|
||||||
+ &hisi_hha_pmu_cpumask_attr_group,
|
|
||||||
+ &hisi_hha_pmu_identifier_group,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const struct hisi_uncore_ops hisi_uncore_hha_ops = {
|
|
||||||
.write_evtype = hisi_hha_pmu_write_evtype,
|
|
||||||
.get_event_idx = hisi_uncore_pmu_get_event_idx,
|
|
||||||
@@ -299,6 +462,8 @@ static const struct hisi_uncore_ops hisi_uncore_hha_ops = {
|
|
||||||
.read_counter = hisi_hha_pmu_read_counter,
|
|
||||||
.get_int_status = hisi_hha_pmu_get_int_status,
|
|
||||||
.clear_int_status = hisi_hha_pmu_clear_int_status,
|
|
||||||
+ .enable_filter = hisi_hha_pmu_enable_filter,
|
|
||||||
+ .disable_filter = hisi_hha_pmu_disable_filter,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
@@ -314,12 +479,20 @@ static int hisi_hha_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
- hha_pmu->num_counters = HHA_V1_NR_COUNTERS;
|
|
||||||
- hha_pmu->counter_bits = 48;
|
|
||||||
+ if (hha_pmu->identifier >= HISI_PMU_V2) {
|
|
||||||
+ hha_pmu->counter_bits = 64;
|
|
||||||
+ hha_pmu->check_event = HHA_V2_NR_EVENT;
|
|
||||||
+ hha_pmu->pmu_events.attr_groups = hisi_hha_pmu_v2_attr_groups;
|
|
||||||
+ hha_pmu->num_counters = HHA_V2_NR_COUNTERS;
|
|
||||||
+ } else {
|
|
||||||
+ hha_pmu->counter_bits = 48;
|
|
||||||
+ hha_pmu->check_event = HHA_V1_NR_EVENT;
|
|
||||||
+ hha_pmu->pmu_events.attr_groups = hisi_hha_pmu_v1_attr_groups;
|
|
||||||
+ hha_pmu->num_counters = HHA_V1_NR_COUNTERS;
|
|
||||||
+ }
|
|
||||||
hha_pmu->ops = &hisi_uncore_hha_ops;
|
|
||||||
hha_pmu->dev = &pdev->dev;
|
|
||||||
hha_pmu->on_cpu = -1;
|
|
||||||
- hha_pmu->check_event = HHA_V1_NR_EVENT;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -361,7 +534,7 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
|
||||||
.start = hisi_uncore_pmu_start,
|
|
||||||
.stop = hisi_uncore_pmu_stop,
|
|
||||||
.read = hisi_uncore_pmu_read,
|
|
||||||
- .attr_groups = hisi_hha_pmu_v1_attr_groups,
|
|
||||||
+ .attr_groups = hha_pmu->pmu_events.attr_groups,
|
|
||||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,400 +0,0 @@
|
|||||||
From c00401895e634812a41f81e20223244782e503a8 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:07 +0800
|
|
||||||
Subject: [PATCH 18/55] drivers/perf: hisi: Update DDRC PMU for programmable
|
|
||||||
counter
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.12-rc3
|
|
||||||
commit cce03e702c9f26a43b16c51bf03029911feab692
|
|
||||||
category: feature
|
|
||||||
bugzilla: 175148
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cce03e702c9f26a43b16c51bf03029911feab692
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
DDRC PMU's events are useful for performance profiling, but the events
|
|
||||||
are limited and counter is fixed. On HiSilicon Hip09 platform, PMU
|
|
||||||
counters are the programmable and more events are supported. Let's
|
|
||||||
add the DDRC PMU v2 driver.
|
|
||||||
|
|
||||||
Bandwidth events are exposed directly in driver and some more events
|
|
||||||
will listed in JSON file later.
|
|
||||||
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Will Deacon <will@kernel.org>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Link: https://lore.kernel.org/r/1615186237-22263-7-git-send-email-zhangshaokun@hisilicon.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 207 ++++++++++++++++--
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.h | 2 +
|
|
||||||
2 files changed, 196 insertions(+), 13 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index 1d1c8e9f417e..af5f8c16eab1 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -21,7 +21,7 @@
|
|
||||||
|
|
||||||
#include "hisi_uncore_pmu.h"
|
|
||||||
|
|
||||||
-/* DDRC register definition */
|
|
||||||
+/* DDRC register definition in v1 */
|
|
||||||
#define DDRC_PERF_CTRL 0x010
|
|
||||||
#define DDRC_FLUX_WR 0x380
|
|
||||||
#define DDRC_FLUX_RD 0x384
|
|
||||||
@@ -37,13 +37,24 @@
|
|
||||||
#define DDRC_INT_CLEAR 0x6d0
|
|
||||||
#define DDRC_VERSION 0x710
|
|
||||||
|
|
||||||
+/* DDRC register definition in v2 */
|
|
||||||
+#define DDRC_V2_INT_MASK 0x528
|
|
||||||
+#define DDRC_V2_INT_STATUS 0x52c
|
|
||||||
+#define DDRC_V2_INT_CLEAR 0x530
|
|
||||||
+#define DDRC_V2_EVENT_CNT 0xe00
|
|
||||||
+#define DDRC_V2_EVENT_CTRL 0xe70
|
|
||||||
+#define DDRC_V2_EVENT_TYPE 0xe74
|
|
||||||
+#define DDRC_V2_PERF_CTRL 0xeA0
|
|
||||||
+
|
|
||||||
/* DDRC has 8-counters */
|
|
||||||
#define DDRC_NR_COUNTERS 0x8
|
|
||||||
#define DDRC_V1_PERF_CTRL_EN 0x2
|
|
||||||
+#define DDRC_V2_PERF_CTRL_EN 0x1
|
|
||||||
#define DDRC_V1_NR_EVENTS 0x7
|
|
||||||
+#define DDRC_V2_NR_EVENTS 0x90
|
|
||||||
|
|
||||||
/*
|
|
||||||
- * For DDRC PMU, there are eight-events and every event has been mapped
|
|
||||||
+ * For PMU v1, there are eight-events and every event has been mapped
|
|
||||||
* to fixed-purpose counters which register offset is not consistent.
|
|
||||||
* Therefore there is no write event type and we assume that event
|
|
||||||
* code (0 to 7) is equal to counter index in PMU driver.
|
|
||||||
@@ -65,6 +76,11 @@ static u32 hisi_ddrc_pmu_v1_get_counter_offset(int cntr_idx)
|
|
||||||
return ddrc_reg_off[cntr_idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
+static u32 hisi_ddrc_pmu_v2_get_counter_offset(int cntr_idx)
|
|
||||||
+{
|
|
||||||
+ return DDRC_V2_EVENT_CNT + cntr_idx * 8;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static u64 hisi_ddrc_pmu_v1_read_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
@@ -79,13 +95,34 @@ static void hisi_ddrc_pmu_v1_write_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
ddrc_pmu->base + hisi_ddrc_pmu_v1_get_counter_offset(hwc->idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
+static u64 hisi_ddrc_pmu_v2_read_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ return readq(ddrc_pmu->base +
|
|
||||||
+ hisi_ddrc_pmu_v2_get_counter_offset(hwc->idx));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ddrc_pmu_v2_write_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc, u64 val)
|
|
||||||
+{
|
|
||||||
+ writeq(val,
|
|
||||||
+ ddrc_pmu->base + hisi_ddrc_pmu_v2_get_counter_offset(hwc->idx));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/*
|
|
||||||
- * For DDRC PMU, event has been mapped to fixed-purpose counter by hardware,
|
|
||||||
- * so there is no need to write event type.
|
|
||||||
+ * For DDRC PMU v1, event has been mapped to fixed-purpose counter by hardware,
|
|
||||||
+ * so there is no need to write event type, while it is programmable counter in
|
|
||||||
+ * PMU v2.
|
|
||||||
*/
|
|
||||||
static void hisi_ddrc_pmu_write_evtype(struct hisi_pmu *hha_pmu, int idx,
|
|
||||||
u32 type)
|
|
||||||
{
|
|
||||||
+ u32 offset;
|
|
||||||
+
|
|
||||||
+ if (hha_pmu->identifier >= HISI_PMU_V2) {
|
|
||||||
+ offset = DDRC_V2_EVENT_TYPE + 4 * idx;
|
|
||||||
+ writel(type, hha_pmu->base + offset);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
static void hisi_ddrc_pmu_v1_start_counters(struct hisi_pmu *ddrc_pmu)
|
|
||||||
@@ -146,6 +183,49 @@ static int hisi_ddrc_pmu_v1_get_event_idx(struct perf_event *event)
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int hisi_ddrc_pmu_v2_get_event_idx(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ return hisi_uncore_pmu_get_event_idx(event);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ddrc_pmu_v2_start_counters(struct hisi_pmu *ddrc_pmu)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(ddrc_pmu->base + DDRC_V2_PERF_CTRL);
|
|
||||||
+ val |= DDRC_V2_PERF_CTRL_EN;
|
|
||||||
+ writel(val, ddrc_pmu->base + DDRC_V2_PERF_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ddrc_pmu_v2_stop_counters(struct hisi_pmu *ddrc_pmu)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(ddrc_pmu->base + DDRC_V2_PERF_CTRL);
|
|
||||||
+ val &= ~DDRC_V2_PERF_CTRL_EN;
|
|
||||||
+ writel(val, ddrc_pmu->base + DDRC_V2_PERF_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ddrc_pmu_v2_enable_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(ddrc_pmu->base + DDRC_V2_EVENT_CTRL);
|
|
||||||
+ val |= 1 << hwc->idx;
|
|
||||||
+ writel(val, ddrc_pmu->base + DDRC_V2_EVENT_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ddrc_pmu_v2_disable_counter(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(ddrc_pmu->base + DDRC_V2_EVENT_CTRL);
|
|
||||||
+ val &= ~(1 << hwc->idx);
|
|
||||||
+ writel(val, ddrc_pmu->base + DDRC_V2_EVENT_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void hisi_ddrc_pmu_v1_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
struct hw_perf_event *hwc)
|
|
||||||
{
|
|
||||||
@@ -153,7 +233,7 @@ static void hisi_ddrc_pmu_v1_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
|
|
||||||
/* Write 0 to enable interrupt */
|
|
||||||
val = readl(ddrc_pmu->base + DDRC_INT_MASK);
|
|
||||||
- val &= ~(1 << GET_DDRC_EVENTID(hwc));
|
|
||||||
+ val &= ~(1 << hwc->idx);
|
|
||||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -164,10 +244,30 @@ static void hisi_ddrc_pmu_v1_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
|
|
||||||
/* Write 1 to mask interrupt */
|
|
||||||
val = readl(ddrc_pmu->base + DDRC_INT_MASK);
|
|
||||||
- val |= (1 << GET_DDRC_EVENTID(hwc));
|
|
||||||
+ val |= 1 << hwc->idx;
|
|
||||||
writel(val, ddrc_pmu->base + DDRC_INT_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void hisi_ddrc_pmu_v2_enable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(ddrc_pmu->base + DDRC_V2_INT_MASK);
|
|
||||||
+ val &= ~(1 << hwc->idx);
|
|
||||||
+ writel(val, ddrc_pmu->base + DDRC_V2_INT_MASK);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ddrc_pmu_v2_disable_counter_int(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(ddrc_pmu->base + DDRC_V2_INT_MASK);
|
|
||||||
+ val |= 1 << hwc->idx;
|
|
||||||
+ writel(val, ddrc_pmu->base + DDRC_V2_INT_MASK);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static u32 hisi_ddrc_pmu_v1_get_int_status(struct hisi_pmu *ddrc_pmu)
|
|
||||||
{
|
|
||||||
return readl(ddrc_pmu->base + DDRC_INT_STATUS);
|
|
||||||
@@ -179,9 +279,21 @@ static void hisi_ddrc_pmu_v1_clear_int_status(struct hisi_pmu *ddrc_pmu,
|
|
||||||
writel(1 << idx, ddrc_pmu->base + DDRC_INT_CLEAR);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static u32 hisi_ddrc_pmu_v2_get_int_status(struct hisi_pmu *ddrc_pmu)
|
|
||||||
+{
|
|
||||||
+ return readl(ddrc_pmu->base + DDRC_V2_INT_STATUS);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_ddrc_pmu_v2_clear_int_status(struct hisi_pmu *ddrc_pmu,
|
|
||||||
+ int idx)
|
|
||||||
+{
|
|
||||||
+ writel(1 << idx, ddrc_pmu->base + DDRC_V2_INT_CLEAR);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static const struct acpi_device_id hisi_ddrc_pmu_acpi_match[] = {
|
|
||||||
{ "HISI0233", },
|
|
||||||
- {},
|
|
||||||
+ { "HISI0234", },
|
|
||||||
+ {}
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(acpi, hisi_ddrc_pmu_acpi_match);
|
|
||||||
|
|
||||||
@@ -213,6 +325,13 @@ static int hisi_ddrc_pmu_init_data(struct platform_device *pdev,
|
|
||||||
}
|
|
||||||
|
|
||||||
ddrc_pmu->identifier = readl(ddrc_pmu->base + DDRC_VERSION);
|
|
||||||
+ if (ddrc_pmu->identifier >= HISI_PMU_V2) {
|
|
||||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,sub-id",
|
|
||||||
+ &ddrc_pmu->sub_id)) {
|
|
||||||
+ dev_err(&pdev->dev, "Can not read sub-id!\n");
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -227,6 +346,16 @@ static const struct attribute_group hisi_ddrc_pmu_v1_format_group = {
|
|
||||||
.attrs = hisi_ddrc_pmu_v1_format_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct attribute *hisi_ddrc_pmu_v2_format_attr[] = {
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_ddrc_pmu_v2_format_group = {
|
|
||||||
+ .name = "format",
|
|
||||||
+ .attrs = hisi_ddrc_pmu_v2_format_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static struct attribute *hisi_ddrc_pmu_v1_events_attr[] = {
|
|
||||||
HISI_PMU_EVENT_ATTR(flux_wr, 0x00),
|
|
||||||
HISI_PMU_EVENT_ATTR(flux_rd, 0x01),
|
|
||||||
@@ -244,6 +373,18 @@ static const struct attribute_group hisi_ddrc_pmu_v1_events_group = {
|
|
||||||
.attrs = hisi_ddrc_pmu_v1_events_attr,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static struct attribute *hisi_ddrc_pmu_v2_events_attr[] = {
|
|
||||||
+ HISI_PMU_EVENT_ATTR(cycles, 0x00),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(flux_wr, 0x83),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(flux_rd, 0x84),
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_ddrc_pmu_v2_events_group = {
|
|
||||||
+ .name = "events",
|
|
||||||
+ .attrs = hisi_ddrc_pmu_v2_events_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
|
|
||||||
static struct attribute *hisi_ddrc_pmu_cpumask_attrs[] = {
|
|
||||||
@@ -275,6 +416,14 @@ static const struct attribute_group *hisi_ddrc_pmu_v1_attr_groups[] = {
|
|
||||||
NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const struct attribute_group *hisi_ddrc_pmu_v2_attr_groups[] = {
|
|
||||||
+ &hisi_ddrc_pmu_v2_format_group,
|
|
||||||
+ &hisi_ddrc_pmu_v2_events_group,
|
|
||||||
+ &hisi_ddrc_pmu_cpumask_attr_group,
|
|
||||||
+ &hisi_ddrc_pmu_identifier_group,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static const struct hisi_uncore_ops hisi_uncore_ddrc_v1_ops = {
|
|
||||||
.write_evtype = hisi_ddrc_pmu_write_evtype,
|
|
||||||
.get_event_idx = hisi_ddrc_pmu_v1_get_event_idx,
|
|
||||||
@@ -290,6 +439,21 @@ static const struct hisi_uncore_ops hisi_uncore_ddrc_v1_ops = {
|
|
||||||
.clear_int_status = hisi_ddrc_pmu_v1_clear_int_status,
|
|
||||||
};
|
|
||||||
|
|
||||||
+static const struct hisi_uncore_ops hisi_uncore_ddrc_v2_ops = {
|
|
||||||
+ .write_evtype = hisi_ddrc_pmu_write_evtype,
|
|
||||||
+ .get_event_idx = hisi_ddrc_pmu_v2_get_event_idx,
|
|
||||||
+ .start_counters = hisi_ddrc_pmu_v2_start_counters,
|
|
||||||
+ .stop_counters = hisi_ddrc_pmu_v2_stop_counters,
|
|
||||||
+ .enable_counter = hisi_ddrc_pmu_v2_enable_counter,
|
|
||||||
+ .disable_counter = hisi_ddrc_pmu_v2_disable_counter,
|
|
||||||
+ .enable_counter_int = hisi_ddrc_pmu_v2_enable_counter_int,
|
|
||||||
+ .disable_counter_int = hisi_ddrc_pmu_v2_disable_counter_int,
|
|
||||||
+ .write_counter = hisi_ddrc_pmu_v2_write_counter,
|
|
||||||
+ .read_counter = hisi_ddrc_pmu_v2_read_counter,
|
|
||||||
+ .get_int_status = hisi_ddrc_pmu_v2_get_int_status,
|
|
||||||
+ .clear_int_status = hisi_ddrc_pmu_v2_clear_int_status,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
struct hisi_pmu *ddrc_pmu)
|
|
||||||
{
|
|
||||||
@@ -303,12 +467,21 @@ static int hisi_ddrc_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
+ if (ddrc_pmu->identifier >= HISI_PMU_V2) {
|
|
||||||
+ ddrc_pmu->counter_bits = 48;
|
|
||||||
+ ddrc_pmu->check_event = DDRC_V2_NR_EVENTS;
|
|
||||||
+ ddrc_pmu->pmu_events.attr_groups = hisi_ddrc_pmu_v2_attr_groups;
|
|
||||||
+ ddrc_pmu->ops = &hisi_uncore_ddrc_v2_ops;
|
|
||||||
+ } else {
|
|
||||||
+ ddrc_pmu->counter_bits = 32;
|
|
||||||
+ ddrc_pmu->check_event = DDRC_V1_NR_EVENTS;
|
|
||||||
+ ddrc_pmu->pmu_events.attr_groups = hisi_ddrc_pmu_v1_attr_groups;
|
|
||||||
+ ddrc_pmu->ops = &hisi_uncore_ddrc_v1_ops;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
ddrc_pmu->num_counters = DDRC_NR_COUNTERS;
|
|
||||||
- ddrc_pmu->counter_bits = 32;
|
|
||||||
- ddrc_pmu->ops = &hisi_uncore_ddrc_v1_ops;
|
|
||||||
ddrc_pmu->dev = &pdev->dev;
|
|
||||||
ddrc_pmu->on_cpu = -1;
|
|
||||||
- ddrc_pmu->check_event = DDRC_V1_NR_EVENTS;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -336,8 +509,16 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
- name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_ddrc%u",
|
|
||||||
- ddrc_pmu->sccl_id, ddrc_pmu->index_id);
|
|
||||||
+ if (ddrc_pmu->identifier >= HISI_PMU_V2)
|
|
||||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
|
||||||
+ "hisi_sccl%u_ddrc%u_%u",
|
|
||||||
+ ddrc_pmu->sccl_id, ddrc_pmu->index_id,
|
|
||||||
+ ddrc_pmu->sub_id);
|
|
||||||
+ else
|
|
||||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
|
|
||||||
+ "hisi_sccl%u_ddrc%u", ddrc_pmu->sccl_id,
|
|
||||||
+ ddrc_pmu->index_id);
|
|
||||||
+
|
|
||||||
ddrc_pmu->pmu = (struct pmu) {
|
|
||||||
.name = name,
|
|
||||||
.module = THIS_MODULE,
|
|
||||||
@@ -350,7 +531,7 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
|
||||||
.start = hisi_uncore_pmu_start,
|
|
||||||
.stop = hisi_uncore_pmu_stop,
|
|
||||||
.read = hisi_uncore_pmu_read,
|
|
||||||
- .attr_groups = hisi_ddrc_pmu_v1_attr_groups,
|
|
||||||
+ .attr_groups = ddrc_pmu->pmu_events.attr_groups,
|
|
||||||
.capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
};
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.h b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
index 1147dbd25344..de6aa17a1355 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.h
|
|
||||||
@@ -88,6 +88,8 @@ struct hisi_pmu {
|
|
||||||
void __iomem *base;
|
|
||||||
/* the ID of the PMU modules */
|
|
||||||
u32 index_id;
|
|
||||||
+ /* For DDRC PMU v2: each DDRC has more than one DMC */
|
|
||||||
+ u32 sub_id;
|
|
||||||
int num_counters;
|
|
||||||
int counter_bits;
|
|
||||||
/* check event code range */
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,618 +0,0 @@
|
|||||||
From 16c054f4640b9f7c21bb784ac54e1ea32ac65df0 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:08 +0800
|
|
||||||
Subject: [PATCH 19/55] drivers/perf: hisi: Add support for HiSilicon SLLC PMU
|
|
||||||
driver
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.12-rc3
|
|
||||||
commit 3bf30882c3c7b6e376d9d6d04082c9aa2d2ac30a
|
|
||||||
category: feature
|
|
||||||
bugzilla: 175148
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3bf30882c3c7b6e376d9d6d04082c9aa2d2ac30a
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
HiSilicon's Hip09 is comprised by multi-dies that can be connected by SLLC
|
|
||||||
module (Skyros Link Layer Controller), its has separate PMU registers which
|
|
||||||
the driver can program it freely and interrupt is supported to handle
|
|
||||||
counter overflow. Let's support its driver under the framework of HiSilicon
|
|
||||||
uncore PMU driver.
|
|
||||||
|
|
||||||
SLLC PMU supports the following filter functions:
|
|
||||||
* tracetag_en: allows user to count data according to tt_req or
|
|
||||||
tt_core set in L3C PMU.
|
|
||||||
|
|
||||||
* srcid_cmd & srcid_msk: allows user to filter statistics that come from
|
|
||||||
specific CCL/ICL by configuration source ID.
|
|
||||||
|
|
||||||
* tgtid_hi & tgtid_lo: it also supports event statistics that these
|
|
||||||
operations will go to the CCL/ICL by configuration target ID or
|
|
||||||
target ID range. It's the same as source ID with 11-bit width in
|
|
||||||
the SoC. More introduction is added in documentation:
|
|
||||||
Documentation/admin-guide/perf/hisi-pmu.rst
|
|
||||||
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Will Deacon <will@kernel.org>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Link: https://lore.kernel.org/r/1615186237-22263-8-git-send-email-zhangshaokun@hisilicon.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
|
|
||||||
Conflicts:
|
|
||||||
drivers/perf/hisilicon/Makefile
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/Makefile | 4 +-
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 530 ++++++++++++++++++
|
|
||||||
include/linux/cpuhotplug.h | 1 +
|
|
||||||
3 files changed, 534 insertions(+), 1 deletion(-)
|
|
||||||
create mode 100644 drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
|
||||||
index 2621d51ae87a..6600a9d45dd8 100644
|
|
||||||
--- a/drivers/perf/hisilicon/Makefile
|
|
||||||
+++ b/drivers/perf/hisilicon/Makefile
|
|
||||||
@@ -1 +1,3 @@
|
|
||||||
-obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o
|
|
||||||
+# SPDX-License-Identifier: GPL-2.0-only
|
|
||||||
+obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
|
|
||||||
+ hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..46be312fa126
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
|
||||||
@@ -0,0 +1,530 @@
|
|
||||||
+// SPDX-License-Identifier: GPL-2.0-only
|
|
||||||
+/*
|
|
||||||
+ * HiSilicon SLLC uncore Hardware event counters support
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 2020 Hisilicon Limited
|
|
||||||
+ * Author: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
+ *
|
|
||||||
+ * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
|
||||||
+ */
|
|
||||||
+#include <linux/acpi.h>
|
|
||||||
+#include <linux/cpuhotplug.h>
|
|
||||||
+#include <linux/interrupt.h>
|
|
||||||
+#include <linux/irq.h>
|
|
||||||
+#include <linux/list.h>
|
|
||||||
+#include <linux/smp.h>
|
|
||||||
+
|
|
||||||
+#include "hisi_uncore_pmu.h"
|
|
||||||
+
|
|
||||||
+/* SLLC register definition */
|
|
||||||
+#define SLLC_INT_MASK 0x0814
|
|
||||||
+#define SLLC_INT_STATUS 0x0818
|
|
||||||
+#define SLLC_INT_CLEAR 0x081c
|
|
||||||
+#define SLLC_PERF_CTRL 0x1c00
|
|
||||||
+#define SLLC_SRCID_CTRL 0x1c04
|
|
||||||
+#define SLLC_TGTID_CTRL 0x1c08
|
|
||||||
+#define SLLC_EVENT_CTRL 0x1c14
|
|
||||||
+#define SLLC_EVENT_TYPE0 0x1c18
|
|
||||||
+#define SLLC_VERSION 0x1cf0
|
|
||||||
+#define SLLC_EVENT_CNT0_L 0x1d00
|
|
||||||
+
|
|
||||||
+#define SLLC_EVTYPE_MASK 0xff
|
|
||||||
+#define SLLC_PERF_CTRL_EN BIT(0)
|
|
||||||
+#define SLLC_FILT_EN BIT(1)
|
|
||||||
+#define SLLC_TRACETAG_EN BIT(2)
|
|
||||||
+#define SLLC_SRCID_EN BIT(4)
|
|
||||||
+#define SLLC_SRCID_NONE 0x0
|
|
||||||
+#define SLLC_TGTID_EN BIT(5)
|
|
||||||
+#define SLLC_TGTID_NONE 0x0
|
|
||||||
+#define SLLC_TGTID_MIN_SHIFT 1
|
|
||||||
+#define SLLC_TGTID_MAX_SHIFT 12
|
|
||||||
+#define SLLC_SRCID_CMD_SHIFT 1
|
|
||||||
+#define SLLC_SRCID_MSK_SHIFT 12
|
|
||||||
+#define SLLC_NR_EVENTS 0x80
|
|
||||||
+
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_min, config1, 10, 0);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_max, config1, 21, 11);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_cmd, config1, 32, 22);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_msk, config1, 43, 33);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tracetag_en, config1, 44, 44);
|
|
||||||
+
|
|
||||||
+static bool tgtid_is_valid(u32 max, u32 min)
|
|
||||||
+{
|
|
||||||
+ return max > 0 && max >= min;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_enable_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
|
||||||
+
|
|
||||||
+ if (tt_en) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ val |= SLLC_TRACETAG_EN | SLLC_FILT_EN;
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_disable_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
|
||||||
+
|
|
||||||
+ if (tt_en) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ val &= ~(SLLC_TRACETAG_EN | SLLC_FILT_EN);
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_config_tgtid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 min = hisi_get_tgtid_min(event);
|
|
||||||
+ u32 max = hisi_get_tgtid_max(event);
|
|
||||||
+
|
|
||||||
+ if (tgtid_is_valid(max, min)) {
|
|
||||||
+ u32 val = (max << SLLC_TGTID_MAX_SHIFT) | (min << SLLC_TGTID_MIN_SHIFT);
|
|
||||||
+
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_TGTID_CTRL);
|
|
||||||
+ /* Enable the tgtid */
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ val |= SLLC_TGTID_EN | SLLC_FILT_EN;
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_clear_tgtid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 min = hisi_get_tgtid_min(event);
|
|
||||||
+ u32 max = hisi_get_tgtid_max(event);
|
|
||||||
+
|
|
||||||
+ if (tgtid_is_valid(max, min)) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ writel(SLLC_TGTID_NONE, sllc_pmu->base + SLLC_TGTID_CTRL);
|
|
||||||
+ /* Disable the tgtid */
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ val &= ~(SLLC_TGTID_EN | SLLC_FILT_EN);
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_config_srcid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
|
||||||
+
|
|
||||||
+ if (cmd) {
|
|
||||||
+ u32 val, msk;
|
|
||||||
+
|
|
||||||
+ msk = hisi_get_srcid_msk(event);
|
|
||||||
+ val = (cmd << SLLC_SRCID_CMD_SHIFT) | (msk << SLLC_SRCID_MSK_SHIFT);
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_SRCID_CTRL);
|
|
||||||
+ /* Enable the srcid */
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ val |= SLLC_SRCID_EN | SLLC_FILT_EN;
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_clear_srcid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *sllc_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
|
||||||
+
|
|
||||||
+ if (cmd) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ writel(SLLC_SRCID_NONE, sllc_pmu->base + SLLC_SRCID_CTRL);
|
|
||||||
+ /* Disable the srcid */
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ val &= ~(SLLC_SRCID_EN | SLLC_FILT_EN);
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_enable_filter(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ if (event->attr.config1 != 0x0) {
|
|
||||||
+ hisi_sllc_pmu_enable_tracetag(event);
|
|
||||||
+ hisi_sllc_pmu_config_srcid(event);
|
|
||||||
+ hisi_sllc_pmu_config_tgtid(event);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_clear_filter(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ if (event->attr.config1 != 0x0) {
|
|
||||||
+ hisi_sllc_pmu_disable_tracetag(event);
|
|
||||||
+ hisi_sllc_pmu_clear_srcid(event);
|
|
||||||
+ hisi_sllc_pmu_clear_tgtid(event);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static u32 hisi_sllc_pmu_get_counter_offset(int idx)
|
|
||||||
+{
|
|
||||||
+ return (SLLC_EVENT_CNT0_L + idx * 8);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static u64 hisi_sllc_pmu_read_counter(struct hisi_pmu *sllc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ return readq(sllc_pmu->base +
|
|
||||||
+ hisi_sllc_pmu_get_counter_offset(hwc->idx));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_write_counter(struct hisi_pmu *sllc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc, u64 val)
|
|
||||||
+{
|
|
||||||
+ writeq(val, sllc_pmu->base +
|
|
||||||
+ hisi_sllc_pmu_get_counter_offset(hwc->idx));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_write_evtype(struct hisi_pmu *sllc_pmu, int idx,
|
|
||||||
+ u32 type)
|
|
||||||
+{
|
|
||||||
+ u32 reg, reg_idx, shift, val;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Select the appropriate event select register(SLLC_EVENT_TYPE0/1).
|
|
||||||
+ * There are 2 event select registers for the 8 hardware counters.
|
|
||||||
+ * Event code is 8-bits and for the former 4 hardware counters,
|
|
||||||
+ * SLLC_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
|
|
||||||
+ * SLLC_EVENT_TYPE1 is chosen.
|
|
||||||
+ */
|
|
||||||
+ reg = SLLC_EVENT_TYPE0 + (idx / 4) * 4;
|
|
||||||
+ reg_idx = idx % 4;
|
|
||||||
+ shift = 8 * reg_idx;
|
|
||||||
+
|
|
||||||
+ /* Write event code to SLLC_EVENT_TYPEx Register */
|
|
||||||
+ val = readl(sllc_pmu->base + reg);
|
|
||||||
+ val &= ~(SLLC_EVTYPE_MASK << shift);
|
|
||||||
+ val |= (type << shift);
|
|
||||||
+ writel(val, sllc_pmu->base + reg);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_start_counters(struct hisi_pmu *sllc_pmu)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ val |= SLLC_PERF_CTRL_EN;
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_stop_counters(struct hisi_pmu *sllc_pmu)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+ val &= ~(SLLC_PERF_CTRL_EN);
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_PERF_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_enable_counter(struct hisi_pmu *sllc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_EVENT_CTRL);
|
|
||||||
+ val |= 1 << hwc->idx;
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_EVENT_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_disable_counter(struct hisi_pmu *sllc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_EVENT_CTRL);
|
|
||||||
+ val &= ~(1 << hwc->idx);
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_EVENT_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_enable_counter_int(struct hisi_pmu *sllc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_INT_MASK);
|
|
||||||
+ /* Write 0 to enable interrupt */
|
|
||||||
+ val &= ~(1 << hwc->idx);
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_INT_MASK);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_disable_counter_int(struct hisi_pmu *sllc_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(sllc_pmu->base + SLLC_INT_MASK);
|
|
||||||
+ /* Write 1 to mask interrupt */
|
|
||||||
+ val |= 1 << hwc->idx;
|
|
||||||
+ writel(val, sllc_pmu->base + SLLC_INT_MASK);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static u32 hisi_sllc_pmu_get_int_status(struct hisi_pmu *sllc_pmu)
|
|
||||||
+{
|
|
||||||
+ return readl(sllc_pmu->base + SLLC_INT_STATUS);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_sllc_pmu_clear_int_status(struct hisi_pmu *sllc_pmu, int idx)
|
|
||||||
+{
|
|
||||||
+ writel(1 << idx, sllc_pmu->base + SLLC_INT_CLEAR);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct acpi_device_id hisi_sllc_pmu_acpi_match[] = {
|
|
||||||
+ { "HISI0263", },
|
|
||||||
+ {}
|
|
||||||
+};
|
|
||||||
+MODULE_DEVICE_TABLE(acpi, hisi_sllc_pmu_acpi_match);
|
|
||||||
+
|
|
||||||
+static int hisi_sllc_pmu_init_data(struct platform_device *pdev,
|
|
||||||
+ struct hisi_pmu *sllc_pmu)
|
|
||||||
+{
|
|
||||||
+ /*
|
|
||||||
+ * Use the SCCL_ID and the index ID to identify the SLLC PMU,
|
|
||||||
+ * while SCCL_ID is from MPIDR_EL1 by CPU.
|
|
||||||
+ */
|
|
||||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
|
||||||
+ &sllc_pmu->sccl_id)) {
|
|
||||||
+ dev_err(&pdev->dev, "Cannot read sccl-id!\n");
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
|
||||||
+ &sllc_pmu->index_id)) {
|
|
||||||
+ dev_err(&pdev->dev, "Cannot read idx-id!\n");
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ /* SLLC PMUs only share the same SCCL */
|
|
||||||
+ sllc_pmu->ccl_id = -1;
|
|
||||||
+
|
|
||||||
+ sllc_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
|
||||||
+ if (IS_ERR(sllc_pmu->base)) {
|
|
||||||
+ dev_err(&pdev->dev, "ioremap failed for sllc_pmu resource.\n");
|
|
||||||
+ return PTR_ERR(sllc_pmu->base);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ sllc_pmu->identifier = readl(sllc_pmu->base + SLLC_VERSION);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_sllc_pmu_v2_format_attr[] = {
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(tgtid_min, "config1:0-10"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(tgtid_max, "config1:11-21"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(srcid_cmd, "config1:22-32"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(srcid_msk, "config1:33-43"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(tracetag_en, "config1:44"),
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_sllc_pmu_v2_format_group = {
|
|
||||||
+ .name = "format",
|
|
||||||
+ .attrs = hisi_sllc_pmu_v2_format_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_sllc_pmu_v2_events_attr[] = {
|
|
||||||
+ HISI_PMU_EVENT_ATTR(rx_req, 0x30),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(rx_data, 0x31),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(tx_req, 0x34),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(tx_data, 0x35),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(cycles, 0x09),
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_sllc_pmu_v2_events_group = {
|
|
||||||
+ .name = "events",
|
|
||||||
+ .attrs = hisi_sllc_pmu_v2_events_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_sllc_pmu_cpumask_attrs[] = {
|
|
||||||
+ &dev_attr_cpumask.attr,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_sllc_pmu_cpumask_attr_group = {
|
|
||||||
+ .attrs = hisi_sllc_pmu_cpumask_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct device_attribute hisi_sllc_pmu_identifier_attr =
|
|
||||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_sllc_pmu_identifier_attrs[] = {
|
|
||||||
+ &hisi_sllc_pmu_identifier_attr.attr,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute_group hisi_sllc_pmu_identifier_group = {
|
|
||||||
+ .attrs = hisi_sllc_pmu_identifier_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group *hisi_sllc_pmu_v2_attr_groups[] = {
|
|
||||||
+ &hisi_sllc_pmu_v2_format_group,
|
|
||||||
+ &hisi_sllc_pmu_v2_events_group,
|
|
||||||
+ &hisi_sllc_pmu_cpumask_attr_group,
|
|
||||||
+ &hisi_sllc_pmu_identifier_group,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct hisi_uncore_ops hisi_uncore_sllc_ops = {
|
|
||||||
+ .write_evtype = hisi_sllc_pmu_write_evtype,
|
|
||||||
+ .get_event_idx = hisi_uncore_pmu_get_event_idx,
|
|
||||||
+ .start_counters = hisi_sllc_pmu_start_counters,
|
|
||||||
+ .stop_counters = hisi_sllc_pmu_stop_counters,
|
|
||||||
+ .enable_counter = hisi_sllc_pmu_enable_counter,
|
|
||||||
+ .disable_counter = hisi_sllc_pmu_disable_counter,
|
|
||||||
+ .enable_counter_int = hisi_sllc_pmu_enable_counter_int,
|
|
||||||
+ .disable_counter_int = hisi_sllc_pmu_disable_counter_int,
|
|
||||||
+ .write_counter = hisi_sllc_pmu_write_counter,
|
|
||||||
+ .read_counter = hisi_sllc_pmu_read_counter,
|
|
||||||
+ .get_int_status = hisi_sllc_pmu_get_int_status,
|
|
||||||
+ .clear_int_status = hisi_sllc_pmu_clear_int_status,
|
|
||||||
+ .enable_filter = hisi_sllc_pmu_enable_filter,
|
|
||||||
+ .disable_filter = hisi_sllc_pmu_clear_filter,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int hisi_sllc_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
+ struct hisi_pmu *sllc_pmu)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = hisi_sllc_pmu_init_data(pdev, sllc_pmu);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ ret = hisi_uncore_pmu_init_irq(sllc_pmu, pdev);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ sllc_pmu->pmu_events.attr_groups = hisi_sllc_pmu_v2_attr_groups;
|
|
||||||
+ sllc_pmu->ops = &hisi_uncore_sllc_ops;
|
|
||||||
+ sllc_pmu->check_event = SLLC_NR_EVENTS;
|
|
||||||
+ sllc_pmu->counter_bits = 64;
|
|
||||||
+ sllc_pmu->num_counters = 8;
|
|
||||||
+ sllc_pmu->dev = &pdev->dev;
|
|
||||||
+ sllc_pmu->on_cpu = -1;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int hisi_sllc_pmu_probe(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *sllc_pmu;
|
|
||||||
+ char *name;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ sllc_pmu = devm_kzalloc(&pdev->dev, sizeof(*sllc_pmu), GFP_KERNEL);
|
|
||||||
+ if (!sllc_pmu)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ ret = hisi_sllc_pmu_dev_probe(pdev, sllc_pmu);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sccl%u_sllc%u",
|
|
||||||
+ sllc_pmu->sccl_id, sllc_pmu->index_id);
|
|
||||||
+ if (!name)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
|
||||||
+ &sllc_pmu->node);
|
|
||||||
+ if (ret) {
|
|
||||||
+ dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ sllc_pmu->pmu = (struct pmu) {
|
|
||||||
+ .module = THIS_MODULE,
|
|
||||||
+ .task_ctx_nr = perf_invalid_context,
|
|
||||||
+ .event_init = hisi_uncore_pmu_event_init,
|
|
||||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
|
||||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
|
||||||
+ .add = hisi_uncore_pmu_add,
|
|
||||||
+ .del = hisi_uncore_pmu_del,
|
|
||||||
+ .start = hisi_uncore_pmu_start,
|
|
||||||
+ .stop = hisi_uncore_pmu_stop,
|
|
||||||
+ .read = hisi_uncore_pmu_read,
|
|
||||||
+ .attr_groups = sllc_pmu->pmu_events.attr_groups,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ ret = perf_pmu_register(&sllc_pmu->pmu, name, -1);
|
|
||||||
+ if (ret) {
|
|
||||||
+ dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
|
||||||
+ cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
|
||||||
+ &sllc_pmu->node);
|
|
||||||
+ irq_set_affinity_hint(sllc_pmu->irq, NULL);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ platform_set_drvdata(pdev, sllc_pmu);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int hisi_sllc_pmu_remove(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *sllc_pmu = platform_get_drvdata(pdev);
|
|
||||||
+
|
|
||||||
+ perf_pmu_unregister(&sllc_pmu->pmu);
|
|
||||||
+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
|
||||||
+ &sllc_pmu->node);
|
|
||||||
+ irq_set_affinity_hint(sllc_pmu->irq, NULL);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct platform_driver hisi_sllc_pmu_driver = {
|
|
||||||
+ .driver = {
|
|
||||||
+ .name = "hisi_sllc_pmu",
|
|
||||||
+ .acpi_match_table = hisi_sllc_pmu_acpi_match,
|
|
||||||
+ .suppress_bind_attrs = true,
|
|
||||||
+ },
|
|
||||||
+ .probe = hisi_sllc_pmu_probe,
|
|
||||||
+ .remove = hisi_sllc_pmu_remove,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int __init hisi_sllc_pmu_module_init(void)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
|
||||||
+ "AP_PERF_ARM_HISI_SLLC_ONLINE",
|
|
||||||
+ hisi_uncore_pmu_online_cpu,
|
|
||||||
+ hisi_uncore_pmu_offline_cpu);
|
|
||||||
+ if (ret) {
|
|
||||||
+ pr_err("SLLC PMU: cpuhp state setup failed, ret = %d\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = platform_driver_register(&hisi_sllc_pmu_driver);
|
|
||||||
+ if (ret)
|
|
||||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+module_init(hisi_sllc_pmu_module_init);
|
|
||||||
+
|
|
||||||
+static void __exit hisi_sllc_pmu_module_exit(void)
|
|
||||||
+{
|
|
||||||
+ platform_driver_unregister(&hisi_sllc_pmu_driver);
|
|
||||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE);
|
|
||||||
+}
|
|
||||||
+module_exit(hisi_sllc_pmu_module_exit);
|
|
||||||
+
|
|
||||||
+MODULE_DESCRIPTION("HiSilicon SLLC uncore PMU driver");
|
|
||||||
+MODULE_LICENSE("GPL v2");
|
|
||||||
+MODULE_AUTHOR("Shaokun Zhang <zhangshaokun@hisilicon.com>");
|
|
||||||
+MODULE_AUTHOR("Qi Liu <liuqi115@huawei.com>");
|
|
||||||
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
|
|
||||||
index d67c0035165c..b5c55a408a30 100644
|
|
||||||
--- a/include/linux/cpuhotplug.h
|
|
||||||
+++ b/include/linux/cpuhotplug.h
|
|
||||||
@@ -161,6 +161,7 @@ enum cpuhp_state {
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
|
||||||
+ CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_L2X0_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_QCOM_L3_ONLINE,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,584 +0,0 @@
|
|||||||
From 71cf98350d1423660b390740a190ce8a98502c37 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:09 +0800
|
|
||||||
Subject: [PATCH 20/55] drivers/perf: hisi: Add support for HiSilicon PA PMU
|
|
||||||
driver
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.12-rc3
|
|
||||||
commit a0ab25cd82eeb68bfa19a4d93a097521af5011b8
|
|
||||||
category: feature
|
|
||||||
bugzilla: 175148
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a0ab25cd82eeb68bfa19a4d93a097521af5011b8
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
On HiSilicon Hip09 platform, there is a PA (Protocol Adapter) module on
|
|
||||||
each chip SICL (Super I/O Cluster) which incorporates three Hydra interface
|
|
||||||
and facilitates the cache coherency between the dies on the chip. While PA
|
|
||||||
uncore PMU model is the same as other Hip09 PMU modules and many PMU events
|
|
||||||
are supported. Let's support the PMU driver using the HiSilicon uncore PMU
|
|
||||||
framework.
|
|
||||||
|
|
||||||
PA PMU supports the following filter functions:
|
|
||||||
* tracetag_en: allows user to count events according to tt_req or
|
|
||||||
tt_core set in L3C PMU. It's the same as other PMUs.
|
|
||||||
|
|
||||||
* srcid_cmd & srcid_msk: allows user to filter statistics that come from
|
|
||||||
specific CCL/ICL by configuration source ID.
|
|
||||||
|
|
||||||
* tgtid_cmd & tgtid_msk: it is the similar function to srcid_cmd &
|
|
||||||
srcid_msk. Both are used to check where the data comes from or go to.
|
|
||||||
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: Will Deacon <will@kernel.org>
|
|
||||||
Cc: John Garry <john.garry@huawei.com>
|
|
||||||
Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>
|
|
||||||
Reviewed-by: John Garry <john.garry@huawei.com>
|
|
||||||
Co-developed-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Qi Liu <liuqi115@huawei.com>
|
|
||||||
Signed-off-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Link: https://lore.kernel.org/r/1615186237-22263-9-git-send-email-zhangshaokun@hisilicon.com
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/Makefile | 3 +-
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 500 ++++++++++++++++++++
|
|
||||||
include/linux/cpuhotplug.h | 1 +
|
|
||||||
3 files changed, 503 insertions(+), 1 deletion(-)
|
|
||||||
create mode 100644 drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/Makefile b/drivers/perf/hisilicon/Makefile
|
|
||||||
index 6600a9d45dd8..7643c9f93e36 100644
|
|
||||||
--- a/drivers/perf/hisilicon/Makefile
|
|
||||||
+++ b/drivers/perf/hisilicon/Makefile
|
|
||||||
@@ -1,3 +1,4 @@
|
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
|
||||||
obj-$(CONFIG_HISI_PMU) += hisi_uncore_pmu.o hisi_uncore_l3c_pmu.o \
|
|
||||||
- hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o
|
|
||||||
+ hisi_uncore_hha_pmu.o hisi_uncore_ddrc_pmu.o hisi_uncore_sllc_pmu.o \
|
|
||||||
+ hisi_uncore_pa_pmu.o
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
|
||||||
new file mode 100644
|
|
||||||
index 000000000000..5517a90552ec
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
|
||||||
@@ -0,0 +1,500 @@
|
|
||||||
+// SPDX-License-Identifier: GPL-2.0-only
|
|
||||||
+/*
|
|
||||||
+ * HiSilicon PA uncore Hardware event counters support
|
|
||||||
+ *
|
|
||||||
+ * Copyright (C) 2020 HiSilicon Limited
|
|
||||||
+ * Author: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
+ *
|
|
||||||
+ * This code is based on the uncore PMUs like arm-cci and arm-ccn.
|
|
||||||
+ */
|
|
||||||
+#include <linux/acpi.h>
|
|
||||||
+#include <linux/cpuhotplug.h>
|
|
||||||
+#include <linux/interrupt.h>
|
|
||||||
+#include <linux/irq.h>
|
|
||||||
+#include <linux/list.h>
|
|
||||||
+#include <linux/smp.h>
|
|
||||||
+
|
|
||||||
+#include "hisi_uncore_pmu.h"
|
|
||||||
+
|
|
||||||
+/* PA register definition */
|
|
||||||
+#define PA_PERF_CTRL 0x1c00
|
|
||||||
+#define PA_EVENT_CTRL 0x1c04
|
|
||||||
+#define PA_TT_CTRL 0x1c08
|
|
||||||
+#define PA_TGTID_CTRL 0x1c14
|
|
||||||
+#define PA_SRCID_CTRL 0x1c18
|
|
||||||
+#define PA_INT_MASK 0x1c70
|
|
||||||
+#define PA_INT_STATUS 0x1c78
|
|
||||||
+#define PA_INT_CLEAR 0x1c7c
|
|
||||||
+#define PA_EVENT_TYPE0 0x1c80
|
|
||||||
+#define PA_PMU_VERSION 0x1cf0
|
|
||||||
+#define PA_EVENT_CNT0_L 0x1d00
|
|
||||||
+
|
|
||||||
+#define PA_EVTYPE_MASK 0xff
|
|
||||||
+#define PA_NR_COUNTERS 0x8
|
|
||||||
+#define PA_PERF_CTRL_EN BIT(0)
|
|
||||||
+#define PA_TRACETAG_EN BIT(4)
|
|
||||||
+#define PA_TGTID_EN BIT(11)
|
|
||||||
+#define PA_SRCID_EN BIT(11)
|
|
||||||
+#define PA_TGTID_NONE 0
|
|
||||||
+#define PA_SRCID_NONE 0
|
|
||||||
+#define PA_TGTID_MSK_SHIFT 12
|
|
||||||
+#define PA_SRCID_MSK_SHIFT 12
|
|
||||||
+
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_cmd, config1, 10, 0);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tgtid_msk, config1, 21, 11);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_cmd, config1, 32, 22);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(srcid_msk, config1, 43, 33);
|
|
||||||
+HISI_PMU_EVENT_ATTR_EXTRACTOR(tracetag_en, config1, 44, 44);
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_enable_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
|
||||||
+
|
|
||||||
+ if (tt_en) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(pa_pmu->base + PA_TT_CTRL);
|
|
||||||
+ val |= PA_TRACETAG_EN;
|
|
||||||
+ writel(val, pa_pmu->base + PA_TT_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_clear_tracetag(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 tt_en = hisi_get_tracetag_en(event);
|
|
||||||
+
|
|
||||||
+ if (tt_en) {
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(pa_pmu->base + PA_TT_CTRL);
|
|
||||||
+ val &= ~PA_TRACETAG_EN;
|
|
||||||
+ writel(val, pa_pmu->base + PA_TT_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_config_tgtid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 cmd = hisi_get_tgtid_cmd(event);
|
|
||||||
+
|
|
||||||
+ if (cmd) {
|
|
||||||
+ u32 msk = hisi_get_tgtid_msk(event);
|
|
||||||
+ u32 val = cmd | PA_TGTID_EN | (msk << PA_TGTID_MSK_SHIFT);
|
|
||||||
+
|
|
||||||
+ writel(val, pa_pmu->base + PA_TGTID_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_clear_tgtid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 cmd = hisi_get_tgtid_cmd(event);
|
|
||||||
+
|
|
||||||
+ if (cmd)
|
|
||||||
+ writel(PA_TGTID_NONE, pa_pmu->base + PA_TGTID_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_config_srcid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
|
||||||
+
|
|
||||||
+ if (cmd) {
|
|
||||||
+ u32 msk = hisi_get_srcid_msk(event);
|
|
||||||
+ u32 val = cmd | PA_SRCID_EN | (msk << PA_SRCID_MSK_SHIFT);
|
|
||||||
+
|
|
||||||
+ writel(val, pa_pmu->base + PA_SRCID_CTRL);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_clear_srcid(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *pa_pmu = to_hisi_pmu(event->pmu);
|
|
||||||
+ u32 cmd = hisi_get_srcid_cmd(event);
|
|
||||||
+
|
|
||||||
+ if (cmd)
|
|
||||||
+ writel(PA_SRCID_NONE, pa_pmu->base + PA_SRCID_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_enable_filter(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ if (event->attr.config1 != 0x0) {
|
|
||||||
+ hisi_pa_pmu_enable_tracetag(event);
|
|
||||||
+ hisi_pa_pmu_config_srcid(event);
|
|
||||||
+ hisi_pa_pmu_config_tgtid(event);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_disable_filter(struct perf_event *event)
|
|
||||||
+{
|
|
||||||
+ if (event->attr.config1 != 0x0) {
|
|
||||||
+ hisi_pa_pmu_clear_tgtid(event);
|
|
||||||
+ hisi_pa_pmu_clear_srcid(event);
|
|
||||||
+ hisi_pa_pmu_clear_tracetag(event);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static u32 hisi_pa_pmu_get_counter_offset(int idx)
|
|
||||||
+{
|
|
||||||
+ return (PA_EVENT_CNT0_L + idx * 8);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static u64 hisi_pa_pmu_read_counter(struct hisi_pmu *pa_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ return readq(pa_pmu->base + hisi_pa_pmu_get_counter_offset(hwc->idx));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_write_counter(struct hisi_pmu *pa_pmu,
|
|
||||||
+ struct hw_perf_event *hwc, u64 val)
|
|
||||||
+{
|
|
||||||
+ writeq(val, pa_pmu->base + hisi_pa_pmu_get_counter_offset(hwc->idx));
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_write_evtype(struct hisi_pmu *pa_pmu, int idx,
|
|
||||||
+ u32 type)
|
|
||||||
+{
|
|
||||||
+ u32 reg, reg_idx, shift, val;
|
|
||||||
+
|
|
||||||
+ /*
|
|
||||||
+ * Select the appropriate event select register(PA_EVENT_TYPE0/1).
|
|
||||||
+ * There are 2 event select registers for the 8 hardware counters.
|
|
||||||
+ * Event code is 8-bits and for the former 4 hardware counters,
|
|
||||||
+ * PA_EVENT_TYPE0 is chosen. For the latter 4 hardware counters,
|
|
||||||
+ * PA_EVENT_TYPE1 is chosen.
|
|
||||||
+ */
|
|
||||||
+ reg = PA_EVENT_TYPE0 + (idx / 4) * 4;
|
|
||||||
+ reg_idx = idx % 4;
|
|
||||||
+ shift = 8 * reg_idx;
|
|
||||||
+
|
|
||||||
+ /* Write event code to pa_EVENT_TYPEx Register */
|
|
||||||
+ val = readl(pa_pmu->base + reg);
|
|
||||||
+ val &= ~(PA_EVTYPE_MASK << shift);
|
|
||||||
+ val |= (type << shift);
|
|
||||||
+ writel(val, pa_pmu->base + reg);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_start_counters(struct hisi_pmu *pa_pmu)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(pa_pmu->base + PA_PERF_CTRL);
|
|
||||||
+ val |= PA_PERF_CTRL_EN;
|
|
||||||
+ writel(val, pa_pmu->base + PA_PERF_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_stop_counters(struct hisi_pmu *pa_pmu)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ val = readl(pa_pmu->base + PA_PERF_CTRL);
|
|
||||||
+ val &= ~(PA_PERF_CTRL_EN);
|
|
||||||
+ writel(val, pa_pmu->base + PA_PERF_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_enable_counter(struct hisi_pmu *pa_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ /* Enable counter index in PA_EVENT_CTRL register */
|
|
||||||
+ val = readl(pa_pmu->base + PA_EVENT_CTRL);
|
|
||||||
+ val |= 1 << hwc->idx;
|
|
||||||
+ writel(val, pa_pmu->base + PA_EVENT_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_disable_counter(struct hisi_pmu *pa_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ /* Clear counter index in PA_EVENT_CTRL register */
|
|
||||||
+ val = readl(pa_pmu->base + PA_EVENT_CTRL);
|
|
||||||
+ val &= ~(1 << hwc->idx);
|
|
||||||
+ writel(val, pa_pmu->base + PA_EVENT_CTRL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_enable_counter_int(struct hisi_pmu *pa_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ /* Write 0 to enable interrupt */
|
|
||||||
+ val = readl(pa_pmu->base + PA_INT_MASK);
|
|
||||||
+ val &= ~(1 << hwc->idx);
|
|
||||||
+ writel(val, pa_pmu->base + PA_INT_MASK);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_disable_counter_int(struct hisi_pmu *pa_pmu,
|
|
||||||
+ struct hw_perf_event *hwc)
|
|
||||||
+{
|
|
||||||
+ u32 val;
|
|
||||||
+
|
|
||||||
+ /* Write 1 to mask interrupt */
|
|
||||||
+ val = readl(pa_pmu->base + PA_INT_MASK);
|
|
||||||
+ val |= 1 << hwc->idx;
|
|
||||||
+ writel(val, pa_pmu->base + PA_INT_MASK);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static u32 hisi_pa_pmu_get_int_status(struct hisi_pmu *pa_pmu)
|
|
||||||
+{
|
|
||||||
+ return readl(pa_pmu->base + PA_INT_STATUS);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void hisi_pa_pmu_clear_int_status(struct hisi_pmu *pa_pmu, int idx)
|
|
||||||
+{
|
|
||||||
+ writel(1 << idx, pa_pmu->base + PA_INT_CLEAR);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static const struct acpi_device_id hisi_pa_pmu_acpi_match[] = {
|
|
||||||
+ { "HISI0273", },
|
|
||||||
+ {}
|
|
||||||
+};
|
|
||||||
+MODULE_DEVICE_TABLE(acpi, hisi_pa_pmu_acpi_match);
|
|
||||||
+
|
|
||||||
+static int hisi_pa_pmu_init_data(struct platform_device *pdev,
|
|
||||||
+ struct hisi_pmu *pa_pmu)
|
|
||||||
+{
|
|
||||||
+ /*
|
|
||||||
+ * Use the SCCL_ID and the index ID to identify the PA PMU,
|
|
||||||
+ * while SCCL_ID is the nearst SCCL_ID from this SICL and
|
|
||||||
+ * CPU core is chosen from this SCCL to manage this PMU.
|
|
||||||
+ */
|
|
||||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,scl-id",
|
|
||||||
+ &pa_pmu->sccl_id)) {
|
|
||||||
+ dev_err(&pdev->dev, "Cannot read sccl-id!\n");
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (device_property_read_u32(&pdev->dev, "hisilicon,idx-id",
|
|
||||||
+ &pa_pmu->index_id)) {
|
|
||||||
+ dev_err(&pdev->dev, "Cannot read idx-id!\n");
|
|
||||||
+ return -EINVAL;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pa_pmu->ccl_id = -1;
|
|
||||||
+
|
|
||||||
+ pa_pmu->base = devm_platform_ioremap_resource(pdev, 0);
|
|
||||||
+ if (IS_ERR(pa_pmu->base)) {
|
|
||||||
+ dev_err(&pdev->dev, "ioremap failed for pa_pmu resource.\n");
|
|
||||||
+ return PTR_ERR(pa_pmu->base);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pa_pmu->identifier = readl(pa_pmu->base + PA_PMU_VERSION);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_pa_pmu_v2_format_attr[] = {
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(event, "config:0-7"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(tgtid_cmd, "config1:0-10"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(tgtid_msk, "config1:11-21"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(srcid_cmd, "config1:22-32"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(srcid_msk, "config1:33-43"),
|
|
||||||
+ HISI_PMU_FORMAT_ATTR(tracetag_en, "config1:44"),
|
|
||||||
+ NULL,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_pa_pmu_v2_format_group = {
|
|
||||||
+ .name = "format",
|
|
||||||
+ .attrs = hisi_pa_pmu_v2_format_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_pa_pmu_v2_events_attr[] = {
|
|
||||||
+ HISI_PMU_EVENT_ATTR(rx_req, 0x40),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(tx_req, 0x5c),
|
|
||||||
+ HISI_PMU_EVENT_ATTR(cycle, 0x78),
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_pa_pmu_v2_events_group = {
|
|
||||||
+ .name = "events",
|
|
||||||
+ .attrs = hisi_pa_pmu_v2_events_attr,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static DEVICE_ATTR(cpumask, 0444, hisi_cpumask_sysfs_show, NULL);
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_pa_pmu_cpumask_attrs[] = {
|
|
||||||
+ &dev_attr_cpumask.attr,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group hisi_pa_pmu_cpumask_attr_group = {
|
|
||||||
+ .attrs = hisi_pa_pmu_cpumask_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct device_attribute hisi_pa_pmu_identifier_attr =
|
|
||||||
+ __ATTR(identifier, 0444, hisi_uncore_pmu_identifier_attr_show, NULL);
|
|
||||||
+
|
|
||||||
+static struct attribute *hisi_pa_pmu_identifier_attrs[] = {
|
|
||||||
+ &hisi_pa_pmu_identifier_attr.attr,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static struct attribute_group hisi_pa_pmu_identifier_group = {
|
|
||||||
+ .attrs = hisi_pa_pmu_identifier_attrs,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct attribute_group *hisi_pa_pmu_v2_attr_groups[] = {
|
|
||||||
+ &hisi_pa_pmu_v2_format_group,
|
|
||||||
+ &hisi_pa_pmu_v2_events_group,
|
|
||||||
+ &hisi_pa_pmu_cpumask_attr_group,
|
|
||||||
+ &hisi_pa_pmu_identifier_group,
|
|
||||||
+ NULL
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static const struct hisi_uncore_ops hisi_uncore_pa_ops = {
|
|
||||||
+ .write_evtype = hisi_pa_pmu_write_evtype,
|
|
||||||
+ .get_event_idx = hisi_uncore_pmu_get_event_idx,
|
|
||||||
+ .start_counters = hisi_pa_pmu_start_counters,
|
|
||||||
+ .stop_counters = hisi_pa_pmu_stop_counters,
|
|
||||||
+ .enable_counter = hisi_pa_pmu_enable_counter,
|
|
||||||
+ .disable_counter = hisi_pa_pmu_disable_counter,
|
|
||||||
+ .enable_counter_int = hisi_pa_pmu_enable_counter_int,
|
|
||||||
+ .disable_counter_int = hisi_pa_pmu_disable_counter_int,
|
|
||||||
+ .write_counter = hisi_pa_pmu_write_counter,
|
|
||||||
+ .read_counter = hisi_pa_pmu_read_counter,
|
|
||||||
+ .get_int_status = hisi_pa_pmu_get_int_status,
|
|
||||||
+ .clear_int_status = hisi_pa_pmu_clear_int_status,
|
|
||||||
+ .enable_filter = hisi_pa_pmu_enable_filter,
|
|
||||||
+ .disable_filter = hisi_pa_pmu_disable_filter,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int hisi_pa_pmu_dev_probe(struct platform_device *pdev,
|
|
||||||
+ struct hisi_pmu *pa_pmu)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = hisi_pa_pmu_init_data(pdev, pa_pmu);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ ret = hisi_uncore_pmu_init_irq(pa_pmu, pdev);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+
|
|
||||||
+ pa_pmu->pmu_events.attr_groups = hisi_pa_pmu_v2_attr_groups;
|
|
||||||
+ pa_pmu->num_counters = PA_NR_COUNTERS;
|
|
||||||
+ pa_pmu->ops = &hisi_uncore_pa_ops;
|
|
||||||
+ pa_pmu->check_event = 0xB0;
|
|
||||||
+ pa_pmu->counter_bits = 64;
|
|
||||||
+ pa_pmu->dev = &pdev->dev;
|
|
||||||
+ pa_pmu->on_cpu = -1;
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *pa_pmu;
|
|
||||||
+ char *name;
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ pa_pmu = devm_kzalloc(&pdev->dev, sizeof(*pa_pmu), GFP_KERNEL);
|
|
||||||
+ if (!pa_pmu)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ ret = hisi_pa_pmu_dev_probe(pdev, pa_pmu);
|
|
||||||
+ if (ret)
|
|
||||||
+ return ret;
|
|
||||||
+ /*
|
|
||||||
+ * PA is attached in SICL and the CPU core is chosen to manage this
|
|
||||||
+ * PMU which is the nearest SCCL, while its SCCL_ID is greater than
|
|
||||||
+ * one with the SICL_ID.
|
|
||||||
+ */
|
|
||||||
+ name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "hisi_sicl%u_pa%u",
|
|
||||||
+ pa_pmu->sccl_id - 1, pa_pmu->index_id);
|
|
||||||
+ if (!name)
|
|
||||||
+ return -ENOMEM;
|
|
||||||
+
|
|
||||||
+ ret = cpuhp_state_add_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
|
||||||
+ &pa_pmu->node);
|
|
||||||
+ if (ret) {
|
|
||||||
+ dev_err(&pdev->dev, "Error %d registering hotplug\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ pa_pmu->pmu = (struct pmu) {
|
|
||||||
+ .module = THIS_MODULE,
|
|
||||||
+ .task_ctx_nr = perf_invalid_context,
|
|
||||||
+ .event_init = hisi_uncore_pmu_event_init,
|
|
||||||
+ .pmu_enable = hisi_uncore_pmu_enable,
|
|
||||||
+ .pmu_disable = hisi_uncore_pmu_disable,
|
|
||||||
+ .add = hisi_uncore_pmu_add,
|
|
||||||
+ .del = hisi_uncore_pmu_del,
|
|
||||||
+ .start = hisi_uncore_pmu_start,
|
|
||||||
+ .stop = hisi_uncore_pmu_stop,
|
|
||||||
+ .read = hisi_uncore_pmu_read,
|
|
||||||
+ .attr_groups = pa_pmu->pmu_events.attr_groups,
|
|
||||||
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ ret = perf_pmu_register(&pa_pmu->pmu, name, -1);
|
|
||||||
+ if (ret) {
|
|
||||||
+ dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
|
||||||
+ cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
|
||||||
+ &pa_pmu->node);
|
|
||||||
+ irq_set_affinity_hint(pa_pmu->irq, NULL);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ platform_set_drvdata(pdev, pa_pmu);
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int hisi_pa_pmu_remove(struct platform_device *pdev)
|
|
||||||
+{
|
|
||||||
+ struct hisi_pmu *pa_pmu = platform_get_drvdata(pdev);
|
|
||||||
+
|
|
||||||
+ perf_pmu_unregister(&pa_pmu->pmu);
|
|
||||||
+ cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
|
||||||
+ &pa_pmu->node);
|
|
||||||
+ irq_set_affinity_hint(pa_pmu->irq, NULL);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static struct platform_driver hisi_pa_pmu_driver = {
|
|
||||||
+ .driver = {
|
|
||||||
+ .name = "hisi_pa_pmu",
|
|
||||||
+ .acpi_match_table = hisi_pa_pmu_acpi_match,
|
|
||||||
+ .suppress_bind_attrs = true,
|
|
||||||
+ },
|
|
||||||
+ .probe = hisi_pa_pmu_probe,
|
|
||||||
+ .remove = hisi_pa_pmu_remove,
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+static int __init hisi_pa_pmu_module_init(void)
|
|
||||||
+{
|
|
||||||
+ int ret;
|
|
||||||
+
|
|
||||||
+ ret = cpuhp_setup_state_multi(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
|
||||||
+ "AP_PERF_ARM_HISI_PA_ONLINE",
|
|
||||||
+ hisi_uncore_pmu_online_cpu,
|
|
||||||
+ hisi_uncore_pmu_offline_cpu);
|
|
||||||
+ if (ret) {
|
|
||||||
+ pr_err("PA PMU: cpuhp state setup failed, ret = %d\n", ret);
|
|
||||||
+ return ret;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ ret = platform_driver_register(&hisi_pa_pmu_driver);
|
|
||||||
+ if (ret)
|
|
||||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE);
|
|
||||||
+
|
|
||||||
+ return ret;
|
|
||||||
+}
|
|
||||||
+module_init(hisi_pa_pmu_module_init);
|
|
||||||
+
|
|
||||||
+static void __exit hisi_pa_pmu_module_exit(void)
|
|
||||||
+{
|
|
||||||
+ platform_driver_unregister(&hisi_pa_pmu_driver);
|
|
||||||
+ cpuhp_remove_multi_state(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE);
|
|
||||||
+}
|
|
||||||
+module_exit(hisi_pa_pmu_module_exit);
|
|
||||||
+
|
|
||||||
+MODULE_DESCRIPTION("HiSilicon Protocol Adapter uncore PMU driver");
|
|
||||||
+MODULE_LICENSE("GPL v2");
|
|
||||||
+MODULE_AUTHOR("Shaokun Zhang <zhangshaokun@hisilicon.com>");
|
|
||||||
+MODULE_AUTHOR("Qi Liu <liuqi115@huawei.com>");
|
|
||||||
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
|
|
||||||
index b5c55a408a30..225b095a96db 100644
|
|
||||||
--- a/include/linux/cpuhotplug.h
|
|
||||||
+++ b/include/linux/cpuhotplug.h
|
|
||||||
@@ -161,6 +161,7 @@ enum cpuhp_state {
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
|
||||||
+ CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_L2X0_ONLINE,
|
|
||||||
CPUHP_AP_PERF_ARM_QCOM_L2_ONLINE,
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
@ -1,181 +0,0 @@
|
|||||||
From e0b763c0b1c8c96a04fd56f7be82d13903123b19 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Thomas Gleixner <tglx@linutronix.de>
|
|
||||||
Date: Fri, 30 Jul 2021 15:44:12 +0800
|
|
||||||
Subject: [PATCH 21/55] perf/hisi: Use irq_set_affinity()
|
|
||||||
|
|
||||||
mainline inclusion
|
|
||||||
from mainline-v5.13-rc3
|
|
||||||
commit 77b06ddc04354293f746d0434f00700110d3392d
|
|
||||||
category: bugfix
|
|
||||||
bugzilla: 175148
|
|
||||||
CVE: NA
|
|
||||||
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=77b06ddc04354293f746d0434f00700110d3392d
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
|
|
||||||
These drivers use irq_set_affinity_hint() to set the affinity for the PMU
|
|
||||||
interrupts, which relies on the undocumented side effect that this function
|
|
||||||
actually sets the affinity under the hood.
|
|
||||||
|
|
||||||
Setting an hint is clearly not a guarantee and for these PMU interrupts an
|
|
||||||
affinity hint, which is supposed to guide userspace for setting affinity,
|
|
||||||
is beyond pointless, because the affinity of these interrupts cannot be
|
|
||||||
modified from user space.
|
|
||||||
|
|
||||||
Aside of that the error checks are bogus because the only error which is
|
|
||||||
returned from irq_set_affinity_hint() is when there is no irq descriptor
|
|
||||||
for the interrupt number, but not when the affinity set fails. That's on
|
|
||||||
purpose because the hint can point to an offline CPU.
|
|
||||||
|
|
||||||
Replace the mindless abuse with irq_set_affinity().
|
|
||||||
|
|
||||||
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
||||||
Cc: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Cc: Will Deacon <will@kernel.org>
|
|
||||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Cc: linux-arm-kernel@lists.infradead.org
|
|
||||||
Acked-by: Mark Rutland <mark.rutland@arm.com>
|
|
||||||
Link: https://lore.kernel.org/r/20210518093118.813375875@linutronix.de
|
|
||||||
Signed-off-by: Will Deacon <will@kernel.org>
|
|
||||||
Reviewed-by: Shaokun Zhang <zhangshaokun@hisilicon.com>
|
|
||||||
Signed-off-by: Zheng Zengkai <zhengzengkai@huawei.com>
|
|
||||||
Signed-off-by: hongrongxuan <hongrongxuan@huawei.com>
|
|
||||||
---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c | 3 ---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c | 3 ---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c | 3 ---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pa_pmu.c | 3 ---
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_pmu.c | 4 ++--
|
|
||||||
drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c | 3 ---
|
|
||||||
6 files changed, 2 insertions(+), 17 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
index af5f8c16eab1..457ac6a1ad64 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
|
|
||||||
@@ -540,7 +540,6 @@ static int hisi_ddrc_pmu_probe(struct platform_device *pdev)
|
|
||||||
dev_err(ddrc_pmu->dev, "DDRC PMU register failed!\n");
|
|
||||||
cpuhp_state_remove_instance_nocalls(
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE, &ddrc_pmu->node);
|
|
||||||
- irq_set_affinity_hint(ddrc_pmu->irq, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
@@ -553,8 +552,6 @@ static int hisi_ddrc_pmu_remove(struct platform_device *pdev)
|
|
||||||
perf_pmu_unregister(&ddrc_pmu->pmu);
|
|
||||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_DDRC_ONLINE,
|
|
||||||
&ddrc_pmu->node);
|
|
||||||
- irq_set_affinity_hint(ddrc_pmu->irq, NULL);
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
index a7e1749fc3e4..89996b4d939f 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
|
|
||||||
@@ -543,7 +543,6 @@ static int hisi_hha_pmu_probe(struct platform_device *pdev)
|
|
||||||
dev_err(hha_pmu->dev, "HHA PMU register failed!\n");
|
|
||||||
cpuhp_state_remove_instance_nocalls(
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE, &hha_pmu->node);
|
|
||||||
- irq_set_affinity_hint(hha_pmu->irq, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
@@ -556,8 +555,6 @@ static int hisi_hha_pmu_remove(struct platform_device *pdev)
|
|
||||||
perf_pmu_unregister(&hha_pmu->pmu);
|
|
||||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_HHA_ONLINE,
|
|
||||||
&hha_pmu->node);
|
|
||||||
- irq_set_affinity_hint(hha_pmu->irq, NULL);
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
index 87ca2a9ca8c5..d70a01587d72 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
|
|
||||||
@@ -581,7 +581,6 @@ static int hisi_l3c_pmu_probe(struct platform_device *pdev)
|
|
||||||
dev_err(l3c_pmu->dev, "L3C PMU register failed!\n");
|
|
||||||
cpuhp_state_remove_instance_nocalls(
|
|
||||||
CPUHP_AP_PERF_ARM_HISI_L3_ONLINE, &l3c_pmu->node);
|
|
||||||
- irq_set_affinity_hint(l3c_pmu->irq, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
@@ -594,8 +593,6 @@ static int hisi_l3c_pmu_remove(struct platform_device *pdev)
|
|
||||||
perf_pmu_unregister(&l3c_pmu->pmu);
|
|
||||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_L3_ONLINE,
|
|
||||||
&l3c_pmu->node);
|
|
||||||
- irq_set_affinity_hint(l3c_pmu->irq, NULL);
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
|
||||||
index 5517a90552ec..390e59f4ef60 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pa_pmu.c
|
|
||||||
@@ -436,7 +436,6 @@ static int hisi_pa_pmu_probe(struct platform_device *pdev)
|
|
||||||
dev_err(pa_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
|
||||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
|
||||||
&pa_pmu->node);
|
|
||||||
- irq_set_affinity_hint(pa_pmu->irq, NULL);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -451,8 +450,6 @@ static int hisi_pa_pmu_remove(struct platform_device *pdev)
|
|
||||||
perf_pmu_unregister(&pa_pmu->pmu);
|
|
||||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_PA_ONLINE,
|
|
||||||
&pa_pmu->node);
|
|
||||||
- irq_set_affinity_hint(pa_pmu->irq, NULL);
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_pmu.c b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
index c0f221e39aff..2758cab39a58 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_pmu.c
|
|
||||||
@@ -491,7 +491,7 @@ int hisi_uncore_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
|
|
||||||
hisi_pmu->on_cpu = cpu;
|
|
||||||
|
|
||||||
/* Overflow interrupt also should use the same CPU */
|
|
||||||
- WARN_ON(irq_set_affinity_hint(hisi_pmu->irq, cpumask_of(cpu)));
|
|
||||||
+ WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(cpu)));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -524,7 +524,7 @@ int hisi_uncore_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
|
|
||||||
perf_pmu_migrate_context(&hisi_pmu->pmu, cpu, target);
|
|
||||||
/* Use this CPU for event counting */
|
|
||||||
hisi_pmu->on_cpu = target;
|
|
||||||
- WARN_ON(irq_set_affinity_hint(hisi_pmu->irq, cpumask_of(target)));
|
|
||||||
+ WARN_ON(irq_set_affinity(hisi_pmu->irq, cpumask_of(target)));
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
diff --git a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
|
||||||
index 46be312fa126..835ec3e2178f 100644
|
|
||||||
--- a/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
|
||||||
+++ b/drivers/perf/hisilicon/hisi_uncore_sllc_pmu.c
|
|
||||||
@@ -465,7 +465,6 @@ static int hisi_sllc_pmu_probe(struct platform_device *pdev)
|
|
||||||
dev_err(sllc_pmu->dev, "PMU register failed, ret = %d\n", ret);
|
|
||||||
cpuhp_state_remove_instance(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
|
||||||
&sllc_pmu->node);
|
|
||||||
- irq_set_affinity_hint(sllc_pmu->irq, NULL);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -481,8 +480,6 @@ static int hisi_sllc_pmu_remove(struct platform_device *pdev)
|
|
||||||
perf_pmu_unregister(&sllc_pmu->pmu);
|
|
||||||
cpuhp_state_remove_instance_nocalls(CPUHP_AP_PERF_ARM_HISI_SLLC_ONLINE,
|
|
||||||
&sllc_pmu->node);
|
|
||||||
- irq_set_affinity_hint(sllc_pmu->irq, NULL);
|
|
||||||
-
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.27.0
|
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user