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
|
||||
{**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 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