Compare commits

...

No commits in common. "9c129c18a4694f69ead30167ba88991e2692bff4" and "f8a00b125c55bb2718add107fe7c3a84dc6e14f3" have entirely different histories.

802 changed files with 3255 additions and 555925 deletions

File diff suppressed because it is too large Load Diff

View 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

View File

@ -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
};
/*

View 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

View File

@ -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

View 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

View 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

View File

@ -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
View 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)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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
SOURCE
View File

@ -1 +0,0 @@
4.19.90-2504.4.0

View File

@ -1,4 +0,0 @@
<multibuild>
<flavor>raspberrypi-kernel</flavor>
<flavor>kernel-rt</flavor>
</multibuild>

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

View File

@ -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
View File

@ -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

File diff suppressed because it is too large Load Diff

14586
kernel.spec

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -1 +0,0 @@
nil

Binary file not shown.

2791
llvm-toolset-17.spec Normal file

File diff suppressed because it is too large Load Diff

4
llvm-toolset-17.yaml Normal file
View File

@ -0,0 +1,4 @@
version_control: github
src_repo: llvm/llvm-project
tag_prefix: ^llvmorg-
seperator: .

View File

@ -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

View File

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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