From a32e89883a53564d8c68ede6e210299fe62ff238 Mon Sep 17 00:00:00 2001 From: Jamie Hill-Daniel Date: Tue, 18 Jan 2022 08:06:04 +0100 Subject: [PATCH 01/52] UPSTREAM: vfs: fs_context: fix up param length parsing in legacy_parse_param The "PAGE_SIZE - 2 - size" calculation in legacy_parse_param() is an unsigned type so a large value of "size" results in a high positive value instead of a negative value as expected. Fix this by getting rid of the subtraction. Signed-off-by: Jamie Hill-Daniel Signed-off-by: William Liu Tested-by: Salvatore Bonaccorso Tested-by: Thadeu Lima de Souza Cascardo Acked-by: Dan Carpenter Acked-by: Al Viro Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds (cherry picked from commit 722d94847de29310e8aa03fcbdb41fc92c521756) Bug: 213421437 Signed-off-by: Greg Kroah-Hartman Change-Id: Ica4c894715daae0d4393a377ac3e81260a651df9 --- fs/fs_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/fs_context.c b/fs/fs_context.c index 2834d1afa6e8..b11677802ee1 100644 --- a/fs/fs_context.c +++ b/fs/fs_context.c @@ -530,7 +530,7 @@ static int legacy_parse_param(struct fs_context *fc, struct fs_parameter *param) param->key); } - if (len > PAGE_SIZE - 2 - size) + if (size + len + 2 > PAGE_SIZE) return invalf(fc, "VFS: Legacy: Cumulative options too large"); if (strchr(param->key, ',') || (param->type == fs_value_is_string && From 96c08d92106026fea3fa1b5543c864b10a6c3316 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Oct 2021 16:12:14 +0200 Subject: [PATCH 02/52] Revert portions of "ANDROID: vendor_hooks: Add hooks for scheduler" This reverts part of commit 53e8099784435152ed3d2a60190e265ab0e436eb. The hook android_rvh_check_preempt_wakeup_ignore is not used by any vendor, so remove it to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 182441701 Cc: xieliujie Signed-off-by: Greg Kroah-Hartman Change-Id: I69bdc14143760bfdd07bbd72ed3d5a4127fbc4c8 --- drivers/android/vendor_hooks.c | 1 - include/trace/hooks/sched.h | 3 --- kernel/sched/fair.c | 4 ---- 3 files changed, 8 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index f1e530388bd0..4ebf556d855f 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -238,7 +238,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cgroup_force_kthread_migration); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_syscall_prctl_finished); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_create_worker); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_check_preempt_tick); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_check_preempt_wakeup_ignore); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_replace_next_task_fair); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sched_yield); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_wait_for_work); diff --git a/include/trace/hooks/sched.h b/include/trace/hooks/sched.h index 0844244c9aff..e6c8bd35e189 100644 --- a/include/trace/hooks/sched.h +++ b/include/trace/hooks/sched.h @@ -283,9 +283,6 @@ DECLARE_RESTRICTED_HOOK(android_rvh_check_preempt_tick, unsigned long delta_exec, struct cfs_rq *cfs_rq, struct sched_entity *curr, unsigned int granularity), TP_ARGS(p, ideal_runtime, skip_preempt, delta_exec, cfs_rq, curr, granularity), 1); -DECLARE_RESTRICTED_HOOK(android_rvh_check_preempt_wakeup_ignore, - TP_PROTO(struct task_struct *p, bool *ignore), - TP_ARGS(p, ignore), 1); DECLARE_RESTRICTED_HOOK(android_rvh_replace_next_task_fair, TP_PROTO(struct rq *rq, struct task_struct **p, struct sched_entity **se, bool *repick, bool simple, struct task_struct *prev), diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 7d009aaccb72..8dc3d9a02b54 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7064,13 +7064,9 @@ static void check_preempt_wakeup(struct rq *rq, struct task_struct *p, int wake_ int scale = cfs_rq->nr_running >= sched_nr_latency; int next_buddy_marked = 0; bool preempt = false, nopreempt = false; - bool ignore = false; if (unlikely(se == pse)) return; - trace_android_rvh_check_preempt_wakeup_ignore(curr, &ignore); - if (ignore) - return; /* * This is possible from callers such as attach_tasks(), in which we From 18975040b9441435ae43d41f145ffd358fe9165c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Oct 2021 16:23:03 +0200 Subject: [PATCH 03/52] Revert portions of "ANDROID: sched: Add vendor hooks for sched." This reverts part of commit 54f66141a8834e27601fe594d68a97db01bb86b6. The hook android_rvh_entity_tick is not used by any vendor, so remove it to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 183674818 Cc: lijianzhong Signed-off-by: Greg Kroah-Hartman Change-Id: I92acc11802939d1ebfcc8253490193019567695d --- drivers/android/vendor_hooks.c | 1 - include/trace/hooks/sched.h | 4 ---- kernel/sched/fair.c | 1 - 3 files changed, 6 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 4ebf556d855f..6b9285029545 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -315,7 +315,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_after_enqueue_task); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_after_dequeue_task); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_enqueue_entity); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_dequeue_entity); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_entity_tick); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_enqueue_task_fair); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_dequeue_task_fair); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sched_stat_runtime_rt); diff --git a/include/trace/hooks/sched.h b/include/trace/hooks/sched.h index e6c8bd35e189..92690acc1197 100644 --- a/include/trace/hooks/sched.h +++ b/include/trace/hooks/sched.h @@ -339,10 +339,6 @@ DECLARE_RESTRICTED_HOOK(android_rvh_dequeue_entity, TP_PROTO(struct cfs_rq *cfs, struct sched_entity *se), TP_ARGS(cfs, se), 1); -DECLARE_RESTRICTED_HOOK(android_rvh_entity_tick, - TP_PROTO(struct cfs_rq *cfs_rq, struct sched_entity *se), - TP_ARGS(cfs_rq, se), 1); - DECLARE_RESTRICTED_HOOK(android_rvh_enqueue_task_fair, TP_PROTO(struct rq *rq, struct task_struct *p, int flags), TP_ARGS(rq, p, flags), 1); diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 8dc3d9a02b54..725c5224caae 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -4607,7 +4607,6 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued) if (cfs_rq->nr_running > 1) check_preempt_tick(cfs_rq, curr); - trace_android_rvh_entity_tick(cfs_rq, curr); } From 63e7148b272922a309b7d8e357f18f1f9411357f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Oct 2021 17:19:59 +0200 Subject: [PATCH 04/52] Revert "ANDROID: user: Add vendor hook to user for GKI purpose" This reverts commit c9b8fa644f45e9c99da85d8947f6c7e06771f205. The hooks android_vh_alloc_uid and android_vh_free_user are not used by any vendor, so remove them to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 187458531 Cc: heshuai1 Signed-off-by: Greg Kroah-Hartman Change-Id: I2aa3f95ab52c2d81eb790ba8b64b864f8189222b --- drivers/android/vendor_hooks.c | 3 --- include/trace/hooks/user.h | 23 ----------------------- kernel/user.c | 4 ---- 3 files changed, 30 deletions(-) delete mode 100644 include/trace/hooks/user.h diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 6b9285029545..63a06d02a9a1 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -60,7 +60,6 @@ #include #include #include -#include #include #include #include @@ -355,8 +354,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_v4l2subdev_set_frame_interval); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_v4l2subdev_set_frame_interval); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_scmi_timeout_sync); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_find_new_ilb); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_uid); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_free_user); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_add_request); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_update_request); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_freq_qos_remove_request); diff --git a/include/trace/hooks/user.h b/include/trace/hooks/user.h deleted file mode 100644 index b5b507ccd9c2..000000000000 --- a/include/trace/hooks/user.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM user -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH trace/hooks -#if !defined(_TRACE_HOOK_USER_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_HOOK_USER_H -#include -#include - -struct user_struct; -DECLARE_HOOK(android_vh_alloc_uid, - TP_PROTO(struct user_struct *user), - TP_ARGS(user)); - -DECLARE_HOOK(android_vh_free_user, - TP_PROTO(struct user_struct *up), - TP_ARGS(up)); - -#endif /* _TRACE_HOOK_USER_H */ -/* This part must be outside protection */ -#include - diff --git a/kernel/user.c b/kernel/user.c index 83adc37251fa..ab445fcc07aa 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -20,8 +20,6 @@ #include #include -#include - /* * userns count is 1 for root user, 1 for init_uts_ns, * and 1 for... ? @@ -141,7 +139,6 @@ static struct user_struct *uid_hash_find(kuid_t uid, struct hlist_head *hashent) static void free_user(struct user_struct *up, unsigned long flags) __releases(&uidhash_lock) { - trace_android_vh_free_user(up); uid_hash_remove(up); spin_unlock_irqrestore(&uidhash_lock, flags); kmem_cache_free(uid_cachep, up); @@ -193,7 +190,6 @@ struct user_struct *alloc_uid(kuid_t uid) new->uid = uid; refcount_set(&new->__count, 1); - trace_android_vh_alloc_uid(new); ratelimit_state_init(&new->ratelimit, HZ, 100); ratelimit_set_flags(&new->ratelimit, RATELIMIT_MSG_ON_RELEASE); From 7887091009b24fc74bd7478d92ed5aab9adc815e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 21 Oct 2021 09:26:52 +0200 Subject: [PATCH 05/52] Revert "ANDROID: sysrq: add vendor hook for sysrq crash information" This reverts commit 0d8928ed6ee38f00f3595e1f3b623de0d99c311d. The hook android_vh_sysrq_crash is not used by any vendor, so remove it to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 170234110 Cc: Sangmoon Kim Signed-off-by: Greg Kroah-Hartman Change-Id: I1b4b9280081e0fb569bb74c7f0d3efcb18728b48 --- drivers/android/vendor_hooks.c | 2 -- drivers/tty/sysrq.c | 4 ---- include/trace/hooks/sysrqcrash.h | 22 ---------------------- 3 files changed, 28 deletions(-) delete mode 100644 include/trace/hooks/sysrqcrash.h diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 63a06d02a9a1..8b3800240250 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -126,7 +125,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_find_busiest_group); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_gic_resume); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_wq_lockup_pool); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ipi_stop); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sysrq_crash); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_dump_throttled_rt_tasks); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_printk_hotplug); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_jiffies_update); diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index 8f01cde61d20..959f9e121cc6 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c @@ -55,8 +55,6 @@ #include #include -#include - /* Whether we react on sysrq keys or just ignore them */ static int __read_mostly sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE; static bool __read_mostly sysrq_always_enabled; @@ -153,8 +151,6 @@ static void sysrq_handle_crash(int key) /* release the RCU read lock before crashing */ rcu_read_unlock(); - trace_android_vh_sysrq_crash(current); - panic("sysrq triggered crash\n"); } static const struct sysrq_key_op sysrq_crash_op = { diff --git a/include/trace/hooks/sysrqcrash.h b/include/trace/hooks/sysrqcrash.h deleted file mode 100644 index d163f898a9f6..000000000000 --- a/include/trace/hooks/sysrqcrash.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM sysrqcrash -#define TRACE_INCLUDE_PATH trace/hooks - -#if !defined(_TRACE_HOOK_SYSRQCRASH_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_HOOK_SYSRQCRASH_H -#include -#include -/* - * Following tracepoints are not exported in tracefs and provide a - * mechanism for vendor modules to hook and extend functionality - */ -DECLARE_HOOK(android_vh_sysrq_crash, - TP_PROTO(void *data), - TP_ARGS(data)); - -/* macro versions of hooks are no longer required */ - -#endif /* _TRACE_HOOK_SYSRQCRASH_H */ -/* This part must be outside protection */ -#include From 64095600fd538eab27c28e2b54f0b0887a68f1f7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 21 Oct 2021 09:34:04 +0200 Subject: [PATCH 06/52] Revert "ANDROID: vendor_hooks: Add hooks to recognize special worker thread." This reverts commit 8f3f46d77c8133ccce52e055a8b4b577699acc5f. The hook android_vh_create_worker is not used by any vendor, so remove it to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 184571803 Cc: Liujie Xie Signed-off-by: Greg Kroah-Hartman Change-Id: I3112f4e067c27ecb6889333bb58f9342df0ecb63 --- drivers/android/vendor_hooks.c | 2 -- include/trace/hooks/workqueue.h | 22 ---------------------- kernel/workqueue.c | 2 -- 3 files changed, 26 deletions(-) delete mode 100644 include/trace/hooks/workqueue.h diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 8b3800240250..99d492cf8076 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include @@ -233,7 +232,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cpufreq_transition); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cgroup_set_task); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_cgroup_force_kthread_migration); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_syscall_prctl_finished); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_create_worker); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_check_preempt_tick); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_replace_next_task_fair); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sched_yield); diff --git a/include/trace/hooks/workqueue.h b/include/trace/hooks/workqueue.h deleted file mode 100644 index 0ffe56433a4c..000000000000 --- a/include/trace/hooks/workqueue.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM workqueue -#define TRACE_INCLUDE_PATH trace/hooks - -#if !defined(_TRACE_HOOK_WORKQUEUE_H) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_HOOK_WORKQUEUE_H -#include -#include -/* - * Following tracepoints are not exported in tracefs and provide a - * mechanism for vendor modules to hook and extend functionality - */ -struct worker; -DECLARE_HOOK(android_vh_create_worker, - TP_PROTO(struct worker *worker, struct workqueue_attrs *attrs), - TP_ARGS(worker, attrs)); -/* macro versions of hooks are no longer required */ - -#endif /* _TRACE_HOOK_WORKQUEUE_H */ -/* This part must be outside protection */ -#include diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 4d09cece5cb9..6adbbb358e3a 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -55,7 +55,6 @@ #include "workqueue_internal.h" #include -#include /* events/workqueue.h uses default TRACE_INCLUDE_PATH */ #undef TRACE_INCLUDE_PATH @@ -1950,7 +1949,6 @@ static struct worker *create_worker(struct worker_pool *pool) if (IS_ERR(worker->task)) goto fail; - trace_android_vh_create_worker(worker, pool->attrs); set_user_nice(worker->task, pool->attrs->nice); kthread_bind_mask(worker->task, pool->attrs->cpumask); From 9c63be2adac9788180d892351052b9f2bcdb3d37 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Wed, 18 Aug 2021 11:24:50 -0400 Subject: [PATCH 07/52] UPSTREAM: tracefs: Have tracefs directories not set OTH permission bits by default [ Upstream commit 49d67e445742bbcb03106b735b2ab39f6e5c56bc ] The tracefs file system is by default mounted such that only root user can access it. But there are legitimate reasons to create a group and allow those added to the group to have access to tracing. By changing the permissions of the tracefs mount point to allow access, it will allow group access to the tracefs directory. There should not be any real reason to allow all access to the tracefs directory as it contains sensitive information. Have the default permission of directories being created not have any OTH (other) bits set, such that an admin that wants to give permission to a group has to first disable all OTH bits in the file system. Link: https://lkml.kernel.org/r/20210818153038.664127804@goodmis.org Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Sasha Levin (cherry picked from commit 3c2434d9a6c6807f84a7c7be9396588897e4f31f) Bug: 214061655 Signed-off-by: Roger Liao Change-Id: Id2cd708f00f31adc8ef398c80e098fe8742e6fa9 --- fs/tracefs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 0ee8c6dfb036..bf58ae6f984f 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -430,7 +430,8 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, if (unlikely(!inode)) return failed_creating(dentry); - inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; + /* Do not set bits for OTH */ + inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP; inode->i_op = ops; inode->i_fop = &simple_dir_operations; From 8455746a4564f56f12d250657536a287066b2f28 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Wed, 8 Dec 2021 07:57:20 -0500 Subject: [PATCH 08/52] UPSTREAM: tracefs: Have new files inherit the ownership of their parent commit ee7f3666995d8537dec17b1d35425f28877671a9 upstream. If directories in tracefs have their ownership changed, then any new files and directories that are created under those directories should inherit the ownership of the director they are created in. Link: https://lkml.kernel.org/r/20211208075720.4855d180@gandalf.local.home Cc: Kees Cook Cc: Ingo Molnar Cc: Andrew Morton Cc: Linus Torvalds Cc: Al Viro Cc: Greg Kroah-Hartman Cc: Yabin Cui Cc: Christian Brauner Cc: stable@vger.kernel.org Fixes: 4282d60689d4f ("tracefs: Add new tracefs file system") Reported-by: Kalesh Singh Reported: https://lore.kernel.org/all/CAC_TJve8MMAv+H_NdLSJXZUSoxOEq2zB_pVaJ9p=7H6Bu3X76g@mail.gmail.com/ Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 33204825cc2b0f3184ef6bc8426a973a30566578) Bug: 214061655 Signed-off-by: Roger Liao Change-Id: I033edde0b38d2c1cad638a9d5f8648aa7f16cfdf --- fs/tracefs/inode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index bf58ae6f984f..3d7bb4c8c261 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -412,6 +412,8 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode, inode->i_mode = mode; inode->i_fop = fops ? fops : &tracefs_file_operations; inode->i_private = data; + inode->i_uid = d_inode(dentry->d_parent)->i_uid; + inode->i_gid = d_inode(dentry->d_parent)->i_gid; d_instantiate(dentry, inode); fsnotify_create(dentry->d_parent->d_inode, dentry); return end_creating(dentry); @@ -434,6 +436,8 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP; inode->i_op = ops; inode->i_fop = &simple_dir_operations; + inode->i_uid = d_inode(dentry->d_parent)->i_uid; + inode->i_gid = d_inode(dentry->d_parent)->i_gid; /* directory inodes start off with i_nlink == 2 (for "." entry) */ inc_nlink(inode); From bdc732d112f3e2c4160fe03c62c32308529ab0f6 Mon Sep 17 00:00:00 2001 From: "Steven Rostedt (VMware)" Date: Tue, 7 Dec 2021 17:17:29 -0500 Subject: [PATCH 09/52] UPSTREAM: tracefs: Set all files to the same group ownership as the mount option commit 48b27b6b5191e2e1f2798cd80877b6e4ef47c351 upstream. As people have been asking to allow non-root processes to have access to the tracefs directory, it was considered best to only allow groups to have access to the directory, where it is easier to just set the tracefs file system to a specific group (as other would be too dangerous), and that way the admins could pick which processes would have access to tracefs. Unfortunately, this broke tooling on Android that expected the other bit to be set. For some special cases, for non-root tools to trace the system, tracefs would be mounted and change the permissions of the top level directory which gave access to all running tasks permission to the tracing directory. Even though this would be dangerous to do in a production environment, for testing environments this can be useful. Now with the new changes to not allow other (which is still the proper thing to do), it breaks the testing tooling. Now more code needs to be loaded on the system to change ownership of the tracing directory. The real solution is to have tracefs honor the gid=xxx option when mounting. That is, (tracing group tracing has value 1003) mount -t tracefs -o gid=1003 tracefs /sys/kernel/tracing should have it that all files in the tracing directory should be of the given group. Copy the logic from d_walk() from dcache.c and simplify it for the mount case of tracefs if gid is set. All the files in tracefs will be walked and their group will be set to the value passed in. Link: https://lkml.kernel.org/r/20211207171729.2a54e1b3@gandalf.local.home Cc: Ingo Molnar Cc: Kees Cook Cc: Andrew Morton Cc: Linus Torvalds Cc: linux-fsdevel@vger.kernel.org Cc: Al Viro Cc: Greg Kroah-Hartman Reported-by: Kalesh Singh Reported-by: Yabin Cui Fixes: 49d67e445742 ("tracefs: Have tracefs directories not set OTH permission bits by default") Signed-off-by: Steven Rostedt (VMware) Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 5f1f94c26b0d0abb9931d7b0864719078585b28a) Bug: 214061655 Signed-off-by: Roger Liao Change-Id: Ib82bc6fec33f9fd2f926d76db752d43ec8db8dd1 --- fs/tracefs/inode.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index 3d7bb4c8c261..ade05887070d 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -159,6 +159,77 @@ struct tracefs_fs_info { struct tracefs_mount_opts mount_opts; }; +static void change_gid(struct dentry *dentry, kgid_t gid) +{ + if (!dentry->d_inode) + return; + dentry->d_inode->i_gid = gid; +} + +/* + * Taken from d_walk, but without he need for handling renames. + * Nothing can be renamed while walking the list, as tracefs + * does not support renames. This is only called when mounting + * or remounting the file system, to set all the files to + * the given gid. + */ +static void set_gid(struct dentry *parent, kgid_t gid) +{ + struct dentry *this_parent; + struct list_head *next; + + this_parent = parent; + spin_lock(&this_parent->d_lock); + + change_gid(this_parent, gid); +repeat: + next = this_parent->d_subdirs.next; +resume: + while (next != &this_parent->d_subdirs) { + struct list_head *tmp = next; + struct dentry *dentry = list_entry(tmp, struct dentry, d_child); + next = tmp->next; + + spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); + + change_gid(dentry, gid); + + if (!list_empty(&dentry->d_subdirs)) { + spin_unlock(&this_parent->d_lock); + spin_release(&dentry->d_lock.dep_map, _RET_IP_); + this_parent = dentry; + spin_acquire(&this_parent->d_lock.dep_map, 0, 1, _RET_IP_); + goto repeat; + } + spin_unlock(&dentry->d_lock); + } + /* + * All done at this level ... ascend and resume the search. + */ + rcu_read_lock(); +ascend: + if (this_parent != parent) { + struct dentry *child = this_parent; + this_parent = child->d_parent; + + spin_unlock(&child->d_lock); + spin_lock(&this_parent->d_lock); + + /* go into the first sibling still alive */ + do { + next = child->d_child.next; + if (next == &this_parent->d_subdirs) + goto ascend; + child = list_entry(next, struct dentry, d_child); + } while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)); + rcu_read_unlock(); + goto resume; + } + rcu_read_unlock(); + spin_unlock(&this_parent->d_lock); + return; +} + static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) { substring_t args[MAX_OPT_ARGS]; @@ -191,6 +262,7 @@ static int tracefs_parse_options(char *data, struct tracefs_mount_opts *opts) if (!gid_valid(gid)) return -EINVAL; opts->gid = gid; + set_gid(tracefs_mount->mnt_root, gid); break; case Opt_mode: if (match_octal(&args[0], &option)) From 3f305a910171e603cdd2cc073acdda85d5028241 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 22 Oct 2021 15:23:31 +0200 Subject: [PATCH 10/52] Revert half of "ANDROID: gic-v3: Add vendor hook to GIC v3" This reverts parts of commit 00c6f53e034e2b580e51d3339dbc4b7f06529073. The hook android_vh_gic_v3_affinity_init is not used by any vendor, so remove it to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 172637074 Cc: Neeraj Upadhyay Cc: Prasad Sodagudi Signed-off-by: Greg Kroah-Hartman Change-Id: I30cc4ebf738b77c2ea48df1d74ef5663f0ae1be6 --- drivers/android/vendor_hooks.c | 1 - drivers/irqchip/irq-gic-v3.c | 8 ++------ include/trace/hooks/gic_v3.h | 3 --- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 99d492cf8076..66912f1612d6 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -128,7 +128,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_dump_throttled_rt_tasks); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_printk_hotplug); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_jiffies_update); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_gic_v3_set_affinity); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_gic_v3_affinity_init); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_suspend_epoch_val); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_resume_epoch_val); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_max_freq); diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index da5d5fe0a72b..179b54628888 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -812,15 +812,11 @@ static void __init gic_dist_init(void) * enabled. */ affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id())); - for (i = 32; i < GIC_LINE_NR; i++) { - trace_android_vh_gic_v3_affinity_init(i, GICD_IROUTER, &affinity); + for (i = 32; i < GIC_LINE_NR; i++) gic_write_irouter(affinity, base + GICD_IROUTER + i * 8); - } - for (i = 0; i < GIC_ESPI_NR; i++) { - trace_android_vh_gic_v3_affinity_init(i, GICD_IROUTERnE, &affinity); + for (i = 0; i < GIC_ESPI_NR; i++) gic_write_irouter(affinity, base + GICD_IROUTERnE + i * 8); - } } static int gic_iterate_rdists(int (*fn)(struct redist_region *, void __iomem *)) diff --git a/include/trace/hooks/gic_v3.h b/include/trace/hooks/gic_v3.h index 3afb7379145d..42e0bb934570 100644 --- a/include/trace/hooks/gic_v3.h +++ b/include/trace/hooks/gic_v3.h @@ -12,9 +12,6 @@ */ struct irq_data; struct cpumask; -DECLARE_HOOK(android_vh_gic_v3_affinity_init, - TP_PROTO(int irq, u32 offset, u64 *affinity), - TP_ARGS(irq, offset, affinity)); DECLARE_RESTRICTED_HOOK(android_rvh_gic_v3_set_affinity, TP_PROTO(struct irq_data *d, const struct cpumask *mask_val, u64 *affinity, bool force, void __iomem *base), From e09000ee1915ee62d218e02ffce3eb1a33c91590 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 22 Oct 2021 15:30:40 +0200 Subject: [PATCH 11/52] Revert half of "ANDROID: vendor_hooks: Add hooks for memory when debug" This reverts parts of commit 24149445adaceb3948d5ad5bbb63c62ff2914e83. The hooks android_vh_alloc_pages_slowpath, android_vh_print_slabinfo_header, and android_vh_cache_show are not used by any vendor, so remove them to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 182443489 Cc: Liujie Xie Signed-off-by: Greg Kroah-Hartman Change-Id: I63621110c0c38b7e5d5e5e6f85c513bf00ecc00b --- drivers/android/vendor_hooks.c | 3 --- include/trace/hooks/mm.h | 9 --------- mm/page_alloc.c | 3 +-- mm/slab_common.c | 2 -- 4 files changed, 1 insertion(+), 16 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 66912f1612d6..fe6962df9180 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -267,11 +267,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exit_mm); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_from_fragment_pool); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exclude_reserved_zone); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_include_reserved_zone); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alloc_pages_slowpath); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mem); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_print_slabinfo_header); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_shrink_slab); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cache_show); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpci_override_toggling); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_typec_tcpci_chk_contaminant); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_typec_tcpci_get_vbus); diff --git a/include/trace/hooks/mm.h b/include/trace/hooks/mm.h index 5821f6d74a07..1e7c0a0811de 100644 --- a/include/trace/hooks/mm.h +++ b/include/trace/hooks/mm.h @@ -68,16 +68,7 @@ DECLARE_HOOK(android_vh_include_reserved_zone, DECLARE_HOOK(android_vh_show_mem, TP_PROTO(unsigned int filter, nodemask_t *nodemask), TP_ARGS(filter, nodemask)); -DECLARE_HOOK(android_vh_alloc_pages_slowpath, - TP_PROTO(gfp_t gfp_mask, unsigned int order, unsigned long delta), - TP_ARGS(gfp_mask, order, delta)); -DECLARE_HOOK(android_vh_print_slabinfo_header, - TP_PROTO(struct seq_file *m), - TP_ARGS(m)); struct slabinfo; -DECLARE_HOOK(android_vh_cache_show, - TP_PROTO(struct seq_file *m, struct slabinfo *sinfo, struct kmem_cache *s), - TP_ARGS(m, sinfo, s)); struct dirty_throttle_control; DECLARE_HOOK(android_vh_mm_dirty_limits, TP_PROTO(struct dirty_throttle_control *const gdtc, bool strictlimit, diff --git a/mm/page_alloc.c b/mm/page_alloc.c index e18561a8c5cd..5b9b465582d6 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4778,7 +4778,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, int no_progress_loops; unsigned int cpuset_mems_cookie; int reserve_flags; - unsigned long alloc_start = jiffies; + /* * We also sanity check to catch abuse of atomic reserves being used by * callers that are not in atomic context. @@ -5020,7 +5020,6 @@ fail: warn_alloc(gfp_mask, ac->nodemask, "page allocation failure: order:%u", order); got_pg: - trace_android_vh_alloc_pages_slowpath(gfp_mask, order, alloc_start); return page; } diff --git a/mm/slab_common.c b/mm/slab_common.c index 6a04bfa91df5..c751b18f7e60 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -950,7 +950,6 @@ static void print_slabinfo_header(struct seq_file *m) seq_puts(m, " : globalstat "); seq_puts(m, " : cpustat "); #endif - trace_android_vh_print_slabinfo_header(m); seq_putc(m, '\n'); } @@ -986,7 +985,6 @@ static void cache_show(struct kmem_cache *s, struct seq_file *m) seq_printf(m, " : slabdata %6lu %6lu %6lu", sinfo.active_slabs, sinfo.num_slabs, sinfo.shared_avail); slabinfo_show_stats(m, s); - trace_android_vh_cache_show(m, &sinfo, s); seq_putc(m, '\n'); } From b3e6d6eec69f8dd7b55b16b0b614122f16911be1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 22 Oct 2021 15:35:23 +0200 Subject: [PATCH 12/52] Revert "ANDROID: vendor_hooks: add hook and OEM data for slab shrink" This reverts commit bf769b72164aeef29c303888604266cae5d32264. The hook android_vh_do_shrink_slab is not used by any vendor, so remove it to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 188684131 Cc: rongqianfeng Signed-off-by: Greg Kroah-Hartman Change-Id: I814e3aad76770140063fad4a81951fc025b2b1dd --- drivers/android/vendor_hooks.c | 1 - include/trace/hooks/vmscan.h | 3 --- mm/vmscan.c | 2 -- 3 files changed, 6 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index fe6962df9180..d86c973aa04c 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -268,7 +268,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_get_from_fragment_pool); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_exclude_reserved_zone); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_include_reserved_zone); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_mem); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_do_shrink_slab); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpci_override_toggling); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_typec_tcpci_chk_contaminant); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_typec_tcpci_get_vbus); diff --git a/include/trace/hooks/vmscan.h b/include/trace/hooks/vmscan.h index b6b77d9895cd..ecbff00093ee 100644 --- a/include/trace/hooks/vmscan.h +++ b/include/trace/hooks/vmscan.h @@ -22,9 +22,6 @@ DECLARE_HOOK(android_vh_shrink_slab_bypass, DECLARE_HOOK(android_vh_tune_inactive_ratio, TP_PROTO(unsigned long *inactive_ratio, int file), TP_ARGS(inactive_ratio, file)) -DECLARE_HOOK(android_vh_do_shrink_slab, - TP_PROTO(struct shrinker *shrinker, struct shrink_control *shrinkctl, int priority), - TP_ARGS(shrinker, shrinkctl, priority)); DECLARE_RESTRICTED_HOOK(android_rvh_set_balance_anon_file_reclaim, TP_PROTO(bool *balance_anon_file_reclaim), TP_ARGS(balance_anon_file_reclaim), 1); diff --git a/mm/vmscan.c b/mm/vmscan.c index d49cd9cb79e0..3f5a834dd764 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -451,8 +451,6 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, : SHRINK_BATCH; long scanned = 0, next_deferred; - trace_android_vh_do_shrink_slab(shrinker, shrinkctl, priority); - if (!(shrinker->flags & SHRINKER_NUMA_AWARE)) nid = 0; From 92ab2aeca5aee77423736ffef6b3c5022b206adc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Oct 2021 16:06:41 +0200 Subject: [PATCH 13/52] Revert "ANDROID: GKI: net: add vendor hooks for 'struct sock' lifecycle" This reverts commit 0ed7424fa0cc7253718f29972af0a7362bc4a961. The hooks android_rvh_sk_alloc and android_rvh_sk_free are not used by any vendor, so remove them to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 171013716 Cc: Vignesh Saravanaperumal Signed-off-by: Greg Kroah-Hartman Change-Id: I5fa860e75a0640bc02d1dffeb556497badd6f3bf --- drivers/android/vendor_hooks.c | 2 -- include/trace/hooks/net.h | 6 +----- net/core/sock.c | 5 ----- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index d86c973aa04c..8d79781cd6a4 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -89,8 +89,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_prepare_prio_fork); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_finish_prio_fork); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_user_nice); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_setscheduler); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_sk_alloc); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_sk_free); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_nf_conn_alloc); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_nf_conn_free); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_arch_set_freq_scale); diff --git a/include/trace/hooks/net.h b/include/trace/hooks/net.h index 6715aa4eb668..6296d57d4b2a 100644 --- a/include/trace/hooks/net.h +++ b/include/trace/hooks/net.h @@ -19,15 +19,11 @@ DECLARE_HOOK(android_vh_kfree_skb, TP_PROTO(struct sk_buff *skb), TP_ARGS(skb)); struct nf_conn; -struct sock; +struct sock; /* needed for CRC preservation */ DECLARE_RESTRICTED_HOOK(android_rvh_nf_conn_alloc, TP_PROTO(struct nf_conn *nf_conn), TP_ARGS(nf_conn), 1); DECLARE_RESTRICTED_HOOK(android_rvh_nf_conn_free, TP_PROTO(struct nf_conn *nf_conn), TP_ARGS(nf_conn), 1); -DECLARE_RESTRICTED_HOOK(android_rvh_sk_alloc, - TP_PROTO(struct sock *sock), TP_ARGS(sock), 1); -DECLARE_RESTRICTED_HOOK(android_rvh_sk_free, - TP_PROTO(struct sock *sock), TP_ARGS(sock), 1); /* macro versions of hooks are no longer required */ diff --git a/net/core/sock.c b/net/core/sock.c index 4f9409db11dc..059605a3ec4e 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -136,7 +136,6 @@ #include #include -#include #include #include @@ -1696,8 +1695,6 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, if (security_sk_alloc(sk, family, priority)) goto out_free; - trace_android_rvh_sk_alloc(sk); - if (!try_module_get(prot->owner)) goto out_free_sec; sk_tx_queue_clear(sk); @@ -1707,7 +1704,6 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, out_free_sec: security_sk_free(sk); - trace_android_rvh_sk_free(sk); out_free: if (slab != NULL) kmem_cache_free(slab, sk); @@ -1727,7 +1723,6 @@ static void sk_prot_free(struct proto *prot, struct sock *sk) cgroup_sk_free(&sk->sk_cgrp_data); mem_cgroup_sk_free(sk); security_sk_free(sk); - trace_android_rvh_sk_free(sk); if (slab != NULL) kmem_cache_free(slab, sk); else From d8fe0b1fc2f592e5f0b56c2d9a31a46d989ecdf1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Oct 2021 16:56:32 +0200 Subject: [PATCH 14/52] Revert "ANDROID: GKI: net: add vendor hooks for 'struct nf_conn' lifecycle" This reverts commit 4d3095647872844a0449478beaf61db24cad779f. The hooks android_rvh_nf_conn_alloc and android_rvh_nf_conn_free were not used by any vendor, so remove them to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 171013716 Cc: Vignesh Saravanaperumal Signed-off-by: Greg Kroah-Hartman Change-Id: I069a798036056feadb2c933da42d405b7bf22cd4 --- drivers/android/vendor_hooks.c | 2 -- include/trace/hooks/net.h | 6 +----- net/netfilter/nf_conntrack_core.c | 3 --- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 8d79781cd6a4..bdfd287971c6 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -89,8 +89,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_prepare_prio_fork); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_finish_prio_fork); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_set_user_nice); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_setscheduler); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_nf_conn_alloc); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_nf_conn_free); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_arch_set_freq_scale); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_is_fpsimd_save); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_binder_transaction_init); diff --git a/include/trace/hooks/net.h b/include/trace/hooks/net.h index 6296d57d4b2a..acb2fd2c7e07 100644 --- a/include/trace/hooks/net.h +++ b/include/trace/hooks/net.h @@ -18,12 +18,8 @@ DECLARE_HOOK(android_vh_ptype_head, DECLARE_HOOK(android_vh_kfree_skb, TP_PROTO(struct sk_buff *skb), TP_ARGS(skb)); -struct nf_conn; +struct nf_conn; /* needed for CRC preservation */ struct sock; /* needed for CRC preservation */ -DECLARE_RESTRICTED_HOOK(android_rvh_nf_conn_alloc, - TP_PROTO(struct nf_conn *nf_conn), TP_ARGS(nf_conn), 1); -DECLARE_RESTRICTED_HOOK(android_rvh_nf_conn_free, - TP_PROTO(struct nf_conn *nf_conn), TP_ARGS(nf_conn), 1); /* macro versions of hooks are no longer required */ diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index c8a2e09a9182..be821c274325 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1496,8 +1496,6 @@ __nf_conntrack_alloc(struct net *net, nf_ct_zone_add(ct, zone); - trace_android_rvh_nf_conn_alloc(ct); - /* Because we use RCU lookups, we set ct_general.use to zero before * this is inserted in any list. */ @@ -1530,7 +1528,6 @@ void nf_conntrack_free(struct nf_conn *ct) nf_ct_ext_destroy(ct); kmem_cache_free(nf_conntrack_cachep, ct); smp_mb__before_atomic(); - trace_android_rvh_nf_conn_free(ct); atomic_dec(&net->ct.count); } EXPORT_SYMBOL_GPL(nf_conntrack_free); From 4b3396046c76922a86ea3bb0792f0095b59d19f7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 21 Oct 2021 13:29:34 +0200 Subject: [PATCH 15/52] Revert "ANDROID: vendor_hooks: Add a hook for task tagging" This reverts commit cadbca1c5e17b746b994cd6b18ae6d927f41ae5e. The hook android_vh_set_task_comm is not used by any vendor, so remove it to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 189352151 Cc: ted.lin Signed-off-by: Greg Kroah-Hartman Change-Id: I005ad1c1a55f8646e5bbccd142827eed553411f6 --- drivers/android/vendor_hooks.c | 1 - fs/exec.c | 2 -- include/trace/hooks/sched.h | 4 ---- 3 files changed, 7 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index bdfd287971c6..afbf68f586f7 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -325,7 +325,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_save_vmalloc_stack); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_show_stack_hash); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_save_track_hash); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_vmpressure); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_set_task_comm); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpufreq_acct_update_power); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_typec_tcpm_log); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_media_device_setup_link); diff --git a/fs/exec.c b/fs/exec.c index ec5ef10ce2db..5ce144cf810f 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -73,7 +73,6 @@ #include "internal.h" #include -#include EXPORT_TRACEPOINT_SYMBOL_GPL(task_rename); @@ -1230,7 +1229,6 @@ void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec) strlcpy(tsk->comm, buf, sizeof(tsk->comm)); task_unlock(tsk); perf_event_comm(tsk, exec); - trace_android_vh_set_task_comm(tsk); } /* diff --git a/include/trace/hooks/sched.h b/include/trace/hooks/sched.h index 92690acc1197..55fc6c3a1a89 100644 --- a/include/trace/hooks/sched.h +++ b/include/trace/hooks/sched.h @@ -363,10 +363,6 @@ DECLARE_HOOK(android_vh_dup_task_struct, TP_PROTO(struct task_struct *tsk, struct task_struct *orig), TP_ARGS(tsk, orig)); -DECLARE_HOOK(android_vh_set_task_comm, - TP_PROTO(struct task_struct *p), - TP_ARGS(p)); - DECLARE_RESTRICTED_HOOK(android_rvh_find_new_ilb, TP_PROTO(struct cpumask *nohz_idle_cpus_mask, int *ilb), TP_ARGS(nohz_idle_cpus_mask, ilb), 1); From 9f58bcd6145927813fc30704e76ff46e992779e5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Oct 2021 17:31:20 +0200 Subject: [PATCH 16/52] Revert half of "ANDROID: vendor_hooks: Add param for android_vh_cpu_up/down" This reverts half of commit 496b17304af015d57562344e188d8e5809a9a648. This hook is not used, so the param is not needed at all. Step on the way to remove the hook entirely. Bug: 203756332 Bug: 203492840 Cc: Liujie Xie Signed-off-by: Greg Kroah-Hartman Change-Id: I84c021f1139e0bbadc3573211a8ee8a24273f5e9 --- include/trace/hooks/cpu.h | 4 ++-- kernel/cpu.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/trace/hooks/cpu.h b/include/trace/hooks/cpu.h index fc3eaf318b25..33ab6ef1f28c 100644 --- a/include/trace/hooks/cpu.h +++ b/include/trace/hooks/cpu.h @@ -15,8 +15,8 @@ DECLARE_HOOK(android_vh_cpu_up, TP_ARGS(cpu)); DECLARE_HOOK(android_vh_cpu_down, - TP_PROTO(unsigned int cpu), - TP_ARGS(cpu)); + TP_PROTO(void *unused), + TP_ARGS(unused)); /* macro versions of hooks are no longer required */ diff --git a/kernel/cpu.c b/kernel/cpu.c index 739597d16bf6..e3b41a8ad8e2 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -1127,7 +1127,7 @@ static int cpu_down(unsigned int cpu, enum cpuhp_state target) { int err; - trace_android_vh_cpu_down(cpu); + trace_android_vh_cpu_down(NULL); cpu_maps_update_begin(); err = cpu_down_maps_locked(cpu, target); From a863cef344a0e028c9016b42dcad02dbc7820e92 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 14 Nov 2021 14:32:53 +0100 Subject: [PATCH 17/52] Revert half of "ANDROID: arm64: add vendor hooks for bti and pauth fault" This reverts half of commit 06d074249fa373865805136b3d34aeb7c20ee5d2. The hooks android_rvh_do_bti is not used by any vendor, so remove them to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203187389 Cc: Sangmoon Kim Signed-off-by: Greg Kroah-Hartman Change-Id: I840399ee4461c6bffa8c8b63d9cd5748d88d2aae --- arch/arm64/kernel/traps.c | 1 - drivers/android/vendor_hooks.c | 1 - include/trace/hooks/traps.h | 5 ----- 3 files changed, 7 deletions(-) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 6c39a61ec115..acc7e7647cbb 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -414,7 +414,6 @@ NOKPROBE_SYMBOL(do_undefinstr); void do_bti(struct pt_regs *regs) { - trace_android_rvh_do_bti(regs, user_mode(regs)); BUG_ON(!user_mode(regs)); force_signal_inject(SIGILL, ILL_ILLOPC, regs->pc, 0); } diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index afbf68f586f7..8dc3d3c10435 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -237,7 +237,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_alter_mutex_list_add); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mutex_unlock_slowpath); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_rwsem_wake_finish); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_undefinstr); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_bti); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_ptrauth_fault); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_bad_mode); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_arm64_serror_panic); diff --git a/include/trace/hooks/traps.h b/include/trace/hooks/traps.h index f8d56a207afc..d1ceb632c1d5 100644 --- a/include/trace/hooks/traps.h +++ b/include/trace/hooks/traps.h @@ -17,11 +17,6 @@ DECLARE_RESTRICTED_HOOK(android_rvh_do_undefinstr, TP_ARGS(regs, user), TP_CONDITION(!user)); -DECLARE_RESTRICTED_HOOK(android_rvh_do_bti, - TP_PROTO(struct pt_regs *regs, bool user), - TP_ARGS(regs, user), - TP_CONDITION(!user)); - DECLARE_RESTRICTED_HOOK(android_rvh_do_ptrauth_fault, TP_PROTO(struct pt_regs *regs, unsigned int esr, bool user), TP_ARGS(regs, esr, user), From a0009ade38735214ec8ff2e55d3b9dead3c5b2f4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 20 Oct 2021 17:33:37 +0200 Subject: [PATCH 18/52] Revert half of "ANDROID: cpu/hotplug: create vendor hook for cpu_up/cpu_down" This reverts parts of commit f7d52eda9f27dff180a165dc3ab7000538943384. The hook android_vh_cpu_down is not used by any vendor, so remove it to help with merge issues with future LTS releases. If this is needed by any real user, it can easily be reverted to add it back and then the symbol should be added to the abi list at the same time to prevent it from being removed again later. Bug: 203756332 Bug: 176152285 Cc: Stephen Dickey Signed-off-by: Greg Kroah-Hartman Change-Id: I66e5308f32b8b11741dd4ea659cd3f79fa9a6526 --- drivers/android/vendor_hooks.c | 1 - include/trace/hooks/cpu.h | 4 ---- kernel/cgroup/cpuset.c | 1 - kernel/cpu.c | 2 -- 4 files changed, 8 deletions(-) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 8dc3d3c10435..c88ff0ddfcf3 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -182,7 +182,6 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_map_util_freq); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_report_bug); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_em_cpu_energy); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_up); -EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cpu_down); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_sched_balance_rt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_timer_calc_index); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_watchdog_timer_softlockup); diff --git a/include/trace/hooks/cpu.h b/include/trace/hooks/cpu.h index 33ab6ef1f28c..8653e34064c3 100644 --- a/include/trace/hooks/cpu.h +++ b/include/trace/hooks/cpu.h @@ -14,10 +14,6 @@ DECLARE_HOOK(android_vh_cpu_up, TP_PROTO(unsigned int cpu), TP_ARGS(cpu)); -DECLARE_HOOK(android_vh_cpu_down, - TP_PROTO(void *unused), - TP_ARGS(unused)); - /* macro versions of hooks are no longer required */ #endif /* _TRACE_HOOK_CPU_H */ diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index a49b1598466d..d956748bab5d 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -3298,7 +3298,6 @@ void cpuset_wait_for_hotplug(void) { flush_work(&cpuset_hotplug_work); } -EXPORT_SYMBOL_GPL(cpuset_wait_for_hotplug); /* * Keep top_cpuset.mems_allowed tracking node_states[N_MEMORY]. diff --git a/kernel/cpu.c b/kernel/cpu.c index e3b41a8ad8e2..5a965aa03e61 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -1127,8 +1127,6 @@ static int cpu_down(unsigned int cpu, enum cpuhp_state target) { int err; - trace_android_vh_cpu_down(NULL); - cpu_maps_update_begin(); err = cpu_down_maps_locked(cpu, target); cpu_maps_update_done(); From aee6af70464661072b38742daadf7014b1d6806b Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Mon, 9 Aug 2021 19:14:00 +0800 Subject: [PATCH 19/52] UPSTREAM: coresight: tmc-etr: Add barrier after updating AUX ring buffer Since a memory barrier is required between AUX trace data store and aux_head store, and the AUX trace data is filled with memcpy(), it's sufficient to use smp_wmb() so can ensure the trace data is visible prior to updating aux_head. Bug: 213931796 Signed-off-by: Leo Yan Reviewed-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20210809111407.596077-3-leo.yan@linaro.org Signed-off-by: Suzuki K Poulose Signed-off-by: Mathieu Poirier (cherry picked from commit 26701ceb4c2c6bfa5f8c8984fa1a1ea08fa0f02c) Signed-off-by: Qais Yousef Change-Id: I99ae5605d18d6c9c1a908f79611a464b3c17fc2f --- drivers/hwtracing/coresight/coresight-tmc-etr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index ea5027e397d0..ba621a9808fd 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -1563,6 +1563,14 @@ tmc_update_etr_buffer(struct coresight_device *csdev, */ if (etr_perf->snapshot) handle->head += size; + + /* + * Ensure that the AUX trace data is visible before the aux_head + * is updated via perf_aux_output_end(), as expected by the + * perf ring buffer. + */ + smp_wmb(); + out: /* * Don't set the TRUNCATED flag in snapshot mode because 1) the From 79b64fa780851eb40fc4f400d4d8967350eaa635 Mon Sep 17 00:00:00 2001 From: Leo Yan Date: Sun, 5 Sep 2021 11:21:44 +0800 Subject: [PATCH 20/52] UPSTREAM: coresight: tmc-etr: Speed up for bounce buffer in flat mode The AUX bounce buffer is allocated with API dma_alloc_coherent(), in the low level's architecture code, e.g. for Arm64, it maps the memory with the attribution "Normal non-cacheable"; this can be concluded from the definition for pgprot_dmacoherent() in arch/arm64/include/asm/pgtable.h. Later when access the AUX bounce buffer, since the memory mapping is non-cacheable, it's low efficiency due to every load instruction must reach out DRAM. This patch changes to allocate pages with dma_alloc_noncoherent(), the driver can access the memory via cacheable mapping; therefore, load instructions can fetch data from cache lines rather than always read data from DRAM, the driver can boost memory performance. After using the cacheable mapping, the driver uses dma_sync_single_for_cpu() to invalidate cacheline prior to read bounce buffer so can avoid read stale trace data. By measurement the duration for function tmc_update_etr_buffer() with ftrace function_graph tracer, it shows the performance significant improvement for copying 4MiB data from bounce buffer: # echo tmc_etr_get_data_flat_buf > set_graph_notrace // avoid noise # echo tmc_update_etr_buffer > set_graph_function # echo function_graph > current_tracer before: # CPU DURATION FUNCTION CALLS # | | | | | | | 2) | tmc_update_etr_buffer() { ... 2) # 8148.320 us | } after: # CPU DURATION FUNCTION CALLS # | | | | | | | 2) | tmc_update_etr_buffer() { ... 2) # 2525.420 us | } Bug: 213931796 Signed-off-by: Leo Yan Reviewed-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20210905032144.966766-1-leo.yan@linaro.org Signed-off-by: Mathieu Poirier (cherry picked from commit 0abd076217a39c4abc47dcd84d0c8f491f87cbe7) Signed-off-by: Qais Yousef Change-Id: I6adf07f35c90ea298b5a875298afc062696d0d6f --- .../hwtracing/coresight/coresight-tmc-etr.c | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c index ba621a9808fd..ec092b605c63 100644 --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c @@ -609,8 +609,9 @@ static int tmc_etr_alloc_flat_buf(struct tmc_drvdata *drvdata, if (!flat_buf) return -ENOMEM; - flat_buf->vaddr = dma_alloc_coherent(real_dev, etr_buf->size, - &flat_buf->daddr, GFP_KERNEL); + flat_buf->vaddr = dma_alloc_noncoherent(real_dev, etr_buf->size, + &flat_buf->daddr, + DMA_FROM_DEVICE, GFP_KERNEL); if (!flat_buf->vaddr) { kfree(flat_buf); return -ENOMEM; @@ -631,14 +632,18 @@ static void tmc_etr_free_flat_buf(struct etr_buf *etr_buf) if (flat_buf && flat_buf->daddr) { struct device *real_dev = flat_buf->dev->parent; - dma_free_coherent(real_dev, flat_buf->size, - flat_buf->vaddr, flat_buf->daddr); + dma_free_noncoherent(real_dev, etr_buf->size, + flat_buf->vaddr, flat_buf->daddr, + DMA_FROM_DEVICE); } kfree(flat_buf); } static void tmc_etr_sync_flat_buf(struct etr_buf *etr_buf, u64 rrp, u64 rwp) { + struct etr_flat_buf *flat_buf = etr_buf->private; + struct device *real_dev = flat_buf->dev->parent; + /* * Adjust the buffer to point to the beginning of the trace data * and update the available trace data. @@ -648,6 +653,19 @@ static void tmc_etr_sync_flat_buf(struct etr_buf *etr_buf, u64 rrp, u64 rwp) etr_buf->len = etr_buf->size; else etr_buf->len = rwp - rrp; + + /* + * The driver always starts tracing at the beginning of the buffer, + * the only reason why we would get a wrap around is when the buffer + * is full. Sync the entire buffer in one go for this case. + */ + if (etr_buf->offset + etr_buf->len > etr_buf->size) + dma_sync_single_for_cpu(real_dev, flat_buf->daddr, + etr_buf->size, DMA_FROM_DEVICE); + else + dma_sync_single_for_cpu(real_dev, + flat_buf->daddr + etr_buf->offset, + etr_buf->len, DMA_FROM_DEVICE); } static ssize_t tmc_etr_get_data_flat_buf(struct etr_buf *etr_buf, From 2bb8b3c9075947d73918df74bd8ecfdc03f05f8d Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Tue, 14 Sep 2021 11:26:32 +0100 Subject: [PATCH 21/52] BACKPORT: coresight: etm4x: Save restore TRFCR_EL1 When the CPU enters a low power mode, the TRFCR_EL1 contents could be reset. Thus we need to save/restore the TRFCR_EL1 along with the ETM4x registers to allow the tracing. The TRFCR related helpers are in a new header file, as we need to use them for TRBE in the later patches. Bug: 213931796 Cc: Mathieu Poirier Cc: Anshuman Khandual Cc: Mike Leach Cc: Leo Yan Reviewed-by: Anshuman Khandual Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20210914102641.1852544-2-suzuki.poulose@arm.com [Fixed cosmetic details] Signed-off-by: Mathieu Poirier (cherry picked from commit 937d3f58cacf377cab7c32e475e1ffa91d611dce) Signed-off-by: Qais Yousef [Conflict in in drivers/hwtracing/coresight/coresight-etm4x-core.c, unnecessary new includes were removed] Change-Id: Id81d9505e86664c09ec6876e48c4e9c2d945503e --- .../coresight/coresight-etm4x-core.c | 43 +++++++++++++------ drivers/hwtracing/coresight/coresight-etm4x.h | 2 + .../coresight/coresight-self-hosted-trace.h | 24 +++++++++++ 3 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 drivers/hwtracing/coresight/coresight-self-hosted-trace.h diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index 6fee02bf7b71..ea4b8955c1ad 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -39,6 +39,7 @@ #include "coresight-etm4x.h" #include "coresight-etm-perf.h" +#include "coresight-self-hosted-trace.h" static int boot_enable; module_param(boot_enable, int, 0444); @@ -990,7 +991,7 @@ static void cpu_enable_tracing(struct etmv4_drvdata *drvdata) if (is_kernel_in_hyp_mode()) trfcr |= TRFCR_EL2_CX; - write_sysreg_s(trfcr, SYS_TRFCR_EL1); + write_trfcr(trfcr); } static void etm4_init_arch_data(void *info) @@ -1528,7 +1529,7 @@ static void etm4_init_trace_id(struct etmv4_drvdata *drvdata) drvdata->trcid = coresight_get_trace_id(drvdata->cpu); } -static int etm4_cpu_save(struct etmv4_drvdata *drvdata) +static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) { int i, ret = 0; struct etmv4_save_state *state; @@ -1667,7 +1668,23 @@ out: return ret; } -static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) +static int etm4_cpu_save(struct etmv4_drvdata *drvdata) +{ + int ret = 0; + + /* Save the TRFCR irrespective of whether the ETM is ON */ + if (drvdata->trfc) + drvdata->save_trfcr = read_trfcr(); + /* + * Save and restore the ETM Trace registers only if + * the ETM is active. + */ + if (local_read(&drvdata->mode) && drvdata->save_state) + ret = __etm4_cpu_save(drvdata); + return ret; +} + +static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) { int i; struct etmv4_save_state *state = drvdata->save_state; @@ -1763,6 +1780,14 @@ static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) etm4_cs_lock(drvdata, csa); } +static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) +{ + if (drvdata->trfc) + write_trfcr(drvdata->save_trfcr); + if (drvdata->state_needs_restore) + __etm4_cpu_restore(drvdata); +} + static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd, void *v) { @@ -1774,23 +1799,17 @@ static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd, drvdata = etmdrvdata[cpu]; - if (!drvdata->save_state) - return NOTIFY_OK; - if (WARN_ON_ONCE(drvdata->cpu != cpu)) return NOTIFY_BAD; switch (cmd) { case CPU_PM_ENTER: - /* save the state if self-hosted coresight is in use */ - if (local_read(&drvdata->mode)) - if (etm4_cpu_save(drvdata)) - return NOTIFY_BAD; + if (etm4_cpu_save(drvdata)) + return NOTIFY_BAD; break; case CPU_PM_EXIT: case CPU_PM_ENTER_FAILED: - if (drvdata->state_needs_restore) - etm4_cpu_restore(drvdata); + etm4_cpu_restore(drvdata); break; default: return NOTIFY_DONE; diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index e5b79bdb9851..82cba16b73a6 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -921,6 +921,7 @@ struct etmv4_save_state { * @lpoverride: If the implementation can support low-power state over. * @trfc: If the implementation supports Arm v8.4 trace filter controls. * @config: structure holding configuration parameters. + * @save_trfcr: Saved TRFCR_EL1 register during a CPU PM event. * @save_state: State to be preserved across power loss * @state_needs_restore: True when there is context to restore after PM exit * @skip_power_up: Indicates if an implementation can skip powering up @@ -973,6 +974,7 @@ struct etmv4_drvdata { bool lpoverride; bool trfc; struct etmv4_config config; + u64 save_trfcr; struct etmv4_save_state *save_state; bool state_needs_restore; bool skip_power_up; diff --git a/drivers/hwtracing/coresight/coresight-self-hosted-trace.h b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h new file mode 100644 index 000000000000..303d71911870 --- /dev/null +++ b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Arm v8 Self-Hosted trace support. + * + * Copyright (C) 2021 ARM Ltd. + */ + +#ifndef __CORESIGHT_SELF_HOSTED_TRACE_H +#define __CORESIGHT_SELF_HOSTED_TRACE_H + +#include + +static inline u64 read_trfcr(void) +{ + return read_sysreg_s(SYS_TRFCR_EL1); +} + +static inline void write_trfcr(u64 val) +{ + write_sysreg_s(val, SYS_TRFCR_EL1); + isb(); +} + +#endif /* __CORESIGHT_SELF_HOSTED_TRACE_H */ From 71aebf8793c5a253824896b673968b8bfa863ac0 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Tue, 14 Sep 2021 11:26:33 +0100 Subject: [PATCH 22/52] UPSTREAM: coresight: etm4x: Use Trace Filtering controls dynamically The Trace Filtering support (FEAT_TRF) ensures that the ETM can be prohibited from generating any trace for a given EL. This is much stricter knob, than the TRCVICTLR exception level masks, which doesn't prevent the ETM from generating Context packets for an "excluded" EL. At the moment, we do a onetime enable trace at user and kernel and leave it untouched for the kernel life time. This implies that the ETM could potentially generate trace packets containing the kernel addresses, and thus leaking the kernel virtual address in the trace. This patch makes the switch dynamic, by honoring the filters set by the user and enforcing them in the TRFCR controls. We also rename the cpu_enable_tracing() appropriately to cpu_detect_trace_filtering() and the drvdata member trfc => trfcr to indicate the "value" of the TRFCR_EL1. Bug: 213931796 Cc: Mathieu Poirier Cc: Al Grant Cc: Mike Leach Cc: Leo Yan Signed-off-by: Suzuki K Poulose Reviewed-by: Anshuman Khandual Link: https://lore.kernel.org/r/20210914102641.1852544-3-suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier (cherry picked from commit 5f6fd1aa8cc147b111af1a833574487a87237dc0) Signed-off-by: Qais Yousef Change-Id: If6ae831b3d1f5334648eb3d02262812527e2bb9d --- .../coresight/coresight-etm4x-core.c | 63 ++++++++++++++----- drivers/hwtracing/coresight/coresight-etm4x.h | 7 ++- .../coresight/coresight-self-hosted-trace.h | 7 +++ 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c index ea4b8955c1ad..bfcf9e0415c2 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c @@ -237,6 +237,45 @@ struct etm4_enable_arg { int rc; }; +/* + * etm4x_prohibit_trace - Prohibit the CPU from tracing at all ELs. + * When the CPU supports FEAT_TRF, we could move the ETM to a trace + * prohibited state by filtering the Exception levels via TRFCR_EL1. + */ +static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata) +{ + /* If the CPU doesn't support FEAT_TRF, nothing to do */ + if (!drvdata->trfcr) + return; + cpu_prohibit_trace(); +} + +/* + * etm4x_allow_trace - Allow CPU tracing in the respective ELs, + * as configured by the drvdata->config.mode for the current + * session. Even though we have TRCVICTLR bits to filter the + * trace in the ELs, it doesn't prevent the ETM from generating + * a packet (e.g, TraceInfo) that might contain the addresses from + * the excluded levels. Thus we use the additional controls provided + * via the Trace Filtering controls (FEAT_TRF) to make sure no trace + * is generated for the excluded ELs. + */ +static void etm4x_allow_trace(struct etmv4_drvdata *drvdata) +{ + u64 trfcr = drvdata->trfcr; + + /* If the CPU doesn't support FEAT_TRF, nothing to do */ + if (!trfcr) + return; + + if (drvdata->config.mode & ETM_MODE_EXCL_KERN) + trfcr &= ~TRFCR_ELx_ExTRE; + if (drvdata->config.mode & ETM_MODE_EXCL_USER) + trfcr &= ~TRFCR_ELx_E0TRE; + + write_trfcr(trfcr); +} + #ifdef CONFIG_ETM4X_IMPDEF_FEATURE #define HISI_HIP08_AMBA_ID 0x000b6d01 @@ -441,6 +480,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) if (etm4x_is_ete(drvdata)) etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + etm4x_allow_trace(drvdata); /* Enable the trace unit */ etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); @@ -724,7 +764,6 @@ static int etm4_enable(struct coresight_device *csdev, static void etm4_disable_hw(void *info) { u32 control; - u64 trfcr; struct etmv4_drvdata *drvdata = info; struct etmv4_config *config = &drvdata->config; struct coresight_device *csdev = drvdata->csdev; @@ -751,12 +790,7 @@ static void etm4_disable_hw(void *info) * If the CPU supports v8.4 Trace filter Control, * set the ETM to trace prohibited region. */ - if (drvdata->trfc) { - trfcr = read_sysreg_s(SYS_TRFCR_EL1); - write_sysreg_s(trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE), - SYS_TRFCR_EL1); - isb(); - } + etm4x_prohibit_trace(drvdata); /* * Make sure everything completes before disabling, as recommended * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register, @@ -772,9 +806,6 @@ static void etm4_disable_hw(void *info) if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1)) dev_err(etm_dev, "timeout while waiting for PM stable Trace Status\n"); - if (drvdata->trfc) - write_sysreg_s(trfcr, SYS_TRFCR_EL1); - /* read the status of the single shot comparators */ for (i = 0; i < drvdata->nr_ss_cmp; i++) { config->ss_status[i] = @@ -969,15 +1000,15 @@ static bool etm4_init_csdev_access(struct etmv4_drvdata *drvdata, return false; } -static void cpu_enable_tracing(struct etmv4_drvdata *drvdata) +static void cpu_detect_trace_filtering(struct etmv4_drvdata *drvdata) { u64 dfr0 = read_sysreg(id_aa64dfr0_el1); u64 trfcr; + drvdata->trfcr = 0; if (!cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_TRACE_FILT_SHIFT)) return; - drvdata->trfc = true; /* * If the CPU supports v8.4 SelfHosted Tracing, enable * tracing at the kernel EL and EL0, forcing to use the @@ -991,7 +1022,7 @@ static void cpu_enable_tracing(struct etmv4_drvdata *drvdata) if (is_kernel_in_hyp_mode()) trfcr |= TRFCR_EL2_CX; - write_trfcr(trfcr); + drvdata->trfcr = trfcr; } static void etm4_init_arch_data(void *info) @@ -1177,7 +1208,7 @@ static void etm4_init_arch_data(void *info) /* NUMCNTR, bits[30:28] number of counters available for tracing */ drvdata->nr_cntr = BMVAL(etmidr5, 28, 30); etm4_cs_lock(drvdata, csa); - cpu_enable_tracing(drvdata); + cpu_detect_trace_filtering(drvdata); } static inline u32 etm4_get_victlr_access_type(struct etmv4_config *config) @@ -1673,7 +1704,7 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata) int ret = 0; /* Save the TRFCR irrespective of whether the ETM is ON */ - if (drvdata->trfc) + if (drvdata->trfcr) drvdata->save_trfcr = read_trfcr(); /* * Save and restore the ETM Trace registers only if @@ -1782,7 +1813,7 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) { - if (drvdata->trfc) + if (drvdata->trfcr) write_trfcr(drvdata->save_trfcr); if (drvdata->state_needs_restore) __etm4_cpu_restore(drvdata); diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h index 82cba16b73a6..3c4d69b096ca 100644 --- a/drivers/hwtracing/coresight/coresight-etm4x.h +++ b/drivers/hwtracing/coresight/coresight-etm4x.h @@ -919,7 +919,10 @@ struct etmv4_save_state { * @nooverflow: Indicate if overflow prevention is supported. * @atbtrig: If the implementation can support ATB triggers * @lpoverride: If the implementation can support low-power state over. - * @trfc: If the implementation supports Arm v8.4 trace filter controls. + * @trfcr: If the CPU supports FEAT_TRF, value of the TRFCR_ELx that + * allows tracing at all ELs. We don't want to compute this + * at runtime, due to the additional setting of TRFCR_CX when + * in EL2. Otherwise, 0. * @config: structure holding configuration parameters. * @save_trfcr: Saved TRFCR_EL1 register during a CPU PM event. * @save_state: State to be preserved across power loss @@ -972,7 +975,7 @@ struct etmv4_drvdata { bool nooverflow; bool atbtrig; bool lpoverride; - bool trfc; + u64 trfcr; struct etmv4_config config; u64 save_trfcr; struct etmv4_save_state *save_state; diff --git a/drivers/hwtracing/coresight/coresight-self-hosted-trace.h b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h index 303d71911870..23f05df3f173 100644 --- a/drivers/hwtracing/coresight/coresight-self-hosted-trace.h +++ b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h @@ -21,4 +21,11 @@ static inline void write_trfcr(u64 val) isb(); } +static inline void cpu_prohibit_trace(void) +{ + u64 trfcr = read_trfcr(); + + /* Prohibit tracing at EL0 & the kernel EL */ + write_trfcr(trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE)); +} #endif /* __CORESIGHT_SELF_HOSTED_TRACE_H */ From dd3256d4392c3753b11237697fd7bffd769ad786 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Thu, 14 Oct 2021 15:22:38 +0100 Subject: [PATCH 23/52] UPSTREAM: coresight: trbe: Defer the probe on offline CPUs If a CPU is offline during the driver init, we could end up causing a kernel crash trying to register the coresight device for the TRBE instance. The trbe_cpudata for the TRBE instance is initialized only when it is probed. Otherwise, we could end up dereferencing a NULL cpudata->drvdata. e.g: [ 0.149999] coresight ete0: CPU0: ete v1.1 initialized [ 0.149999] coresight-etm4x ete_1: ETM arch init failed [ 0.149999] coresight-etm4x: probe of ete_1 failed with error -22 [ 0.150085] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000050 [ 0.150085] Mem abort info: [ 0.150085] ESR = 0x96000005 [ 0.150085] EC = 0x25: DABT (current EL), IL = 32 bits [ 0.150085] SET = 0, FnV = 0 [ 0.150085] EA = 0, S1PTW = 0 [ 0.150085] Data abort info: [ 0.150085] ISV = 0, ISS = 0x00000005 [ 0.150085] CM = 0, WnR = 0 [ 0.150085] [0000000000000050] user address but active_mm is swapper [ 0.150085] Internal error: Oops: 96000005 [#1] PREEMPT SMP [ 0.150085] Modules linked in: [ 0.150085] Hardware name: FVP Base RevC (DT) [ 0.150085] pstate: 00800009 (nzcv daif -PAN +UAO -TCO BTYPE=--) [ 0.150155] pc : arm_trbe_register_coresight_cpu+0x74/0x144 [ 0.150155] lr : arm_trbe_register_coresight_cpu+0x48/0x144 ... [ 0.150237] Call trace: [ 0.150237] arm_trbe_register_coresight_cpu+0x74/0x144 [ 0.150237] arm_trbe_device_probe+0x1c0/0x2d8 [ 0.150259] platform_drv_probe+0x94/0xbc [ 0.150259] really_probe+0x1bc/0x4a8 [ 0.150266] driver_probe_device+0x7c/0xb8 [ 0.150266] device_driver_attach+0x6c/0xac [ 0.150266] __driver_attach+0xc4/0x148 [ 0.150266] bus_for_each_dev+0x7c/0xc8 [ 0.150266] driver_attach+0x24/0x30 [ 0.150266] bus_add_driver+0x100/0x1e0 [ 0.150266] driver_register+0x78/0x110 [ 0.150266] __platform_driver_register+0x44/0x50 [ 0.150266] arm_trbe_init+0x28/0x84 [ 0.150266] do_one_initcall+0x94/0x2bc [ 0.150266] do_initcall_level+0xa4/0x158 [ 0.150266] do_initcalls+0x54/0x94 [ 0.150319] do_basic_setup+0x24/0x30 [ 0.150319] kernel_init_freeable+0xe8/0x14c [ 0.150319] kernel_init+0x14/0x18c [ 0.150319] ret_from_fork+0x10/0x30 [ 0.150319] Code: f94012c8 b0004ce2 9134a442 52819801 (f9402917) [ 0.150319] ---[ end trace d23e0cfe5098535e ]--- [ 0.150346] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b Fix this by skipping the step, if we are unable to probe the CPU. Bug: 213931796 Fixes: 3fbf7f011f24 ("coresight: sink: Add TRBE driver") Reported-by: Bransilav Rankov Cc: Anshuman Khandual Cc: Mathieu Poirier Cc: Mike Leach Cc: Leo Yan Cc: stable Tested-by: Branislav Rankov Signed-off-by: Suzuki K Poulose Reviewed-by: Anshuman Khandual Link: https://lore.kernel.org/r/20211014142238.2221248-1-suzuki.poulose@arm.com Signed-off-by: Mathieu Poirier (cherry picked from commit a08025b3fe56185290a1ea476581f03ca733f967) Signed-off-by: Qais Yousef Change-Id: I34a5a03a8f321cd807731b54d620b3b90135264f --- drivers/hwtracing/coresight/coresight-trbe.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/hwtracing/coresight/coresight-trbe.c b/drivers/hwtracing/coresight/coresight-trbe.c index 176868496879..7b8fed7b63cc 100644 --- a/drivers/hwtracing/coresight/coresight-trbe.c +++ b/drivers/hwtracing/coresight/coresight-trbe.c @@ -869,6 +869,10 @@ static void arm_trbe_register_coresight_cpu(struct trbe_drvdata *drvdata, int cp if (WARN_ON(trbe_csdev)) return; + /* If the TRBE was not probed on the CPU, we shouldn't be here */ + if (WARN_ON(!cpudata->drvdata)) + return; + dev = &cpudata->drvdata->pdev->dev; desc.name = devm_kasprintf(dev, GFP_KERNEL, "trbe%d", cpu); if (!desc.name) @@ -950,7 +954,9 @@ static int arm_trbe_probe_coresight(struct trbe_drvdata *drvdata) return -ENOMEM; for_each_cpu(cpu, &drvdata->supported_cpus) { - smp_call_function_single(cpu, arm_trbe_probe_cpu, drvdata, 1); + /* If we fail to probe the CPU, let us defer it to hotplug callbacks */ + if (smp_call_function_single(cpu, arm_trbe_probe_cpu, drvdata, 1)) + continue; if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) arm_trbe_register_coresight_cpu(drvdata, cpu); if (cpumask_test_cpu(cpu, &drvdata->supported_cpus)) From e48051244a03ff0a24b3bc0fdd8d06badc8e3292 Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Tue, 19 Oct 2021 17:31:39 +0100 Subject: [PATCH 24/52] UPSTREAM: arm64: Add Neoverse-N2, Cortex-A710 CPU part definition Add the CPU Partnumbers for the new Arm designs. Bug: 213931796 Cc: Catalin Marinas Cc: Mark Rutland Cc: Will Deacon Acked-by: Catalin Marinas Reviewed-by: Anshuman Khandual Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20211019163153.3692640-2-suzuki.poulose@arm.com Signed-off-by: Will Deacon (cherry picked from commit 2d0d656700d67239a57afaf617439143d8dac9be) Signed-off-by: Qais Yousef Change-Id: I6fd8750086badd03e486c24036dabdd3d0b14026 --- arch/arm64/include/asm/cputype.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index ef5b040dee44..6f4c4b5a908d 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -72,6 +72,8 @@ #define ARM_CPU_PART_CORTEX_A76 0xD0B #define ARM_CPU_PART_NEOVERSE_N1 0xD0C #define ARM_CPU_PART_CORTEX_A77 0xD0D +#define ARM_CPU_PART_CORTEX_A710 0xD47 +#define ARM_CPU_PART_NEOVERSE_N2 0xD49 #define APM_CPU_PART_POTENZA 0x000 @@ -109,6 +111,8 @@ #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) #define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77) +#define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) +#define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) #define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX) #define MIDR_THUNDERX_83XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_83XX) From a512242e66cea3de1020d83ca9f2977c0a75530b Mon Sep 17 00:00:00 2001 From: Suzuki K Poulose Date: Tue, 19 Oct 2021 17:31:41 +0100 Subject: [PATCH 25/52] BACKPORT: arm64: errata: Add workaround for TSB flush failures Arm Neoverse-N2 (#2067961) and Cortex-A710 (#2054223) suffers from errata, where a TSB (trace synchronization barrier) fails to flush the trace data completely, when executed from a trace prohibited region. In Linux we always execute it after we have moved the PE to trace prohibited region. So, we can apply the workaround every time a TSB is executed. The work around is to issue two TSB consecutively. NOTE: This errata is defined as LOCAL_CPU_ERRATUM, implying that a late CPU could be blocked from booting if it is the first CPU that requires the workaround. This is because we do not allow setting a cpu_hwcaps after the SMP boot. The other alternative is to use "this_cpu_has_cap()" instead of the faster system wide check, which may be a bit of an overhead, given we may have to do this in nvhe KVM host before a guest entry. Bug: 213931796 Cc: Will Deacon Cc: Catalin Marinas Cc: Mathieu Poirier Cc: Mike Leach Cc: Mark Rutland Cc: Anshuman Khandual Cc: Marc Zyngier Acked-by: Catalin Marinas Reviewed-by: Mathieu Poirier Reviewed-by: Anshuman Khandual Signed-off-by: Suzuki K Poulose Link: https://lore.kernel.org/r/20211019163153.3692640-4-suzuki.poulose@arm.com Signed-off-by: Will Deacon (cherry picked from commit fa82d0b4b833790ac4572377fb777dcea24a9d69) [Fix conflict due to another workaround that is not backported (TRBE_OVERWRITE). Also manually update cpucaps.h which is autogenerated in upstream from arch/arm64/tools/cpucaps which we ignored as part of the conflict resolution] Signed-off-by: Qais Yousef Change-Id: I6b40eaa0ac14552c867860133a04619cb556bc31 --- Documentation/arm64/silicon-errata.rst | 4 ++++ arch/arm64/Kconfig | 33 ++++++++++++++++++++++++++ arch/arm64/include/asm/barrier.h | 16 ++++++++++++- arch/arm64/include/asm/cpucaps.h | 1 + arch/arm64/kernel/cpu_errata.c | 19 +++++++++++++++ 5 files changed, 72 insertions(+), 1 deletion(-) diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index 719510247292..5a30b1857420 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -92,12 +92,16 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1349291 | N/A | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1542419 | ARM64_ERRATUM_1542419 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Neoverse-N2 | #2067961 | ARM64_ERRATUM_2067961 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | MMU-500 | #841119,826419 | N/A | +----------------+-----------------+-----------------+-----------------------------+ +----------------+-----------------+-----------------+-----------------------------+ diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 3007e975270c..642a4482dd4e 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -669,6 +669,39 @@ config ARM64_ERRATUM_1508412 If unsure, say Y. +config ARM64_WORKAROUND_TSB_FLUSH_FAILURE + bool + +config ARM64_ERRATUM_2054223 + bool "Cortex-A710: 2054223: workaround TSB instruction failing to flush trace" + default y + select ARM64_WORKAROUND_TSB_FLUSH_FAILURE + help + Enable workaround for ARM Cortex-A710 erratum 2054223 + + Affected cores may fail to flush the trace data on a TSB instruction, when + the PE is in trace prohibited state. This will cause losing a few bytes + of the trace cached. + + Workaround is to issue two TSB consecutively on affected cores. + + If unsure, say Y. + +config ARM64_ERRATUM_2067961 + bool "Neoverse-N2: 2067961: workaround TSB instruction failing to flush trace" + default y + select ARM64_WORKAROUND_TSB_FLUSH_FAILURE + help + Enable workaround for ARM Neoverse-N2 erratum 2067961 + + Affected cores may fail to flush the trace data on a TSB instruction, when + the PE is in trace prohibited state. This will cause losing a few bytes + of the trace cached. + + Workaround is to issue two TSB consecutively on affected cores. + + If unsure, say Y. + config CAVIUM_ERRATUM_22375 bool "Cavium erratum 22375, 24313" default y diff --git a/arch/arm64/include/asm/barrier.h b/arch/arm64/include/asm/barrier.h index bffa8860af1c..e9eeeb14485b 100644 --- a/arch/arm64/include/asm/barrier.h +++ b/arch/arm64/include/asm/barrier.h @@ -23,7 +23,7 @@ #define dsb(opt) asm volatile("dsb " #opt : : : "memory") #define psb_csync() asm volatile("hint #17" : : : "memory") -#define tsb_csync() asm volatile("hint #18" : : : "memory") +#define __tsb_csync() asm volatile("hint #18" : : : "memory") #define csdb() asm volatile("hint #20" : : : "memory") #define spec_bar() asm volatile(ALTERNATIVE("dsb nsh\nisb\n", \ @@ -50,6 +50,20 @@ #define dma_rmb() dmb(oshld) #define dma_wmb() dmb(oshst) + +#define tsb_csync() \ + do { \ + /* \ + * CPUs affected by Arm Erratum 2054223 or 2067961 needs \ + * another TSB to ensure the trace is flushed. The barriers \ + * don't have to be strictly back to back, as long as the \ + * CPU is in trace prohibited state. \ + */ \ + if (cpus_have_final_cap(ARM64_WORKAROUND_TSB_FLUSH_FAILURE)) \ + __tsb_csync(); \ + __tsb_csync(); \ + } while (0) + /* * Generate a mask for array_index__nospec() that is ~0UL when 0 <= idx < sz * and 0 otherwise. diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h index 10a2d914d4ca..c0ff1d4bccab 100644 --- a/arch/arm64/include/asm/cpucaps.h +++ b/arch/arm64/include/asm/cpucaps.h @@ -69,6 +69,7 @@ #define ARM64_WORKAROUND_1508412 58 #define ARM64_HAS_LDAPR 59 #define ARM64_KVM_PROTECTED_MODE 60 +#define ARM64_WORKAROUND_TSB_FLUSH_FAILURE 61 /* kabi: reserve 62 - 76 for future cpu capabilities */ #define ARM64_NCAPS 76 diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c index a63428301f42..7c6d59c4f099 100644 --- a/arch/arm64/kernel/cpu_errata.c +++ b/arch/arm64/kernel/cpu_errata.c @@ -342,6 +342,18 @@ static const struct midr_range erratum_1463225[] = { }; #endif +#ifdef CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE +static const struct midr_range tsb_flush_fail_cpus[] = { +#ifdef CONFIG_ARM64_ERRATUM_2067961 + MIDR_ALL_VERSIONS(MIDR_NEOVERSE_N2), +#endif +#ifdef CONFIG_ARM64_ERRATUM_2054223 + MIDR_ALL_VERSIONS(MIDR_CORTEX_A710), +#endif + {}, +}; +#endif /* CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE */ + const struct arm64_cpu_capabilities arm64_errata[] = { #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE { @@ -527,6 +539,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = { 0, 0, 1, 0), }, +#endif +#ifdef CONFIG_ARM64_WORKAROUND_TSB_FLUSH_FAILURE + { + .desc = "ARM erratum 2067961 or 2054223", + .capability = ARM64_WORKAROUND_TSB_FLUSH_FAILURE, + ERRATA_MIDR_RANGE_LIST(tsb_flush_fail_cpus), + }, #endif { } From fd4c6594f5ce87eb3f6d53bd73eb14689305fdf1 Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Wed, 12 Jan 2022 13:52:50 -0800 Subject: [PATCH 26/52] ANDROID: incremental-fs: fix mount_fs issue Syzbot recently found a number of issues related to incremental-fs (see bug numbers below). All have to do with the fact that incr-fs allows mounts of the same source and target multiple times. The correct behavior for a file system is to allow only one such mount, and then every subsequent attempt should fail with a -EBUSY error code. In case of the issues listed below the common pattern is that the reproducer calls: mount("./file0", "./file0", "incremental-fs", 0, NULL) many times and then invokes a file operation like chmod, setxattr, or open on the ./file0. This causes a recursive call for all the mounted instances, which eventually causes a stack overflow and a kernel crash: BUG: stack guard page was hit at ffffc90000c0fff8 kernel stack overflow (double-fault): 0000 [#1] PREEMPT SMP KASAN The reason why many mounts with the same source and target are possible is because the incfs_mount_fs() as it is allocates a new super_block for every call, regardless of whether a given mount already exists or not. This happens every time the sget() function is called with a test param equal to NULL. The correct behavior for an FS mount implementation is to call appropriate mount vfs call for it's type, i.e. mount_bdev() for a block device backed FS, mount_single() for a pseudo file system, like sysfs that is mounted in a single, well know location, or mount_nodev() for other special purpose FS like overlayfs. In case of incremental-fs the open coded mount logic doesn't check for abusive mount attempts such as overlays. To fix this issue the logic needs to be changed to pass a proper test function to sget() call, which then checks if a super_block for a mount instance has already been allocated and also allows the VFS to properly verify invalid mount attempts. Bug: 211066171 Bug: 213140206 Bug: 213215835 Bug: 211914587 Bug: 211213635 Bug: 213137376 Bug: 211161296 Signed-off-by: Tadeusz Struk Change-Id: I66cfc3f1b5aaffb32b0845b2dad3ff26fe952e27 --- fs/incfs/data_mgmt.c | 1 + fs/incfs/vfs.c | 58 ++++++++++++++++++++++++++++++++------------ fs/incfs/vfs.h | 1 - 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/fs/incfs/data_mgmt.c b/fs/incfs/data_mgmt.c index fbab68a280d5..a383c5b5ad7f 100644 --- a/fs/incfs/data_mgmt.c +++ b/fs/incfs/data_mgmt.c @@ -175,6 +175,7 @@ void incfs_free_mount_info(struct mount_info *mi) kfree(mi->pseudo_file_xattr[i].data); kfree(mi->mi_per_uid_read_timeouts); incfs_free_sysfs_node(mi->mi_sysfs_node); + kfree(mi->mi_options.sysfs_name); kfree(mi); } diff --git a/fs/incfs/vfs.c b/fs/incfs/vfs.c index ea7866fbfd6e..35ac6e3daf8e 100644 --- a/fs/incfs/vfs.c +++ b/fs/incfs/vfs.c @@ -393,7 +393,7 @@ static int iterate_incfs_dir(struct file *file, struct dir_context *ctx) struct mount_info *mi = get_mount_info(file_superblock(file)); bool root; - if (!dir) { + if (!dir || !mi) { error = -EBADF; goto out; } @@ -1336,6 +1336,9 @@ static int dir_rename(struct inode *old_dir, struct dentry *old_dentry, struct dentry *trap; int error = 0; + if (!mi) + return -EBADF; + error = mutex_lock_interruptible(&mi->mi_dir_struct_mutex); if (error) return error; @@ -1664,6 +1667,9 @@ static ssize_t incfs_getxattr(struct dentry *d, const char *name, size_t stored_size; int i; + if (!mi) + return -EBADF; + if (di && di->backing_path.dentry) return vfs_getxattr(di->backing_path.dentry, name, value, size); @@ -1698,6 +1704,9 @@ static ssize_t incfs_setxattr(struct dentry *d, const char *name, size_t *stored_size; int i; + if (!mi) + return -EBADF; + if (di && di->backing_path.dentry) return vfs_setxattr(di->backing_path.dentry, name, value, size, flags); @@ -1736,6 +1745,11 @@ static ssize_t incfs_listxattr(struct dentry *d, char *list, size_t size) return vfs_listxattr(di->backing_path.dentry, list, size); } +static int incfs_test_super(struct super_block *s, void *p) +{ + return s->s_fs_info != NULL; +} + struct dentry *incfs_mount_fs(struct file_system_type *type, int flags, const char *dev_name, void *data) { @@ -1746,7 +1760,8 @@ struct dentry *incfs_mount_fs(struct file_system_type *type, int flags, struct dentry *incomplete_dir = NULL; struct super_block *src_fs_sb = NULL; struct inode *root_inode = NULL; - struct super_block *sb = sget(type, NULL, set_anon_super, flags, NULL); + struct super_block *sb = sget(type, incfs_test_super, set_anon_super, + flags, NULL); int error = 0; if (IS_ERR(sb)) @@ -1787,13 +1802,18 @@ struct dentry *incfs_mount_fs(struct file_system_type *type, int flags, src_fs_sb = backing_dir_path.dentry->d_sb; sb->s_maxbytes = src_fs_sb->s_maxbytes; - mi = incfs_alloc_mount_info(sb, &options, &backing_dir_path); + if (!sb->s_fs_info) { + mi = incfs_alloc_mount_info(sb, &options, &backing_dir_path); - if (IS_ERR_OR_NULL(mi)) { - error = PTR_ERR(mi); - pr_err("incfs: Error allocating mount info. %d\n", error); - mi = NULL; - goto err; + if (IS_ERR_OR_NULL(mi)) { + error = PTR_ERR(mi); + pr_err("incfs: Error allocating mount info. %d\n", error); + mi = NULL; + goto err; + } + sb->s_fs_info = mi; + } else { + mi = sb->s_fs_info; } index_dir = open_or_create_special_dir(backing_dir_path.dentry, @@ -1818,21 +1838,22 @@ struct dentry *incfs_mount_fs(struct file_system_type *type, int flags, } mi->mi_incomplete_dir = incomplete_dir; - sb->s_fs_info = mi; root_inode = fetch_regular_inode(sb, backing_dir_path.dentry); if (IS_ERR(root_inode)) { error = PTR_ERR(root_inode); goto err; } - sb->s_root = d_make_root(root_inode); if (!sb->s_root) { - error = -ENOMEM; - goto err; + sb->s_root = d_make_root(root_inode); + if (!sb->s_root) { + error = -ENOMEM; + goto err; + } + error = incfs_init_dentry(sb->s_root, &backing_dir_path); + if (error) + goto err; } - error = incfs_init_dentry(sb->s_root, &backing_dir_path); - if (error) - goto err; path_put(&backing_dir_path); sb->s_flags |= SB_ACTIVE; @@ -1854,6 +1875,9 @@ static int incfs_remount_fs(struct super_block *sb, int *flags, char *data) struct mount_info *mi = get_mount_info(sb); int err = 0; + if (!mi) + return err; + sync_filesystem(sb); err = parse_options(&options, (char *)data); if (err) @@ -1883,12 +1907,16 @@ void incfs_kill_sb(struct super_block *sb) pr_debug("incfs: unmount\n"); generic_shutdown_super(sb); incfs_free_mount_info(mi); + sb->s_fs_info = NULL; } static int show_options(struct seq_file *m, struct dentry *root) { struct mount_info *mi = get_mount_info(root->d_sb); + if (!mi) + return -EBADF; + seq_printf(m, ",read_timeout_ms=%u", mi->mi_options.read_timeout_ms); seq_printf(m, ",readahead=%u", mi->mi_options.readahead_pages); if (mi->mi_options.read_log_pages != 0) { diff --git a/fs/incfs/vfs.h b/fs/incfs/vfs.h index 79fdf243733d..8876e63a8b0f 100644 --- a/fs/incfs/vfs.h +++ b/fs/incfs/vfs.h @@ -19,7 +19,6 @@ static inline struct mount_info *get_mount_info(struct super_block *sb) { struct mount_info *result = sb->s_fs_info; - WARN_ON(!result); return result; } From 1bfc9c16ae45a1a18d20752ed7011d83a713ae2a Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Wed, 12 Jan 2022 18:42:35 -0800 Subject: [PATCH 27/52] ANDROID: selftests: fix incfs_test Fix incfs test build error: incfs_test.c:4441:19: error: argument 2 is null but the corresponding size argument 3 value is 1 [-Werror=nonnull] 4441 | TESTEQUAL(read(fd, NULL, 1), -1); | ^ Bug: 211066171 Signed-off-by: Tadeusz Struk Change-Id: I028d02aef9938a9abe6c529756b89d7cb07507f2 --- tools/testing/selftests/filesystems/incfs/incfs_test.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/filesystems/incfs/incfs_test.c b/tools/testing/selftests/filesystems/incfs/incfs_test.c index 4c30aec3f545..2d2bc933fefc 100644 --- a/tools/testing/selftests/filesystems/incfs/incfs_test.c +++ b/tools/testing/selftests/filesystems/incfs/incfs_test.c @@ -4409,6 +4409,7 @@ static int sysfs_test(const char *mount_dir) int fd = -1; int pid = -1; char buffer[32]; + char *null_buf = NULL; int status; struct incfs_per_uid_read_timeouts purt_set[] = { { @@ -4437,13 +4438,13 @@ static int sysfs_test(const char *mount_dir) TEST(fd = open(filename, O_RDONLY | O_CLOEXEC), fd != -1); TESTEQUAL(ioctl_test_last_error(cmd_fd, NULL, 0, 0), 0); TESTEQUAL(sysfs_test_value("reads_failed_timed_out", 0), 0); - TEST(read(fd, NULL, 1), -1); + TESTEQUAL(read(fd, null_buf, 1), -1); TESTEQUAL(ioctl_test_last_error(cmd_fd, &file.id, 0, -ETIME), 0); TESTEQUAL(sysfs_test_value("reads_failed_timed_out", 2), 0); TESTEQUAL(emit_test_file_data(mount_dir, &file), 0); TESTEQUAL(sysfs_test_value("reads_failed_hash_verification", 0), 0); - TESTEQUAL(read(fd, NULL, 1), -1); + TESTEQUAL(read(fd, null_buf, 1), -1); TESTEQUAL(sysfs_test_value("reads_failed_hash_verification", 1), 0); TESTSYSCALL(close(fd)); fd = -1; From d461f54be339c0bc08a39c2606f31655f495897b Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Thu, 13 Jan 2022 08:53:07 -0800 Subject: [PATCH 28/52] ANDROID: Incremental-fs: Doc: correct a sysfs path in incfs.rst Correct a path to incremental-fs sysfs entry in incfs.rst Bug: 211066171 Signed-off-by: Tadeusz Struk Change-Id: Id3a94888edd9022c517939b4667d9792fc04146a --- Documentation/filesystems/incfs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/filesystems/incfs.rst b/Documentation/filesystems/incfs.rst index 03ae39ec72dc..19db303b8327 100644 --- a/Documentation/filesystems/incfs.rst +++ b/Documentation/filesystems/incfs.rst @@ -7,7 +7,7 @@ incfs: A stacked incremental filesystem for Linux /sys/fs interface ================= -Please update Documentation/ABI/testing/sys-fs-incfs if you update this +Please update Documentation/ABI/testing/sysfs-fs-incfs if you update this section. incfs creates the following files in /sys/fs. From 032a6762957f8389b651864df6e5592649f0163c Mon Sep 17 00:00:00 2001 From: Jens Wiklander Date: Thu, 9 Dec 2021 15:59:37 +0100 Subject: [PATCH 29/52] UPSTREAM: tee: handle lookup of shm with reference count 0 commit dfd0743f1d9ea76931510ed150334d571fbab49d upstream. Since the tee subsystem does not keep a strong reference to its idle shared memory buffers, it races with other threads that try to destroy a shared memory through a close of its dma-buf fd or by unmapping the memory. In tee_shm_get_from_id() when a lookup in teedev->idr has been successful, it is possible that the tee_shm is in the dma-buf teardown path, but that path is blocked by the teedev mutex. Since we don't have an API to tell if the tee_shm is in the dma-buf teardown path or not we must find another way of detecting this condition. Fix this by doing the reference counting directly on the tee_shm using a new refcount_t refcount field. dma-buf is replaced by using anon_inode_getfd() instead, this separates the life-cycle of the underlying file from the tee_shm. tee_shm_put() is updated to hold the mutex when decreasing the refcount to 0 and then remove the tee_shm from teedev->idr before releasing the mutex. This means that the tee_shm can never be found unless it has a refcount larger than 0. Fixes: 967c9cca2cc5 ("tee: generic TEE subsystem") Cc: stable@vger.kernel.org Reviewed-by: Greg Kroah-Hartman Reviewed-by: Lars Persson Reviewed-by: Sumit Garg Reported-by: Patrik Lantz Signed-off-by: Jens Wiklander Signed-off-by: Greg Kroah-Hartman Signed-off-by: Lee Jones Change-Id: Ibd2809a225b167563c65faff4a44e56e23c2e97b --- drivers/tee/tee_shm.c | 171 ++++++++++++++++------------------------ include/linux/tee_drv.h | 4 +- 2 files changed, 68 insertions(+), 107 deletions(-) diff --git a/drivers/tee/tee_shm.c b/drivers/tee/tee_shm.c index 8a9384a64f3e..499fccba3d74 100644 --- a/drivers/tee/tee_shm.c +++ b/drivers/tee/tee_shm.c @@ -1,11 +1,11 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2016, Linaro Limited + * Copyright (c) 2015-2017, 2019-2021 Linaro Limited */ +#include #include -#include -#include #include +#include #include #include #include @@ -28,16 +28,8 @@ static void release_registered_pages(struct tee_shm *shm) } } -static void tee_shm_release(struct tee_shm *shm) +static void tee_shm_release(struct tee_device *teedev, struct tee_shm *shm) { - struct tee_device *teedev = shm->ctx->teedev; - - if (shm->flags & TEE_SHM_DMA_BUF) { - mutex_lock(&teedev->mutex); - idr_remove(&teedev->idr, shm->id); - mutex_unlock(&teedev->mutex); - } - if (shm->flags & TEE_SHM_POOL) { struct tee_shm_pool_mgr *poolm; @@ -64,45 +56,6 @@ static void tee_shm_release(struct tee_shm *shm) tee_device_put(teedev); } -static struct sg_table *tee_shm_op_map_dma_buf(struct dma_buf_attachment - *attach, enum dma_data_direction dir) -{ - return NULL; -} - -static void tee_shm_op_unmap_dma_buf(struct dma_buf_attachment *attach, - struct sg_table *table, - enum dma_data_direction dir) -{ -} - -static void tee_shm_op_release(struct dma_buf *dmabuf) -{ - struct tee_shm *shm = dmabuf->priv; - - tee_shm_release(shm); -} - -static int tee_shm_op_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -{ - struct tee_shm *shm = dmabuf->priv; - size_t size = vma->vm_end - vma->vm_start; - - /* Refuse sharing shared memory provided by application */ - if (shm->flags & TEE_SHM_USER_MAPPED) - return -EINVAL; - - return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT, - size, vma->vm_page_prot); -} - -static const struct dma_buf_ops tee_shm_dma_buf_ops = { - .map_dma_buf = tee_shm_op_map_dma_buf, - .unmap_dma_buf = tee_shm_op_unmap_dma_buf, - .release = tee_shm_op_release, - .mmap = tee_shm_op_mmap, -}; - struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) { struct tee_device *teedev = ctx->teedev; @@ -137,6 +90,7 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) goto err_dev_put; } + refcount_set(&shm->refcount, 1); shm->flags = flags | TEE_SHM_POOL; shm->ctx = ctx; if (flags & TEE_SHM_DMA_BUF) @@ -150,10 +104,7 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) goto err_kfree; } - if (flags & TEE_SHM_DMA_BUF) { - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - mutex_lock(&teedev->mutex); shm->id = idr_alloc(&teedev->idr, shm, 1, 0, GFP_KERNEL); mutex_unlock(&teedev->mutex); @@ -161,28 +112,11 @@ struct tee_shm *tee_shm_alloc(struct tee_context *ctx, size_t size, u32 flags) ret = ERR_PTR(shm->id); goto err_pool_free; } - - exp_info.ops = &tee_shm_dma_buf_ops; - exp_info.size = shm->size; - exp_info.flags = O_RDWR; - exp_info.priv = shm; - - shm->dmabuf = dma_buf_export(&exp_info); - if (IS_ERR(shm->dmabuf)) { - ret = ERR_CAST(shm->dmabuf); - goto err_rem; - } } teedev_ctx_get(ctx); return shm; -err_rem: - if (flags & TEE_SHM_DMA_BUF) { - mutex_lock(&teedev->mutex); - idr_remove(&teedev->idr, shm->id); - mutex_unlock(&teedev->mutex); - } err_pool_free: poolm->ops->free(poolm, shm); err_kfree: @@ -243,6 +177,7 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, goto err; } + refcount_set(&shm->refcount, 1); shm->flags = flags | TEE_SHM_REGISTER; shm->ctx = ctx; shm->id = -1; @@ -303,22 +238,6 @@ struct tee_shm *tee_shm_register(struct tee_context *ctx, unsigned long addr, goto err; } - if (flags & TEE_SHM_DMA_BUF) { - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - - exp_info.ops = &tee_shm_dma_buf_ops; - exp_info.size = shm->size; - exp_info.flags = O_RDWR; - exp_info.priv = shm; - - shm->dmabuf = dma_buf_export(&exp_info); - if (IS_ERR(shm->dmabuf)) { - ret = ERR_CAST(shm->dmabuf); - teedev->desc->ops->shm_unregister(ctx, shm); - goto err; - } - } - return shm; err: if (shm) { @@ -336,6 +255,35 @@ err: } EXPORT_SYMBOL_GPL(tee_shm_register); +static int tee_shm_fop_release(struct inode *inode, struct file *filp) +{ + tee_shm_put(filp->private_data); + return 0; +} + +static int tee_shm_fop_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct tee_shm *shm = filp->private_data; + size_t size = vma->vm_end - vma->vm_start; + + /* Refuse sharing shared memory provided by application */ + if (shm->flags & TEE_SHM_USER_MAPPED) + return -EINVAL; + + /* check for overflowing the buffer's size */ + if (vma->vm_pgoff + vma_pages(vma) > shm->size >> PAGE_SHIFT) + return -EINVAL; + + return remap_pfn_range(vma, vma->vm_start, shm->paddr >> PAGE_SHIFT, + size, vma->vm_page_prot); +} + +static const struct file_operations tee_shm_fops = { + .owner = THIS_MODULE, + .release = tee_shm_fop_release, + .mmap = tee_shm_fop_mmap, +}; + /** * tee_shm_get_fd() - Increase reference count and return file descriptor * @shm: Shared memory handle @@ -348,10 +296,11 @@ int tee_shm_get_fd(struct tee_shm *shm) if (!(shm->flags & TEE_SHM_DMA_BUF)) return -EINVAL; - get_dma_buf(shm->dmabuf); - fd = dma_buf_fd(shm->dmabuf, O_CLOEXEC); + /* matched by tee_shm_put() in tee_shm_op_release() */ + refcount_inc(&shm->refcount); + fd = anon_inode_getfd("tee_shm", &tee_shm_fops, shm, O_RDWR); if (fd < 0) - dma_buf_put(shm->dmabuf); + tee_shm_put(shm); return fd; } @@ -361,17 +310,7 @@ int tee_shm_get_fd(struct tee_shm *shm) */ void tee_shm_free(struct tee_shm *shm) { - /* - * dma_buf_put() decreases the dmabuf reference counter and will - * call tee_shm_release() when the last reference is gone. - * - * In the case of driver private memory we call tee_shm_release - * directly instead as it doesn't have a reference counter. - */ - if (shm->flags & TEE_SHM_DMA_BUF) - dma_buf_put(shm->dmabuf); - else - tee_shm_release(shm); + tee_shm_put(shm); } EXPORT_SYMBOL_GPL(tee_shm_free); @@ -478,10 +417,15 @@ struct tee_shm *tee_shm_get_from_id(struct tee_context *ctx, int id) teedev = ctx->teedev; mutex_lock(&teedev->mutex); shm = idr_find(&teedev->idr, id); + /* + * If the tee_shm was found in the IDR it must have a refcount + * larger than 0 due to the guarantee in tee_shm_put() below. So + * it's safe to use refcount_inc(). + */ if (!shm || shm->ctx != ctx) shm = ERR_PTR(-EINVAL); - else if (shm->flags & TEE_SHM_DMA_BUF) - get_dma_buf(shm->dmabuf); + else + refcount_inc(&shm->refcount); mutex_unlock(&teedev->mutex); return shm; } @@ -493,7 +437,24 @@ EXPORT_SYMBOL_GPL(tee_shm_get_from_id); */ void tee_shm_put(struct tee_shm *shm) { - if (shm->flags & TEE_SHM_DMA_BUF) - dma_buf_put(shm->dmabuf); + struct tee_device *teedev = shm->ctx->teedev; + bool do_release = false; + + mutex_lock(&teedev->mutex); + if (refcount_dec_and_test(&shm->refcount)) { + /* + * refcount has reached 0, we must now remove it from the + * IDR before releasing the mutex. This will guarantee that + * the refcount_inc() in tee_shm_get_from_id() never starts + * from 0. + */ + if (shm->flags & TEE_SHM_DMA_BUF) + idr_remove(&teedev->idr, shm->id); + do_release = true; + } + mutex_unlock(&teedev->mutex); + + if (do_release) + tee_shm_release(teedev, shm); } EXPORT_SYMBOL_GPL(tee_shm_put); diff --git a/include/linux/tee_drv.h b/include/linux/tee_drv.h index 459e9a76d7e6..0c6c1de6f3b7 100644 --- a/include/linux/tee_drv.h +++ b/include/linux/tee_drv.h @@ -195,7 +195,7 @@ int tee_session_calc_client_uuid(uuid_t *uuid, u32 connection_method, * @offset: offset of buffer in user space * @pages: locked pages from userspace * @num_pages: number of locked pages - * @dmabuf: dmabuf used to for exporting to user space + * @refcount: reference counter * @flags: defined by TEE_SHM_* in tee_drv.h * @id: unique id of a shared memory object on this device * @@ -210,7 +210,7 @@ struct tee_shm { unsigned int offset; struct page **pages; size_t num_pages; - struct dma_buf *dmabuf; + refcount_t refcount; u32 flags; int id; }; From 445019bbca5d86f05b6ec383a6c0f4de3af555fe Mon Sep 17 00:00:00 2001 From: Bui Quang Minh Date: Sun, 13 Jun 2021 21:34:39 +0700 Subject: [PATCH 30/52] UPSTREAM: bpf: Fix integer overflow in argument calculation for bpf_map_area_alloc commit 7dd5d437c258bbf4cc15b35229e5208b87b8b4e0 upstream. In 32-bit architecture, the result of sizeof() is a 32-bit integer so the expression becomes the multiplication between 2 32-bit integer which can potentially leads to integer overflow. As a result, bpf_map_area_alloc() allocates less memory than needed. Fix this by casting 1 operand to u64. Fixes: 0d2c4f964050 ("bpf: Eliminate rlimit-based memory accounting for sockmap and sockhash maps") Fixes: 99c51064fb06 ("devmap: Use bpf_map_area_alloc() for allocating hash buckets") Fixes: 546ac1ffb70d ("bpf: add devmap, a map for storing net device references") Signed-off-by: Bui Quang Minh Signed-off-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20210613143440.71975-1-minhquangbui99@gmail.com Signed-off-by: Connor O'Brien Signed-off-by: Greg Kroah-Hartman Signed-off-by: Lee Jones Change-Id: I9ce1991224a87eb39acf1da4923534e22380fc42 --- kernel/bpf/devmap.c | 4 ++-- net/core/sock_map.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c index b5be9659ab59..01149821ded9 100644 --- a/kernel/bpf/devmap.c +++ b/kernel/bpf/devmap.c @@ -92,7 +92,7 @@ static struct hlist_head *dev_map_create_hash(unsigned int entries, int i; struct hlist_head *hash; - hash = bpf_map_area_alloc(entries * sizeof(*hash), numa_node); + hash = bpf_map_area_alloc((u64) entries * sizeof(*hash), numa_node); if (hash != NULL) for (i = 0; i < entries; i++) INIT_HLIST_HEAD(&hash[i]); @@ -153,7 +153,7 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr) spin_lock_init(&dtab->index_lock); } else { - dtab->netdev_map = bpf_map_area_alloc(dtab->map.max_entries * + dtab->netdev_map = bpf_map_area_alloc((u64) dtab->map.max_entries * sizeof(struct bpf_dtab_netdev *), dtab->map.numa_node); if (!dtab->netdev_map) diff --git a/net/core/sock_map.c b/net/core/sock_map.c index ddc899e83313..4ea5bc65848f 100644 --- a/net/core/sock_map.c +++ b/net/core/sock_map.c @@ -52,7 +52,7 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr) if (err) goto free_stab; - stab->sks = bpf_map_area_alloc(stab->map.max_entries * + stab->sks = bpf_map_area_alloc((u64) stab->map.max_entries * sizeof(struct sock *), stab->map.numa_node); if (stab->sks) From 4b1862e4fc6967bf326107ac0d5695157f32c25d Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Mon, 3 Jan 2022 12:50:26 -0800 Subject: [PATCH 31/52] ANDROID: incremental-fs: fix GPF in pending_reads_dispatch_ioctl It is possible that fget returns NULL. This needs to be handled correctly in ioctl_permit_fill. Bug: 212821226 Signed-off-by: Tadeusz Struk Change-Id: Iec8be21982afeab6794b78ab1a542671c52acea2 --- fs/incfs/pseudo_files.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/incfs/pseudo_files.c b/fs/incfs/pseudo_files.c index 1a664f1478d5..1b9bf000f598 100644 --- a/fs/incfs/pseudo_files.c +++ b/fs/incfs/pseudo_files.c @@ -147,8 +147,12 @@ static long ioctl_permit_fill(struct file *f, void __user *arg) return -EFAULT; file = fget(permit_fill.file_descriptor); - if (IS_ERR(file)) + if (IS_ERR_OR_NULL(file)) { + if (!file) + return -ENOENT; + return PTR_ERR(file); + } if (file->f_op != &incfs_file_ops) { error = -EPERM; From b0d13db791b8774617b72c9242a7cf49f67720b2 Mon Sep 17 00:00:00 2001 From: Petr Mladek Date: Fri, 21 Jan 2022 18:36:28 +0530 Subject: [PATCH 32/52] FROMGIT: printk: ringbuffer: Improve prb_next_seq() performance prb_next_seq() always iterates from the first known sequence number. In the worst case, it might loop 8k times for 256kB buffer, 15k times for 512kB buffer, and 64k times for 2MB buffer. It was reported that polling and reading using syslog interface might occupy 50% of CPU. Speedup the search by storing @id of the last finalized descriptor. The loop is still needed because the @id is stored and read in the best effort way. An atomic variable is used to keep the @id consistent. But the stores and reads are not serialized against each other. The descriptor could get reused in the meantime. The related sequence number will be used only when it is still valid. An invalid value should be read _only_ when there is a flood of messages and the ringbuffer is rapidly reused. The performance is the least problem in this case. Bug: 216238044 Reported-by: Chunlei Wang Signed-off-by: Mukesh Ojha Reviewed-by: John Ogness Signed-off-by: Petr Mladek Link: https://lore.kernel.org/r/1642770388-17327-1-git-send-email-quic_mojha@quicinc.com Link: https://lore.kernel.org/lkml/YXlddJxLh77DKfIO@alley/T/#m43062e8b2a17f8dbc8c6ccdb8851fb0dbaabbb14 (cherry picked from commit f244b4dc53e520d4570b2610436aba0593ce6f55 https://git.kernel.org/pub/scm/linux/kernel/git/printk/linux.git printk-rework) Change-Id: I30a71e934422600f6b356da25ab705f71f3ad904 Signed-off-by: Mukesh Ojha --- kernel/printk/printk_ringbuffer.c | 52 ++++++++++++++++++++++++++++--- kernel/printk/printk_ringbuffer.h | 2 ++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/kernel/printk/printk_ringbuffer.c b/kernel/printk/printk_ringbuffer.c index 617dd6358965..b77c4154a1ee 100644 --- a/kernel/printk/printk_ringbuffer.c +++ b/kernel/printk/printk_ringbuffer.c @@ -474,8 +474,10 @@ static enum desc_state desc_read(struct prb_desc_ring *desc_ring, * state has been re-checked. A memcpy() for all of @desc * cannot be used because of the atomic_t @state_var field. */ - memcpy(&desc_out->text_blk_lpos, &desc->text_blk_lpos, - sizeof(desc_out->text_blk_lpos)); /* LMM(desc_read:C) */ + if (desc_out) { + memcpy(&desc_out->text_blk_lpos, &desc->text_blk_lpos, + sizeof(desc_out->text_blk_lpos)); /* LMM(desc_read:C) */ + } if (seq_out) *seq_out = info->seq; /* also part of desc_read:C */ if (caller_id_out) @@ -528,7 +530,8 @@ static enum desc_state desc_read(struct prb_desc_ring *desc_ring, state_val = atomic_long_read(state_var); /* LMM(desc_read:E) */ d_state = get_desc_state(id, state_val); out: - atomic_long_set(&desc_out->state_var, state_val); + if (desc_out) + atomic_long_set(&desc_out->state_var, state_val); return d_state; } @@ -1450,6 +1453,9 @@ static void desc_make_final(struct prb_desc_ring *desc_ring, unsigned long id) atomic_long_cmpxchg_relaxed(&d->state_var, prev_state_val, DESC_SV(id, desc_finalized)); /* LMM(desc_make_final:A) */ + + /* Best effort to remember the last finalized @id. */ + atomic_long_set(&desc_ring->last_finalized_id, id); } /** @@ -1659,7 +1665,12 @@ void prb_commit(struct prb_reserved_entry *e) */ void prb_final_commit(struct prb_reserved_entry *e) { + struct prb_desc_ring *desc_ring = &e->rb->desc_ring; + _prb_commit(e, desc_finalized); + + /* Best effort to remember the last finalized @id. */ + atomic_long_set(&desc_ring->last_finalized_id, e->id); } /* @@ -2007,9 +2018,39 @@ u64 prb_first_valid_seq(struct printk_ringbuffer *rb) */ u64 prb_next_seq(struct printk_ringbuffer *rb) { - u64 seq = 0; + struct prb_desc_ring *desc_ring = &rb->desc_ring; + enum desc_state d_state; + unsigned long id; + u64 seq; - /* Search forward from the oldest descriptor. */ + /* Check if the cached @id still points to a valid @seq. */ + id = atomic_long_read(&desc_ring->last_finalized_id); + d_state = desc_read(desc_ring, id, NULL, &seq, NULL); + + if (d_state == desc_finalized || d_state == desc_reusable) { + /* + * Begin searching after the last finalized record. + * + * On 0, the search must begin at 0 because of hack#2 + * of the bootstrapping phase it is not known if a + * record at index 0 exists. + */ + if (seq != 0) + seq++; + } else { + /* + * The information about the last finalized sequence number + * has gone. It should happen only when there is a flood of + * new messages and the ringbuffer is rapidly recycled. + * Give up and start from the beginning. + */ + seq = 0; + } + + /* + * The information about the last finalized @seq might be inaccurate. + * Search forward to find the current one. + */ while (_prb_read_valid(rb, &seq, NULL, NULL)) seq++; @@ -2046,6 +2087,7 @@ void prb_init(struct printk_ringbuffer *rb, rb->desc_ring.infos = infos; atomic_long_set(&rb->desc_ring.head_id, DESC0_ID(descbits)); atomic_long_set(&rb->desc_ring.tail_id, DESC0_ID(descbits)); + atomic_long_set(&rb->desc_ring.last_finalized_id, DESC0_ID(descbits)); rb->text_data_ring.size_bits = textbits; rb->text_data_ring.data = text_buf; diff --git a/kernel/printk/printk_ringbuffer.h b/kernel/printk/printk_ringbuffer.h index 5dc9d022db07..e68a8cb277b1 100644 --- a/kernel/printk/printk_ringbuffer.h +++ b/kernel/printk/printk_ringbuffer.h @@ -75,6 +75,7 @@ struct prb_desc_ring { struct printk_info *infos; atomic_long_t head_id; atomic_long_t tail_id; + atomic_long_t last_finalized_id; }; /* @@ -258,6 +259,7 @@ static struct printk_ringbuffer name = { \ .infos = &_##name##_infos[0], \ .head_id = ATOMIC_INIT(DESC0_ID(descbits)), \ .tail_id = ATOMIC_INIT(DESC0_ID(descbits)), \ + .last_finalized_id = ATOMIC_INIT(DESC0_ID(descbits)), \ }, \ .text_data_ring = { \ .size_bits = (avgtextbits) + (descbits), \ From 2861bbc5b5a44bd39ae7b3a7840beaa61c5061a2 Mon Sep 17 00:00:00 2001 From: Anshuman Khandual Date: Tue, 25 Jan 2022 15:40:39 +0000 Subject: [PATCH 33/52] FROMLIST: arm64: Add Cortex-A510 CPU part definition Add the CPU Partnumbers for the new Arm designs. Cc: Catalin Marinas Cc: Will Deacon Cc: Suzuki Poulose Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Reviewed-by: Suzuki K Poulose Acked-by: Catalin Marinas Signed-off-by: Anshuman Khandual Signed-off-by: James Morse Bug: 208481398 Link: https://lore.kernel.org/all/20220125154040.549272-2-james.morse@arm.com/ Change-Id: I5ac1ef6a69ae4ad87792e8b128cc79cfc02fc839 Signed-off-by: Elliot Berman --- arch/arm64/include/asm/cputype.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm64/include/asm/cputype.h b/arch/arm64/include/asm/cputype.h index 6f4c4b5a908d..f9adcf962699 100644 --- a/arch/arm64/include/asm/cputype.h +++ b/arch/arm64/include/asm/cputype.h @@ -72,6 +72,7 @@ #define ARM_CPU_PART_CORTEX_A76 0xD0B #define ARM_CPU_PART_NEOVERSE_N1 0xD0C #define ARM_CPU_PART_CORTEX_A77 0xD0D +#define ARM_CPU_PART_CORTEX_A510 0xD46 #define ARM_CPU_PART_CORTEX_A710 0xD47 #define ARM_CPU_PART_NEOVERSE_N2 0xD49 @@ -111,6 +112,7 @@ #define MIDR_CORTEX_A76 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A76) #define MIDR_NEOVERSE_N1 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N1) #define MIDR_CORTEX_A77 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A77) +#define MIDR_CORTEX_A510 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A510) #define MIDR_CORTEX_A710 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A710) #define MIDR_NEOVERSE_N2 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_NEOVERSE_N2) #define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX) From 2aba795b317c2a5b25681647672d2189ab22a94e Mon Sep 17 00:00:00 2001 From: James Morse Date: Tue, 25 Jan 2022 15:40:40 +0000 Subject: [PATCH 34/52] FROMLIST: arm64: cpufeature: List early Cortex-A510 parts as having broken dbm Versions of Cortex-A510 before r0p3 are affected by a hardware erratum where the hardware update of the dirty bit is not correctly ordered. Add these cpus to the cpu_has_broken_dbm list. Cc: stable@vger.kernel.org Signed-off-by: James Morse Bug: 208481398 Link: https://lore.kernel.org/all/20220125154040.549272-3-james.morse@arm.com/ Change-Id: I6ad53c88c034f49f43e61aa2ff3547990583c654 Signed-off-by: Elliot Berman --- Documentation/arm64/silicon-errata.rst | 2 ++ arch/arm64/Kconfig | 10 ++++++++++ arch/arm64/kernel/cpufeature.c | 3 +++ 3 files changed, 15 insertions(+) diff --git a/Documentation/arm64/silicon-errata.rst b/Documentation/arm64/silicon-errata.rst index 5a30b1857420..805c073fd5e6 100644 --- a/Documentation/arm64/silicon-errata.rst +++ b/Documentation/arm64/silicon-errata.rst @@ -92,6 +92,8 @@ stable kernels. +----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A77 | #1508412 | ARM64_ERRATUM_1508412 | +----------------+-----------------+-----------------+-----------------------------+ +| ARM | Cortex-A510 | #2051678 | ARM64_ERRATUM_2051678 | ++----------------+-----------------+-----------------+-----------------------------+ | ARM | Cortex-A710 | #2054223 | ARM64_ERRATUM_2054223 | +----------------+-----------------+-----------------+-----------------------------+ | ARM | Neoverse-N1 | #1188873,1418040| ARM64_ERRATUM_1418040 | diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 642a4482dd4e..c18cd7d63e2b 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -669,6 +669,16 @@ config ARM64_ERRATUM_1508412 If unsure, say Y. +config ARM64_ERRATUM_2051678 + bool "Cortex-A510: 2051678: disable Hardware Update of the page table's dirty bit" + help + This options adds the workaround for ARM Cortex-A510 erratum ARM64_ERRATUM_2051678. + Affected Coretex-A510 might not respect the ordering rules for + hardware update of the page table's dirty bit. The workaround + is to not enable the feature on affected CPUs. + + If unsure, say Y. + config ARM64_WORKAROUND_TSB_FLUSH_FAILURE bool diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index d9e5c16f2037..290bf2cba7ef 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1599,6 +1599,9 @@ static bool cpu_has_broken_dbm(void) MIDR_ALL_VERSIONS(MIDR_CORTEX_A55), /* Kryo4xx Silver (rdpe => r1p0) */ MIDR_REV(MIDR_QCOM_KRYO_4XX_SILVER, 0xd, 0xe), +#endif +#ifdef CONFIG_ARM64_ERRATUM_2051678 + MIDR_REV_RANGE(MIDR_CORTEX_A510, 0, 0, 2), #endif {}, }; From 6a9ff8fa2669adb8dd188dcf8a260ad2bdf31f59 Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Mon, 17 Jan 2022 12:58:20 +0530 Subject: [PATCH 35/52] ANDROID: iommu: Add restricted vendor hook Add restricted vendor hook for arch_setup_dma_ops to allow vendor enhancements. This needs to be restricted vendor hook as it is doing GFP_KERNEL allocation which are non-atomic in nature. Bug: 214353193 Change-Id: I45f8f0404a247b67fd07a6831ff813bbc50fbca2 Signed-off-by: Charan Teja Reddy --- arch/arm64/mm/dma-mapping.c | 1 + drivers/android/vendor_hooks.c | 1 + include/trace/hooks/iommu.h | 4 ++++ 3 files changed, 6 insertions(+) diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index c834a6445842..e75e5e75b192 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -53,6 +53,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, if (iommu) { iommu_setup_dma_ops(dev, dma_base, size); trace_android_vh_iommu_setup_dma_ops(dev, dma_base, size); + trace_android_rvh_iommu_setup_dma_ops(dev, dma_base, size); } #ifdef CONFIG_XEN diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index c88ff0ddfcf3..ef6b8e851608 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -192,6 +192,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_die_kernel_fault); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sea); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_mem_abort); EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_do_sp_pc_abort); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_rvh_iommu_setup_dma_ops); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_iommu_setup_dma_ops); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_iommu_alloc_iova); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_iommu_iovad_alloc_iova); diff --git a/include/trace/hooks/iommu.h b/include/trace/hooks/iommu.h index dd54a50b3aa4..e818b90e482c 100644 --- a/include/trace/hooks/iommu.h +++ b/include/trace/hooks/iommu.h @@ -12,6 +12,10 @@ #include #include +DECLARE_RESTRICTED_HOOK(android_rvh_iommu_setup_dma_ops, + TP_PROTO(struct device *dev, u64 dma_base, u64 size), + TP_ARGS(dev, dma_base, size), 1); + DECLARE_HOOK(android_vh_iommu_setup_dma_ops, TP_PROTO(struct device *dev, u64 dma_base, u64 size), TP_ARGS(dev, dma_base, size)); From 2f61ec09b01cde82b6567a39c04701a5e106d61f Mon Sep 17 00:00:00 2001 From: Charan Teja Reddy Date: Mon, 17 Jan 2022 13:50:02 +0530 Subject: [PATCH 36/52] ANDROID: abi_gki_aarch64_qcom: Add iommu_setup_dma_ops restricted vh Whitelist the restricted vendor hook, iommu_setup_dma_ops, added to enhance the vendor operations. Leaf changes summary: 2 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 1 Added function Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 1 Added variable 1 Added function: [A] 'function int __traceiter_android_rvh_iommu_setup_dma_ops(void*, device*, u64, u64)' 1 Added variable: [A] 'tracepoint __tracepoint_android_rvh_iommu_setup_dma_ops' Bug: 214353193 Change-Id: Ie2378185e7439e41b8fa9ec494386060643514eb Signed-off-by: Charan Teja Reddy --- android/abi_gki_aarch64.xml | 72 ++++++++++++++++++++---------------- android/abi_gki_aarch64_qcom | 2 + 2 files changed, 43 insertions(+), 31 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 33bc082a4aba..d32e0a398529 100755 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -311,6 +311,7 @@ + @@ -5888,6 +5889,7 @@ + @@ -115312,6 +115314,13 @@ + + + + + + + @@ -116223,39 +116232,39 @@ - - - - - + + + + + - - - - - - - - - - - - - - - + - - - - - - + + + + + + + + + + + + + + + + + + + + @@ -117303,6 +117312,7 @@ + @@ -117450,11 +117460,11 @@ - - - - - + + + + + diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index 01c5fe8eea68..c27a4542d4a2 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -2512,6 +2512,7 @@ __traceiter_android_rvh_force_compatible_post __traceiter_android_rvh_force_compatible_pre __traceiter_android_rvh_gic_v3_set_affinity + __traceiter_android_rvh_iommu_setup_dma_ops __traceiter_android_rvh_irqs_disable __traceiter_android_rvh_irqs_enable __traceiter_android_rvh_migrate_queued_task @@ -2625,6 +2626,7 @@ __tracepoint_android_rvh_force_compatible_post __tracepoint_android_rvh_force_compatible_pre __tracepoint_android_rvh_gic_v3_set_affinity + __tracepoint_android_rvh_iommu_setup_dma_ops __tracepoint_android_rvh_irqs_disable __tracepoint_android_rvh_irqs_enable __tracepoint_android_rvh_migrate_queued_task From 6aa9e78d6e9878b8053c93a829ffd24d5d9ccb07 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Tue, 18 Jan 2022 13:54:19 -0800 Subject: [PATCH 37/52] FROMGIT: rcu: Allow expedited RCU grace periods on incoming CPUs Although it is usually safe to invoke synchronize_rcu_expedited() from a preemption-enabled CPU-hotplug notifier, if it is invoked from a notifier between CPUHP_AP_RCUTREE_ONLINE and CPUHP_AP_ACTIVE, its attempts to invoke a workqueue handler will hang due to RCU waiting on a CPU that the scheduler is not paying attention to. This commit therefore expands use of the existing workqueue-independent synchronize_rcu_expedited() from early boot to also include CPUs that are being hotplugged. Bug: 216238044 Link: https://lore.kernel.org/lkml/7359f994-8aaf-3cea-f5cf-c0d3929689d6@quicinc.com/ Reported-by: Mukesh Ojha Cc: Tejun Heo Signed-off-by: Paul E. McKenney (cherry picked from commit 710f460c395af6b81df1c81043308aaa60d5e25c https://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu.git rcu/next) Change-Id: I3f81dee6deaf6a4504aec31e058785dc8cee6a3f Signed-off-by: Mukesh Ojha --- kernel/rcu/tree_exp.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h index 9fb0f0916374..cc5f51fa2b28 100644 --- a/kernel/rcu/tree_exp.h +++ b/kernel/rcu/tree_exp.h @@ -812,7 +812,7 @@ static int rcu_print_task_exp_stall(struct rcu_node *rnp) */ void synchronize_rcu_expedited(void) { - bool boottime = (rcu_scheduler_active == RCU_SCHEDULER_INIT); + bool no_wq; struct rcu_exp_work rew; struct rcu_node *rnp; unsigned long s; @@ -837,9 +837,15 @@ void synchronize_rcu_expedited(void) if (exp_funnel_lock(s)) return; /* Someone else did our work for us. */ + /* Don't use workqueue during boot or from an incoming CPU. */ + preempt_disable(); + no_wq = rcu_scheduler_active == RCU_SCHEDULER_INIT || + !cpumask_test_cpu(smp_processor_id(), cpu_active_mask); + preempt_enable(); + /* Ensure that load happens before action based on it. */ - if (unlikely(boottime)) { - /* Direct call during scheduler init and early_initcalls(). */ + if (unlikely(no_wq)) { + /* Direct call for scheduler init, early_initcall()s, and incoming CPUs. */ rcu_exp_sel_wait_wake(s); } else { /* Marshall arguments & schedule the expedited grace period. */ @@ -857,7 +863,7 @@ void synchronize_rcu_expedited(void) /* Let the next expedited grace period start. */ mutex_unlock(&rcu_state.exp_mutex); - if (likely(!boottime)) + if (likely(!no_wq)) destroy_work_on_stack(&rew.rew_work); } EXPORT_SYMBOL_GPL(synchronize_rcu_expedited); From 5d79e49205a6cf48e3ddc664043abf6990410d50 Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Mon, 20 Dec 2021 11:01:50 -0800 Subject: [PATCH 38/52] UPSTREAM: binder: fix async_free_space accounting for empty parcels commit cfd0d84ba28c18b531648c9d4a35ecca89ad9901 upstream. In 4.13, commit 74310e06be4d ("android: binder: Move buffer out of area shared with user space") fixed a kernel structure visibility issue. As part of that patch, sizeof(void *) was used as the buffer size for 0-length data payloads so the driver could detect abusive clients sending 0-length asynchronous transactions to a server by enforcing limits on async_free_size. Unfortunately, on the "free" side, the accounting of async_free_space did not add the sizeof(void *) back. The result was that up to 8-bytes of async_free_space were leaked on every async transaction of 8-bytes or less. These small transactions are uncommon, so this accounting issue has gone undetected for several years. The fix is to use "buffer_size" (the allocated buffer size) instead of "size" (the logical buffer size) when updating the async_free_space during the free operation. These are the same except for this corner case of asynchronous transactions with payloads < 8 bytes. Fixes: 74310e06be4d ("android: binder: Move buffer out of area shared with user space") Signed-off-by: Todd Kjos Cc: stable@vger.kernel.org # 4.14+ Link: https://lore.kernel.org/r/20211220190150.2107077-1-tkjos@google.com Signed-off-by: Greg Kroah-Hartman Change-Id: I25b00d31a7a7009888ec6e92e4fc43ee1b14e401 --- drivers/android/binder_alloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 34d8fe2f17b8..d30267e08536 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -673,7 +673,7 @@ static void binder_free_buf_locked(struct binder_alloc *alloc, BUG_ON(buffer->user_data > alloc->buffer + alloc->buffer_size); if (buffer->async_transaction) { - alloc->free_async_space += size + sizeof(struct binder_buffer); + alloc->free_async_space += buffer_size + sizeof(struct binder_buffer); binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC_ASYNC, "%d: binder_free_buf size %zd async free %zd\n", From b2fcb7b63b30c6066b596ae938e59633e4665d4e Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 1 Feb 2022 12:35:03 -0800 Subject: [PATCH 39/52] ANDROID: abi: qcom: Add dma_{alloc,free}_noncoherent Leaf changes summary: 2 artifacts changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 2 Added functions Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 2 Added functions: [A] 'function void* dma_alloc_noncoherent(device*, size_t, dma_addr_t*, dma_data_direction, gfp_t)' [A] 'function void dma_free_noncoherent(device*, size_t, void*, dma_addr_t, dma_data_direction)' Bug: 217335534 Fixes: 79b64fa78085 ("UPSTREAM: coresight: tmc-etr: Speed up for bounce buffer in flat mode") Signed-off-by: Elliot Berman Change-Id: I442a250c1c0501fa3c5e0bd6dcfd210766c2b293 --- android/abi_gki_aarch64.xml | 744 ++++++++++++++--------------------- android/abi_gki_aarch64_qcom | 2 + 2 files changed, 294 insertions(+), 452 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index d32e0a398529..63234ad6cb8d 100755 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -1665,6 +1665,7 @@ + @@ -1706,6 +1707,7 @@ + @@ -12414,7 +12416,6 @@ - @@ -14628,7 +14629,6 @@ - @@ -21484,11 +21484,6 @@ - - - - - @@ -23448,17 +23443,6 @@ - - - - - - - - - - - @@ -24884,7 +24868,6 @@ - @@ -32768,32 +32751,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -35187,9 +35145,6 @@ - - - @@ -43732,11 +43687,7 @@ - - - - - + @@ -45180,9 +45131,6 @@ - - - @@ -47431,32 +47379,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -48949,7 +48871,6 @@ - @@ -52415,11 +52336,6 @@ - - - - - @@ -64207,14 +64123,6 @@ - - - - - - - - @@ -66559,11 +66467,6 @@ - - - - - @@ -70577,7 +70480,6 @@ - @@ -71241,11 +71143,7 @@ - - - - - + @@ -75573,9 +75471,9 @@ - + - + @@ -75933,11 +75831,6 @@ - - - - - @@ -79808,7 +79701,6 @@ - @@ -80375,7 +80267,6 @@ - @@ -82216,12 +82107,6 @@ - - - - - - @@ -84028,7 +83913,6 @@ - @@ -86557,53 +86441,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -88088,7 +87925,6 @@ - @@ -89292,7 +89128,6 @@ - @@ -93185,17 +93020,6 @@ - - - - - - - - - - - @@ -113515,11 +113339,11 @@ - - - - - + + + + + @@ -113805,49 +113629,49 @@ - - - - + + + + - - - + + + - - - - - - - + + + + + + + - - - - - - - + + + + + + + - - - - + + + + - - - - + + + + @@ -114123,9 +113947,9 @@ - - - + + + @@ -114133,15 +113957,15 @@ - - - + + + - - - - + + + + @@ -114606,7 +114430,7 @@ - + @@ -115279,10 +115103,10 @@ - - - - + + + + @@ -115295,23 +115119,23 @@ - - - - - - + - - - - - - - + + + + + + + + + + + + @@ -115524,9 +115348,9 @@ - - - + + + @@ -116294,11 +116118,11 @@ - - - - - + + + + + @@ -116330,31 +116154,31 @@ - - - + + + - - - - + + + + - - - - + + + + - - - + + + - - - + + + @@ -116362,20 +116186,20 @@ - - - - - - - - + + + + + + + + - - - - + + + + @@ -116508,16 +116332,16 @@ - - - - + + + + - - - - + + + + @@ -116623,11 +116447,11 @@ - - - - - + + + + + @@ -116655,10 +116479,10 @@ - - - - + + + + @@ -116724,12 +116548,12 @@ - - - - - - + + + + + + @@ -117274,8 +117098,8 @@ - - + + @@ -117294,7 +117118,7 @@ - + @@ -117306,12 +117130,12 @@ - + - - - + + + @@ -117345,7 +117169,7 @@ - + @@ -117471,19 +117295,19 @@ - + - - - - - + + + + + - - + + @@ -117492,7 +117316,7 @@ - + @@ -117515,8 +117339,8 @@ - - + + @@ -117536,19 +117360,19 @@ - + - + - + @@ -117556,7 +117380,7 @@ - + @@ -117581,7 +117405,7 @@ - + @@ -118059,8 +117883,8 @@ - - + + @@ -118117,9 +117941,9 @@ - - - + + + @@ -118236,9 +118060,9 @@ - - - + + + @@ -120390,10 +120214,10 @@ - - - - + + + + @@ -120687,9 +120511,9 @@ - - - + + + @@ -123263,6 +123087,14 @@ + + + + + + + + @@ -123475,6 +123307,14 @@ + + + + + + + + @@ -126997,14 +126837,14 @@ - - - + + + - - - + + + @@ -127684,8 +127524,8 @@ - - + + @@ -127702,7 +127542,7 @@ - + @@ -130211,8 +130051,8 @@ - - + + @@ -130402,10 +130242,10 @@ - - - - + + + + @@ -130423,8 +130263,8 @@ - - + + @@ -130868,9 +130708,9 @@ - - - + + + @@ -133497,8 +133337,8 @@ - - + + @@ -135277,13 +135117,13 @@ - - - + + + - - + + @@ -136274,8 +136114,8 @@ - - + + @@ -136292,8 +136132,8 @@ - - + + @@ -136400,8 +136240,8 @@ - - + + @@ -138069,11 +137909,11 @@ - + - - + + @@ -138183,16 +138023,16 @@ - - - - - - + + + + + + - - + + @@ -138298,10 +138138,10 @@ - - - - + + + + @@ -138356,9 +138196,9 @@ - - - + + + @@ -139554,11 +139394,11 @@ - - - - - + + + + + @@ -139569,65 +139409,65 @@ - - + + - - - - - + + + + + - - + + - - - + + + - - - - - + + + + + - - - + + + - - - - + + + + - - - - - - + + + + + + - - - + + + - - - + + + - - - + + + @@ -139644,20 +139484,20 @@ - - - - - - + + + + + + - - + + @@ -140844,11 +140684,11 @@ - - - - - + + + + + diff --git a/android/abi_gki_aarch64_qcom b/android/abi_gki_aarch64_qcom index c27a4542d4a2..e26f08dfe1c4 100644 --- a/android/abi_gki_aarch64_qcom +++ b/android/abi_gki_aarch64_qcom @@ -549,6 +549,7 @@ divider_ro_round_rate_parent divider_round_rate_parent dma_alloc_attrs + dma_alloc_noncoherent dma_async_device_register dma_async_device_unregister dma_async_tx_descriptor_init @@ -584,6 +585,7 @@ dma_fence_signal_timestamp_locked dma_fence_wait_timeout dma_free_attrs + dma_free_noncoherent dma_get_sgtable_attrs dma_get_slave_channel dma_heap_add From d449d91bc954dc127b836b3994fa47103f7650a1 Mon Sep 17 00:00:00 2001 From: Jing-Ting Wu Date: Thu, 27 Jan 2022 19:31:01 +0800 Subject: [PATCH 40/52] ANDROID: update new gki symbol Leaf changes summary: 1 artifact changed Changed leaf types summary: 0 leaf type changed Removed/Changed/Added functions summary: 0 Removed, 0 Changed, 1 Added function Removed/Changed/Added variables summary: 0 Removed, 0 Changed, 0 Added variable 1 Added function: [A] 'function void static_key_enable_cpuslocked(static_key*)' Bug: 216591390 Signed-off-by: Jing-Ting Wu Change-Id: I4fbb95490fd6226e5b6aa89b8808d9422ab4920e --- android/abi_gki_aarch64.xml | 5 + android/abi_gki_aarch64_mtk | 344 +++++++++++++++++++++++------------- 2 files changed, 226 insertions(+), 123 deletions(-) diff --git a/android/abi_gki_aarch64.xml b/android/abi_gki_aarch64.xml index 63234ad6cb8d..395e702a3f03 100755 --- a/android/abi_gki_aarch64.xml +++ b/android/abi_gki_aarch64.xml @@ -4907,6 +4907,7 @@ + @@ -139799,6 +139800,10 @@ + + + + diff --git a/android/abi_gki_aarch64_mtk b/android/abi_gki_aarch64_mtk index f49b88bc41c0..137ee9d40680 100644 --- a/android/abi_gki_aarch64_mtk +++ b/android/abi_gki_aarch64_mtk @@ -22,12 +22,14 @@ __alloc_percpu_gfp __alloc_skb alloc_workqueue + all_vm_events android_debug_symbol android_rvh_probe_register anon_inode_getfd anon_inode_getfile arc4_crypt arc4_setkey + __arch_clear_user __arch_copy_from_user __arch_copy_to_user arch_timer_read_counter @@ -51,10 +53,12 @@ bio_reset __bitmap_andnot __bitmap_clear + __bitmap_equal bitmap_find_free_region bitmap_find_next_zero_area_off bitmap_free bitmap_from_arr32 + __bitmap_or bitmap_print_to_pagebuf bitmap_release_region __bitmap_set @@ -96,6 +100,7 @@ bus_register bus_set_iommu bus_unregister + cache_line_size call_rcu cancel_delayed_work cancel_delayed_work_sync @@ -107,6 +112,8 @@ cdev_device_del cdev_init __cfi_slowpath + cgroup_taskset_first + cgroup_taskset_next __check_object_size check_preempt_curr __class_create @@ -115,6 +122,7 @@ class_for_each_device __class_register class_unregister + clear_page __ClearPageMovable clk_bulk_disable clk_bulk_enable @@ -172,7 +180,6 @@ config_group_init_type_name console_drivers console_suspend_enabled - console_unlock __const_udelay consume_skb contig_page_data @@ -203,6 +210,8 @@ cpufreq_this_cpu_can_update cpufreq_unregister_driver cpufreq_unregister_governor + cpufreq_update_limits + cpufreq_update_util_data cpu_hotplug_disable cpu_hotplug_enable __cpuhp_remove_state @@ -223,6 +232,8 @@ cpumask_next_and cpu_number __cpu_online_mask + cpu_pm_register_notifier + cpu_pm_unregister_notifier __cpu_possible_mask __cpu_present_mask cpu_scale @@ -289,10 +300,10 @@ del_gendisk del_timer del_timer_sync + desc_to_gpio destroy_workqueue dev_alloc_name dev_base_lock - dev_change_flags dev_change_net_namespace dev_close dev_driver_string @@ -300,21 +311,26 @@ _dev_err dev_err_probe dev_fetch_sw_netstats + devfreq_add_device devfreq_add_governor + devfreq_cooling_unregister devfreq_get_devfreq_by_phandle devfreq_monitor_resume devfreq_monitor_start devfreq_monitor_stop devfreq_monitor_suspend devfreq_recommended_opp + devfreq_register_opp_notifier devfreq_remove_device devfreq_remove_governor devfreq_resume_device devfreq_suspend_device + devfreq_unregister_opp_notifier devfreq_update_interval dev_fwnode __dev_get_by_index dev_get_by_index + dev_get_by_name dev_get_regmap dev_get_stats device_add @@ -341,6 +357,7 @@ device_remove_file device_rename device_set_of_node_from_dev + device_set_wakeup_capable device_show_bool device_store_bool device_unregister @@ -380,6 +397,7 @@ devm_ioremap devm_ioremap_resource devm_ioremap_wc + devm_iounmap devm_kasprintf devm_kfree devm_kmalloc @@ -404,6 +422,8 @@ devm_platform_ioremap_resource_byname devm_power_supply_get_by_phandle devm_power_supply_register + devm_rc_allocate_device + devm_rc_register_device devm_regmap_add_irq_chip devm_regmap_field_alloc __devm_regmap_init @@ -424,6 +444,7 @@ devm_snd_soc_register_component devm_spi_register_controller devm_thermal_zone_of_sensor_register + devm_usb_get_phy devm_watchdog_register_device _dev_notice dev_pm_domain_attach_by_id @@ -434,6 +455,7 @@ dev_pm_opp_add dev_pm_opp_find_freq_ceil dev_pm_opp_find_freq_ceil_by_volt + dev_pm_opp_find_freq_exact dev_pm_opp_find_freq_floor dev_pm_opp_get_freq dev_pm_opp_get_level @@ -445,7 +467,9 @@ dev_pm_opp_of_remove_table dev_pm_opp_put dev_pm_opp_put_opp_table + dev_pm_opp_put_regulators dev_pm_opp_remove_all_dynamic + dev_pm_opp_set_regulators dev_pm_qos_update_request dev_printk dev_queue_xmit @@ -473,6 +497,7 @@ dma_buf_fd dma_buf_get dma_buf_map_attachment + dma_buf_mmap dmabuf_page_pool_alloc dmabuf_page_pool_create dmabuf_page_pool_destroy @@ -482,11 +507,15 @@ dma_buf_vmap dma_buf_vunmap dma_fence_add_callback + dma_fence_array_ops dma_fence_context_alloc dma_fence_default_wait + dma_fence_enable_sw_signaling dma_fence_free + dma_fence_get_status dma_fence_init dma_fence_release + dma_fence_remove_callback dma_fence_signal dma_fence_signal_locked dma_fence_signal_timestamp_locked @@ -496,6 +525,7 @@ dma_heap_add dma_heap_buffer_alloc dma_heap_bufferfd_alloc + dma_heap_buffer_free dma_heap_find dma_heap_get_dev dma_heap_get_drvdata @@ -518,14 +548,17 @@ dma_sync_sg_for_cpu dma_sync_sg_for_device dma_sync_single_for_cpu + dma_sync_single_for_device dma_unmap_page_attrs dma_unmap_resource dma_unmap_sg_attrs do_exit do_wait_intr_irq down + downgrade_write down_interruptible down_read + down_read_trylock down_timeout down_trylock down_write @@ -587,6 +620,7 @@ drm_dev_put drm_dev_register drm_dev_unregister + drm_display_mode_to_videomode drm_dp_aux_init drm_dp_aux_register drm_dp_channel_eq_ok @@ -621,6 +655,7 @@ drm_gem_prime_import drm_gem_vm_close drm_get_edid + drm_get_format_name drm_helper_hpd_irq_event drm_helper_mode_fill_fb_struct drm_helper_probe_single_connector_modes @@ -636,6 +671,7 @@ drm_mode_copy drm_mode_crtc_set_gamma_size drm_mode_duplicate + drm_mode_equal drm_mode_object_find drm_mode_object_put drm_mode_probed_add @@ -759,6 +795,7 @@ gen_pool_best_fit gen_pool_create gen_pool_destroy + gen_pool_dma_alloc_align gen_pool_free_owner gen_pool_has_addr gen_pool_set_algo @@ -784,6 +821,8 @@ get_task_exe_file get_task_mm get_unused_fd_flags + get_user_pages + get_user_pages_fast get_user_pages_remote get_vaddr_frames get_zeroed_page @@ -801,9 +840,13 @@ gpiod_direction_input gpiod_direction_output gpiod_direction_output_raw + gpiod_get_optional gpiod_get_raw_value + gpiod_get_value gpiod_get_value_cansleep gpiod_set_debounce + gpiod_set_raw_value + gpiod_set_raw_value_cansleep gpiod_set_value gpiod_set_value_cansleep gpiod_to_irq @@ -814,9 +857,9 @@ handle_level_irq handle_nested_irq handle_simple_irq - hashlen_string have_governor_per_policy hex_asc + hex_to_bin hrtimer_active hrtimer_cancel hrtimer_forward @@ -859,7 +902,9 @@ idr_find idr_for_each idr_get_next + idr_preload idr_remove + idr_replace iio_alloc_pollfunc iio_buffer_init iio_buffer_put @@ -897,6 +942,7 @@ input_set_abs_params input_set_capability input_unregister_device + iomem_resource iommu_alloc_resv_region iommu_device_register iommu_device_sysfs_add @@ -942,10 +988,12 @@ irq_set_parent irq_to_desc irq_work_queue + irq_work_run irq_work_sync is_dma_buf_file is_vmalloc_addr iterate_fd + jiffies_64_to_clock_t jiffies jiffies_to_msecs jiffies_to_usecs @@ -958,7 +1006,10 @@ kernel_power_off kernel_restart kernel_sigaction + kernfs_find_and_get_ns + kernfs_notify kernfs_path_from_node + kernfs_put kern_mount kern_unmount key_create_or_update @@ -967,6 +1018,7 @@ __kfifo_alloc __kfifo_free __kfifo_in + __kfifo_init __kfifo_out __kfifo_to_user kfree @@ -997,10 +1049,12 @@ kobject_uevent kobject_uevent_env krealloc + ksize kstrdup kstrdup_const kstrndup kstrtobool + kstrtobool_from_user kstrtoint kstrtoint_from_user kstrtol_from_user @@ -1033,6 +1087,7 @@ ktime_get ktime_get_coarse_with_offset ktime_get_mono_fast_ns + ktime_get_raw ktime_get_raw_ts64 ktime_get_real_ts64 ktime_get_seconds @@ -1063,12 +1118,11 @@ __log_read_mmio log_threaded_irq_wakeup_reason __log_write_mmio + loops_per_jiffy lzo1x_1_compress lzo1x_decompress_safe lzorle1x_1_compress - match_hex - match_int - match_token + match_string mbox_chan_received_data mbox_client_txdone mbox_controller_register @@ -1105,6 +1159,7 @@ memcpy __memcpy_fromio __memcpy_toio + memdup_user memmove memory_read_from_buffer memparse @@ -1138,24 +1193,33 @@ mmc_add_host mmc_alloc_host mmc_can_gpio_cd + mmc_cmdq_disable + mmc_cmdq_enable mmc_cqe_request_done mmc_detect_change mmc_free_host + mmc_get_card mmc_gpio_get_cd mmc_gpio_get_ro mmc_hw_reset mmc_of_parse + mmc_put_card mmc_regulator_get_supply mmc_regulator_set_ocr mmc_regulator_set_vqmmc mmc_remove_host mmc_request_done mmc_send_tuning + mmc_set_data_timeout + mmc_switch + mmc_wait_for_req + __mmdrop mmput mod_delayed_work_on mod_timer mod_timer_pending module_layout + module_put __msecs_to_jiffies msleep msleep_interruptible @@ -1172,6 +1236,8 @@ __napi_schedule napi_schedule_prep nd_tbl + neigh_destroy + neigh_lookup netdev_alloc_frag __netdev_alloc_skb netdev_err @@ -1189,6 +1255,7 @@ netif_tx_wake_queue netlink_broadcast __netlink_kernel_create + netlink_kernel_release netlink_register_notifier netlink_unicast netlink_unregister_notifier @@ -1210,6 +1277,7 @@ nr_cpu_ids nsecs_to_jiffies ns_to_timespec64 + n_tty_ioctl_helper __num_online_cpus nvmem_cell_get nvmem_cell_put @@ -1230,6 +1298,7 @@ of_clk_src_simple_get of_count_phandle_with_args of_cpu_node_to_id + of_devfreq_cooling_register_power of_device_get_match_data of_device_is_available of_device_is_compatible @@ -1242,6 +1311,7 @@ of_find_backlight_by_node of_find_compatible_node of_find_device_by_node + of_find_i2c_device_by_node of_find_matching_node_and_match of_find_node_by_name of_find_node_by_phandle @@ -1289,6 +1359,7 @@ of_property_read_string_helper of_property_read_u32_index of_property_read_u64 + of_property_read_u64_index of_property_read_variable_u16_array of_property_read_variable_u32_array of_property_read_variable_u64_array @@ -1298,6 +1369,7 @@ of_remove_property of_reserved_mem_device_init_by_idx of_reserved_mem_lookup + of_root of_thermal_get_trip_points of_translate_address on_each_cpu @@ -1314,11 +1386,15 @@ param_get_uint param_get_ulong param_ops_bool + param_ops_byte param_ops_charp param_ops_int + param_ops_long + param_ops_string param_ops_uint param_set_bool param_set_charp + param_set_int param_set_uint param_set_ulong pause_cpus @@ -1329,6 +1405,7 @@ perf_event_enable perf_event_release_kernel perf_event_update_userpage + perf_num_counters perf_pmu_migrate_context perf_pmu_register perf_pmu_unregister @@ -1370,12 +1447,14 @@ platform_bus_type platform_device_add platform_device_add_data + platform_device_add_resources platform_device_alloc platform_device_del platform_device_put platform_device_register platform_device_register_full platform_device_unregister + __platform_driver_probe __platform_driver_register platform_driver_unregister platform_find_device_by_driver @@ -1415,22 +1494,28 @@ power_supply_get_by_name power_supply_get_drvdata power_supply_get_property + power_supply_is_system_supplied power_supply_put power_supply_register power_supply_reg_notifier power_supply_set_property + power_supply_unreg_notifier prandom_bytes prandom_u32 preempt_schedule preempt_schedule_notrace + prepare_to_wait prepare_to_wait_event print_hex_dump printk printk_deferred proc_create proc_create_data + proc_create_seq_private proc_create_single_data + proc_dointvec_minmax proc_mkdir + proc_mkdir_data proc_remove proc_set_user pskb_expand_head @@ -1480,6 +1565,8 @@ rb_first rb_insert_color rb_next + rb_prev + rb_replace_node rcu_barrier rcu_idle_enter rcu_idle_exit @@ -1513,6 +1600,7 @@ __register_rpmsg_driver register_shrinker register_syscore_ops + register_sysctl_table register_virtio_device register_virtio_driver regmap_bulk_read @@ -1551,6 +1639,7 @@ regulator_set_active_discharge_regmap regulator_set_current_limit regulator_set_current_limit_regmap + regulator_set_load regulator_set_mode regulator_set_voltage regulator_set_voltage_sel_regmap @@ -1559,6 +1648,7 @@ regulator_sync_voltage release_firmware release_pages + __release_region remap_pfn_range remap_vmalloc_range remove_proc_entry @@ -1567,6 +1657,7 @@ request_firmware request_firmware_nowait __request_percpu_irq + __request_region request_threaded_irq reset_control_assert reset_control_deassert @@ -1588,7 +1679,6 @@ __rht_bucket_nested rht_bucket_nested rht_bucket_nested_insert - root_task_group round_jiffies round_jiffies_relative round_jiffies_up @@ -1626,10 +1716,13 @@ __sbitmap_queue_get sched_clock sched_feat_keys + sched_feat_names sched_setattr_nocheck + sched_set_fifo sched_set_normal sched_setscheduler sched_setscheduler_nocheck + sched_show_task sched_uclamp_used schedule schedule_timeout @@ -1649,7 +1742,26 @@ scsi_normalize_sense scsi_print_sense_hdr scsi_unblock_requests + sdio_claim_host + sdio_claim_irq + sdio_disable_func + sdio_enable_func + sdio_f0_readb + sdio_f0_writeb + sdio_get_host_pm_caps + sdio_readb + sdio_readl + sdio_readsb + sdio_register_driver + sdio_release_host + sdio_release_irq + sdio_set_block_size + sdio_set_host_pm_flags sdio_signal_irq + sdio_unregister_driver + sdio_writeb + sdio_writel + sdio_writesb send_sig seq_hex_dump seq_lseek @@ -1661,6 +1773,7 @@ seq_read seq_release seq_release_private + seq_vprintf seq_write serial8250_do_set_termios serial8250_do_shutdown @@ -1673,6 +1786,7 @@ serial8250_suspend_port serial8250_unregister_port set_cpus_allowed_ptr + set_freezable set_normalized_timespec64 set_page_dirty_lock __SetPageMovable @@ -1680,6 +1794,8 @@ set_user_nice sg_alloc_table sg_alloc_table_from_pages + sg_copy_from_buffer + sg_copy_to_buffer sg_free_table sg_init_one sg_init_table @@ -1689,13 +1805,16 @@ sg_next __sg_page_iter_next __sg_page_iter_start + shmem_file_setup si_mem_available + si_meminfo simple_attr_open simple_attr_read simple_attr_release simple_attr_write simple_open simple_read_from_buffer + simple_strtol simple_write_to_buffer single_open single_release @@ -1717,14 +1836,18 @@ skb_queue_head skb_queue_purge skb_queue_tail + skb_realloc_headroom skb_trim smp_call_function + smp_call_function_single snd_card_add_dev_attr snd_ctl_boolean_mono_info snd_jack_set_key snd_pcm_format_physical_width snd_pcm_format_width snd_pcm_hw_constraint_integer + snd_pcm_hw_constraint_list + snd_pcm_hw_constraint_mask64 snd_pcm_hw_constraint_minmax snd_pcm_hw_constraint_step snd_pcm_lib_free_pages @@ -1740,6 +1863,7 @@ snd_soc_component_exit_regmap snd_soc_component_init_regmap snd_soc_component_read + snd_soc_component_set_jack snd_soc_component_update_bits snd_soc_component_write snd_soc_dai_set_sysclk @@ -1756,6 +1880,7 @@ snd_soc_dapm_put_pin_switch snd_soc_dapm_put_volsw snd_soc_dapm_sync + snd_soc_find_dai snd_soc_get_volsw snd_soc_info_enum_double snd_soc_info_volsw @@ -1781,6 +1906,7 @@ __spi_register_driver spi_setup spi_sync + split_page spmi_controller_add spmi_controller_alloc spmi_controller_remove @@ -1793,6 +1919,8 @@ spmi_register_write spmi_register_zero_write sprintf + sprint_symbol + sprint_symbol_no_offset srcu_init_notifier_head srcu_notifier_call_chain srcu_notifier_chain_register @@ -1802,6 +1930,8 @@ __stack_chk_fail __stack_chk_guard stack_trace_save + static_key_disable_cpuslocked + static_key_enable_cpuslocked static_key_slow_dec static_key_slow_inc stop_one_cpu_nowait @@ -1841,11 +1971,14 @@ syscon_node_to_regmap syscon_regmap_lookup_by_compatible syscon_regmap_lookup_by_phandle + sysctl_sched_features sysfs_create_bin_file sysfs_create_file_ns sysfs_create_group sysfs_create_link __sysfs_match_string + sysfs_merge_group + sysfs_notify sysfs_remove_bin_file sysfs_remove_file_ns sysfs_remove_group @@ -1855,6 +1988,7 @@ system_freezable_wq system_freezing_cnt system_highpri_wq + system_long_wq system_power_efficient_wq system_state system_unbound_wq @@ -1866,12 +2000,13 @@ tasklet_kill __tasklet_schedule tasklet_setup - tasklist_lock + task_may_not_preempt __task_pid_nr_ns __task_rq_lock task_sched_runtime thermal_cooling_device_unregister thermal_of_cooling_device_register + thermal_zone_device_update thermal_zone_get_temp thermal_zone_get_zone_by_name tick_nohz_get_idle_calls_cpu @@ -1903,10 +2038,11 @@ __traceiter_android_rvh_rtmutex_prepare_setprio __traceiter_android_rvh_sched_newidle_balance __traceiter_android_rvh_select_task_rq_fair + __traceiter_android_rvh_select_task_rq_rt __traceiter_android_rvh_setscheduler __traceiter_android_rvh_set_user_nice __traceiter_android_rvh_tick_entry - __traceiter_android_rvh_uclamp_eff_get + __traceiter_android_rvh_update_cpu_capacity __traceiter_android_rvh_v4l2subdev_set_fmt __traceiter_android_rvh_v4l2subdev_set_frame_interval __traceiter_android_rvh_v4l2subdev_set_selection @@ -1916,6 +2052,7 @@ __traceiter_android_vh_binder_restore_priority __traceiter_android_vh_binder_set_priority __traceiter_android_vh_binder_transaction_init + __traceiter_android_vh_cgroup_attach __traceiter_android_vh_cgroup_set_task __traceiter_android_vh_check_bpf_syscall __traceiter_android_vh_check_file_open @@ -1923,18 +2060,15 @@ __traceiter_android_vh_clear_mask_adjust __traceiter_android_vh_clear_reserved_fmt_fields __traceiter_android_vh_commit_creds - __traceiter_android_vh_em_cpu_energy __traceiter_android_vh_exit_creds __traceiter_android_vh_fill_ext_fmtdesc __traceiter_android_vh_finish_update_load_avg_se __traceiter_android_vh_freq_qos_add_request __traceiter_android_vh_freq_qos_update_request - __traceiter_android_vh_freq_qos_remove_request - __traceiter_android_vh_iommu_alloc_iova __traceiter_android_vh_iommu_iovad_alloc_iova - __traceiter_android_vh_iommu_free_iova __traceiter_android_vh_iommu_iovad_free_iova __traceiter_android_vh_ipv6_gen_linklocal_addr + __traceiter_android_vh_is_fpsimd_save __traceiter_android_vh_logbuf __traceiter_android_vh_override_creds __traceiter_android_vh_prepare_update_load_avg_se @@ -1943,7 +2077,6 @@ __traceiter_android_vh_rwsem_wake __traceiter_android_vh_rwsem_write_finished __traceiter_android_vh_scheduler_tick - __traceiter_android_vh_scmi_timeout_sync __traceiter_android_vh_selinux_avc_insert __traceiter_android_vh_selinux_avc_lookup __traceiter_android_vh_selinux_avc_node_delete @@ -1956,11 +2089,15 @@ __traceiter_android_vh_set_module_permit_after_init __traceiter_android_vh_set_module_permit_before_init __traceiter_android_vh_set_wake_flags - __traceiter_android_vh_snd_soc_card_get_comp_chain + __traceiter_android_vh_show_resume_epoch_val + __traceiter_android_vh_show_suspend_epoch_val + __traceiter_android_vh_snd_compr_use_pause_in_drain + __traceiter_android_vh_sound_usb_support_cpu_suspend __traceiter_android_vh_syscall_prctl_finished __traceiter_android_vh_ufs_send_command __traceiter_android_vh_ufs_send_tm_command __traceiter_cpu_frequency + __traceiter_gpu_mem_total __traceiter_pelt_se_tp __traceiter_rwmmio_post_read __traceiter_rwmmio_read @@ -1968,6 +2105,7 @@ __traceiter_sched_update_nr_running_tp __traceiter_task_newtask __traceiter_xhci_urb_giveback + trace_output_call __tracepoint_android_rvh_after_enqueue_task __tracepoint_android_rvh_cpu_overutilized __tracepoint_android_rvh_dequeue_task @@ -1983,10 +2121,11 @@ __tracepoint_android_rvh_rtmutex_prepare_setprio __tracepoint_android_rvh_sched_newidle_balance __tracepoint_android_rvh_select_task_rq_fair + __tracepoint_android_rvh_select_task_rq_rt __tracepoint_android_rvh_setscheduler __tracepoint_android_rvh_set_user_nice __tracepoint_android_rvh_tick_entry - __tracepoint_android_rvh_uclamp_eff_get + __tracepoint_android_rvh_update_cpu_capacity __tracepoint_android_rvh_v4l2subdev_set_fmt __tracepoint_android_rvh_v4l2subdev_set_frame_interval __tracepoint_android_rvh_v4l2subdev_set_selection @@ -1996,6 +2135,7 @@ __tracepoint_android_vh_binder_restore_priority __tracepoint_android_vh_binder_set_priority __tracepoint_android_vh_binder_transaction_init + __tracepoint_android_vh_cgroup_attach __tracepoint_android_vh_cgroup_set_task __tracepoint_android_vh_check_bpf_syscall __tracepoint_android_vh_check_file_open @@ -2003,18 +2143,15 @@ __tracepoint_android_vh_clear_mask_adjust __tracepoint_android_vh_clear_reserved_fmt_fields __tracepoint_android_vh_commit_creds - __tracepoint_android_vh_em_cpu_energy __tracepoint_android_vh_exit_creds __tracepoint_android_vh_fill_ext_fmtdesc __tracepoint_android_vh_finish_update_load_avg_se __tracepoint_android_vh_freq_qos_add_request __tracepoint_android_vh_freq_qos_update_request - __tracepoint_android_vh_freq_qos_remove_request - __tracepoint_android_vh_iommu_alloc_iova __tracepoint_android_vh_iommu_iovad_alloc_iova - __tracepoint_android_vh_iommu_free_iova __tracepoint_android_vh_iommu_iovad_free_iova __tracepoint_android_vh_ipv6_gen_linklocal_addr + __tracepoint_android_vh_is_fpsimd_save __tracepoint_android_vh_logbuf __tracepoint_android_vh_override_creds __tracepoint_android_vh_prepare_update_load_avg_se @@ -2023,7 +2160,6 @@ __tracepoint_android_vh_rwsem_wake __tracepoint_android_vh_rwsem_write_finished __tracepoint_android_vh_scheduler_tick - __tracepoint_android_vh_scmi_timeout_sync __tracepoint_android_vh_selinux_avc_insert __tracepoint_android_vh_selinux_avc_lookup __tracepoint_android_vh_selinux_avc_node_delete @@ -2036,11 +2172,15 @@ __tracepoint_android_vh_set_module_permit_after_init __tracepoint_android_vh_set_module_permit_before_init __tracepoint_android_vh_set_wake_flags - __tracepoint_android_vh_snd_soc_card_get_comp_chain + __tracepoint_android_vh_show_resume_epoch_val + __tracepoint_android_vh_show_suspend_epoch_val + __tracepoint_android_vh_snd_compr_use_pause_in_drain + __tracepoint_android_vh_sound_usb_support_cpu_suspend __tracepoint_android_vh_syscall_prctl_finished __tracepoint_android_vh_ufs_send_command __tracepoint_android_vh_ufs_send_tm_command __tracepoint_cpu_frequency + __tracepoint_gpu_mem_total __tracepoint_pelt_se_tp tracepoint_probe_register tracepoint_probe_unregister @@ -2052,7 +2192,7 @@ __tracepoint_task_newtask __tracepoint_xhci_urb_giveback trace_print_array_seq - trace_print_hex_seq + trace_print_flags_seq trace_print_symbols_seq __trace_puts trace_raw_output_prep @@ -2060,12 +2200,15 @@ trace_seq_putc trace_set_clr_event tracing_off + try_module_get try_wait_for_completion + tty_driver_flush_buffer tty_flip_buffer_push tty_insert_flip_string_fixed_flag + tty_register_ldisc tty_termios_baud_rate tty_termios_encode_baud_rate - typec_get_drvdata + tty_unregister_ldisc typec_mux_get_drvdata typec_mux_register typec_mux_set @@ -2082,6 +2225,7 @@ typec_switch_register typec_switch_unregister typec_unregister_partner + typec_unregister_port uart_get_baud_rate uart_get_divisor uart_update_timeout @@ -2113,7 +2257,9 @@ ufshcd_release ufshcd_remove ufshcd_uic_hibern8_exit + ufshcd_update_evt_hist unlock_page + unmap_mapping_range unpin_user_page unpin_user_pages unregister_blkdev @@ -2135,6 +2281,7 @@ unregister_reboot_notifier unregister_rpmsg_driver unregister_shrinker + unregister_sysctl_table unregister_virtio_device unregister_virtio_driver up @@ -2146,6 +2293,8 @@ usb_add_function usb_add_gadget_udc usb_add_hcd + usb_add_phy_dev + usb_assign_descriptors usb_composite_probe usb_composite_unregister usb_copy_descriptors @@ -2164,6 +2313,7 @@ usb_ep_queue usb_ep_set_halt usb_ep_set_maxpacket_limit + usb_free_all_descriptors usb_function_register usb_function_unregister usb_gadget_connect @@ -2178,8 +2328,15 @@ usb_get_function usb_get_function_instance usb_get_maximum_speed + usb_gstrings_attach + usb_hcd_check_unlink_urb + usb_hcd_giveback_urb usb_hcd_is_primary_hcd + usb_hcd_link_urb_to_ep usb_hcd_poll_rh_status + usb_hcd_resume_root_hub + usb_hcd_unlink_urb_from_ep + usb_hcd_unmap_urb_for_dma usb_interface_id usbnet_change_mtu usbnet_disconnect @@ -2209,12 +2366,15 @@ usbnet_write_cmd_async usbnet_write_cmd_nopm usb_os_desc_prepare_interf_dir + usb_otg_state_string + usb_phy_set_charger_current usb_put_function usb_put_function_instance usb_put_hcd usb_register_driver usb_remove_function usb_remove_hcd + usb_remove_phy usb_role_switch_get usb_role_switch_get_drvdata usb_role_switch_register @@ -2354,7 +2514,6 @@ virtqueue_detach_unused_buf virtqueue_get_buf virtqueue_get_vring_size - virtqueue_kick virtqueue_kick_prepare virtqueue_notify vmalloc @@ -2363,10 +2522,15 @@ vmalloc_user vmap vm_event_states + vmf_insert_mixed + vmf_insert_pfn_prot + vm_get_page_prot + vm_insert_page vm_map_ram vm_node_stat vm_unmap_ram vm_zone_stat + vprintk vring_del_virtqueue vring_interrupt vring_new_virtqueue @@ -2381,6 +2545,7 @@ wait_for_completion_interruptible_timeout wait_for_completion_io_timeout wait_for_completion_killable + wait_for_completion_killable_timeout wait_for_completion_timeout wait_woken __wake_up @@ -2399,7 +2564,6 @@ woken_wake_function work_busy work_on_cpu - ww_mutex_lock ww_mutex_unlock xhci_add_endpoint xhci_check_bandwidth @@ -2409,143 +2573,77 @@ xhci_get_ep_ctx xhci_init_driver xhci_reset_bandwidth + zlib_deflate + zlib_deflateEnd + zlib_deflateInit2 + zlib_deflateReset + zlib_deflate_workspacesize # preserved by --additions-only - all_vm_events - __arch_clear_user - __bitmap_equal - __bitmap_or blk_insert_cloned_request - cache_line_size - cgroup_taskset_first - cgroup_taskset_next class_create_file_ns class_remove_file_ns - clear_page - cpufreq_update_util_data - cpu_pm_register_notifier - cpu_pm_unregister_notifier + console_unlock debug_locks_off - devfreq_add_device - devfreq_cooling_unregister - devfreq_register_opp_notifier - devfreq_unregister_opp_notifier - dev_get_by_name + dev_change_flags devm_of_pwm_get - devm_rc_allocate_device - devm_rc_register_device - dev_pm_opp_find_freq_exact - dev_pm_opp_put_regulators - dev_pm_opp_set_regulators - dma_buf_mmap - dma_fence_get_status - dma_fence_remove_callback - dma_heap_buffer_free - dma_sync_single_for_device - downgrade_write - down_read_trylock drm_gem_private_object_init - get_user_pages - get_user_pages_fast - gpiod_set_raw_value + hashlen_string hci_alloc_dev hci_free_dev hci_recv_frame hci_register_dev hci_unregister_dev hex_dump_to_buffer - iomem_resource - irq_work_run - jiffies_64_to_clock_t - __kfifo_init kset_find_obj - kstrtobool_from_user - ktime_get_raw led_classdev_unregister - memdup_user - __mmdrop - module_put - netlink_kernel_release + match_hex + match_int + match_token nla_put_nohdr - n_tty_ioctl_helper - of_devfreq_cooling_register_power - of_root - param_ops_byte - param_ops_string - perf_num_counters pin_user_pages_remote - rb_prev - rb_replace_node - __release_region - __request_region + root_task_group schedutil_cpu_util - sdio_claim_host - sdio_claim_irq - sdio_disable_func - sdio_enable_func - sdio_f0_readb - sdio_f0_writeb - sdio_get_host_pm_caps - sdio_readb - sdio_readl - sdio_readsb - sdio_register_driver - sdio_release_host - sdio_release_irq - sdio_set_block_size - sdio_set_host_pm_flags - sdio_unregister_driver - sdio_writeb - sdio_writel - sdio_writesb send_sig_info - shmem_file_setup - si_meminfo skb_pull_rcsum - skb_realloc_headroom - smp_call_function_single snd_soc_component_test_bits - sprint_symbol_no_offset strpbrk strspn syscore_resume syscore_suspend - system_long_wq - thermal_zone_device_update + tasklist_lock __traceiter_android_rvh_sched_rebalance_domains - __traceiter_android_vh_cgroup_attach - __traceiter_android_vh_is_fpsimd_save + __traceiter_android_rvh_uclamp_eff_get + __traceiter_android_vh_em_cpu_energy + __traceiter_android_vh_freq_qos_remove_request + __traceiter_android_vh_iommu_alloc_iova + __traceiter_android_vh_iommu_free_iova __traceiter_android_vh_media_device_setup_link + __traceiter_android_vh_scmi_timeout_sync + __traceiter_android_vh_snd_soc_card_get_comp_chain __traceiter_android_vh_v4l2subdev_set_fmt __traceiter_android_vh_v4l2subdev_set_frame_interval __traceiter_android_vh_v4l2subdev_set_selection - __traceiter_gpu_mem_total - trace_output_call __tracepoint_android_rvh_sched_rebalance_domains - __tracepoint_android_vh_cgroup_attach - __tracepoint_android_vh_is_fpsimd_save + __tracepoint_android_rvh_uclamp_eff_get + __tracepoint_android_vh_em_cpu_energy + __tracepoint_android_vh_freq_qos_remove_request + __tracepoint_android_vh_iommu_alloc_iova + __tracepoint_android_vh_iommu_free_iova __tracepoint_android_vh_media_device_setup_link + __tracepoint_android_vh_scmi_timeout_sync + __tracepoint_android_vh_snd_soc_card_get_comp_chain __tracepoint_android_vh_ufs_update_sdev __tracepoint_android_vh_v4l2subdev_set_fmt __tracepoint_android_vh_v4l2subdev_set_frame_interval __tracepoint_android_vh_v4l2subdev_set_selection - __tracepoint_gpu_mem_total - trace_print_flags_seq - try_module_get - tty_driver_flush_buffer - tty_register_ldisc - tty_unregister_ldisc + trace_print_hex_seq + typec_get_drvdata ufshcd_auto_hibern8_update ufshcd_shutdown - unmap_mapping_range unregister_syscore_ops v4l2_m2m_buf_remove_by_buf - vmf_insert_pfn_prot - wait_for_completion_killable_timeout + virtqueue_kick wireless_send_event + ww_mutex_lock ww_mutex_lock_interruptible - zlib_deflate - zlib_deflateEnd - zlib_deflateInit2 - zlib_deflateReset - zlib_deflate_workspacesize From 250abe08bbb4ae81dac5568e3df8aa5749c0fc83 Mon Sep 17 00:00:00 2001 From: Vincent Pelletier Date: Sat, 18 Dec 2021 02:18:40 +0000 Subject: [PATCH 41/52] UPSTREAM: usb: gadget: f_fs: Clear ffs_eventfd in ffs_data_clear. commit b1e0887379422975f237d43d8839b751a6bcf154 upstream. ffs_data_clear is indirectly called from both ffs_fs_kill_sb and ffs_ep0_release, so it ends up being called twice when userland closes ep0 and then unmounts f_fs. If userland provided an eventfd along with function's USB descriptors, it ends up calling eventfd_ctx_put as many times, causing a refcount underflow. NULL-ify ffs_eventfd to prevent these extraneous eventfd_ctx_put calls. Also, set epfiles to NULL right after de-allocating it, for readability. For completeness, ffs_data_clear actually ends up being called thrice, the last call being before the whole ffs structure gets freed, so when this specific sequence happens there is a second underflow happening (but not being reported): /sys/kernel/debug/tracing# modprobe usb_f_fs /sys/kernel/debug/tracing# echo ffs_data_clear > set_ftrace_filter /sys/kernel/debug/tracing# echo function > current_tracer /sys/kernel/debug/tracing# echo 1 > tracing_on (setup gadget, run and kill function userland process, teardown gadget) /sys/kernel/debug/tracing# echo 0 > tracing_on /sys/kernel/debug/tracing# cat trace smartcard-openp-436 [000] ..... 1946.208786: ffs_data_clear <-ffs_data_closed smartcard-openp-431 [000] ..... 1946.279147: ffs_data_clear <-ffs_data_closed smartcard-openp-431 [000] .n... 1946.905512: ffs_data_clear <-ffs_data_put Warning output corresponding to above trace: [ 1946.284139] WARNING: CPU: 0 PID: 431 at lib/refcount.c:28 refcount_warn_saturate+0x110/0x15c [ 1946.293094] refcount_t: underflow; use-after-free. [ 1946.298164] Modules linked in: usb_f_ncm(E) u_ether(E) usb_f_fs(E) hci_uart(E) btqca(E) btrtl(E) btbcm(E) btintel(E) bluetooth(E) nls_ascii(E) nls_cp437(E) vfat(E) fat(E) bcm2835_v4l2(CE) bcm2835_mmal_vchiq(CE) videobuf2_vmalloc(E) videobuf2_memops(E) sha512_generic(E) videobuf2_v4l2(E) sha512_arm(E) videobuf2_common(E) videodev(E) cpufreq_dt(E) snd_bcm2835(CE) brcmfmac(E) mc(E) vc4(E) ctr(E) brcmutil(E) snd_soc_core(E) snd_pcm_dmaengine(E) drbg(E) snd_pcm(E) snd_timer(E) snd(E) soundcore(E) drm_kms_helper(E) cec(E) ansi_cprng(E) rc_core(E) syscopyarea(E) raspberrypi_cpufreq(E) sysfillrect(E) sysimgblt(E) cfg80211(E) max17040_battery(OE) raspberrypi_hwmon(E) fb_sys_fops(E) regmap_i2c(E) ecdh_generic(E) rfkill(E) ecc(E) bcm2835_rng(E) rng_core(E) vchiq(CE) leds_gpio(E) libcomposite(E) fuse(E) configfs(E) ip_tables(E) x_tables(E) autofs4(E) ext4(E) crc16(E) mbcache(E) jbd2(E) crc32c_generic(E) sdhci_iproc(E) sdhci_pltfm(E) sdhci(E) [ 1946.399633] CPU: 0 PID: 431 Comm: smartcard-openp Tainted: G C OE 5.15.0-1-rpi #1 Debian 5.15.3-1 [ 1946.417950] Hardware name: BCM2835 [ 1946.425442] Backtrace: [ 1946.432048] [] (dump_backtrace) from [] (show_stack+0x20/0x24) [ 1946.448226] r7:00000009 r6:0000001c r5:c04a948c r4:c0a64e2c [ 1946.458412] [] (show_stack) from [] (dump_stack+0x28/0x30) [ 1946.470380] [] (dump_stack) from [] (__warn+0xe8/0x154) [ 1946.482067] r5:c04a948c r4:c0a71dc8 [ 1946.490184] [] (__warn) from [] (warn_slowpath_fmt+0xa0/0xe4) [ 1946.506758] r7:00000009 r6:0000001c r5:c0a71dc8 r4:c0a71e04 [ 1946.517070] [] (warn_slowpath_fmt) from [] (refcount_warn_saturate+0x110/0x15c) [ 1946.535309] r8:c0100224 r7:c0dfcb84 r6:ffffffff r5:c3b84c00 r4:c24a17c0 [ 1946.546708] [] (refcount_warn_saturate) from [] (eventfd_ctx_put+0x48/0x74) [ 1946.564476] [] (eventfd_ctx_put) from [] (ffs_data_clear+0xd0/0x118 [usb_f_fs]) [ 1946.582664] r5:c3b84c00 r4:c2695b00 [ 1946.590668] [] (ffs_data_clear [usb_f_fs]) from [] (ffs_data_closed+0x9c/0x150 [usb_f_fs]) [ 1946.609608] r5:bf54d014 r4:c2695b00 [ 1946.617522] [] (ffs_data_closed [usb_f_fs]) from [] (ffs_fs_kill_sb+0x2c/0x30 [usb_f_fs]) [ 1946.636217] r7:c0dfcb84 r6:c3a12260 r5:bf54d014 r4:c229f000 [ 1946.646273] [] (ffs_fs_kill_sb [usb_f_fs]) from [] (deactivate_locked_super+0x54/0x9c) [ 1946.664893] r5:bf54d014 r4:c229f000 [ 1946.672921] [] (deactivate_locked_super) from [] (deactivate_super+0x60/0x64) [ 1946.690722] r5:c2a09000 r4:c229f000 [ 1946.698706] [] (deactivate_super) from [] (cleanup_mnt+0xe4/0x14c) [ 1946.715553] r5:c2a09000 r4:00000000 [ 1946.723528] [] (cleanup_mnt) from [] (__cleanup_mnt+0x1c/0x20) [ 1946.739922] r7:c0dfcb84 r6:c3a12260 r5:c3a126fc r4:00000000 [ 1946.750088] [] (__cleanup_mnt) from [] (task_work_run+0x84/0xb8) [ 1946.766602] [] (task_work_run) from [] (do_work_pending+0x470/0x56c) [ 1946.783540] r7:5ac3c35a r6:c0d0424c r5:c200bfb0 r4:c200a000 [ 1946.793614] [] (do_work_pending) from [] (slow_work_pending+0xc/0x20) [ 1946.810553] Exception stack(0xc200bfb0 to 0xc200bff8) [ 1946.820129] bfa0: 00000000 00000000 000000aa b5e21430 [ 1946.837104] bfc0: bef867a0 00000001 bef86840 00000034 bef86838 bef86790 bef86794 bef867a0 [ 1946.854125] bfe0: 00000000 bef86798 b67b7a1c b6d626a4 60000010 b5a23760 [ 1946.865335] r10:00000000 r9:c200a000 r8:c0100224 r7:00000034 r6:bef86840 r5:00000001 [ 1946.881914] r4:bef867a0 [ 1946.888793] ---[ end trace 7387f2a9725b28d0 ]--- Fixes: 5e33f6fdf735 ("usb: gadget: ffs: add eventfd notification about ffs events") Cc: stable Signed-off-by: Vincent Pelletier Link: https://lore.kernel.org/r/f79eeea29f3f98de6782a064ec0f7351ad2f598f.1639793920.git.plr.vincent@gmail.com Signed-off-by: Greg Kroah-Hartman BUG: 217829161 Change-Id: I8672231aeed2f19f06af35ed72e60198bb17cca7 Signed-off-by: Udipto Goswami --- drivers/usb/gadget/function/f_fs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 2113e541457e..d8652321e15e 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1772,11 +1772,15 @@ static void ffs_data_clear(struct ffs_data *ffs) BUG_ON(ffs->gadget); - if (ffs->epfiles) + if (ffs->epfiles) { ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count); + ffs->epfiles = NULL; + } - if (ffs->ffs_eventfd) + if (ffs->ffs_eventfd) { eventfd_ctx_put(ffs->ffs_eventfd); + ffs->ffs_eventfd = NULL; + } kfree(ffs->raw_descs_data); kfree(ffs->raw_strings); @@ -1789,7 +1793,6 @@ static void ffs_data_reset(struct ffs_data *ffs) ffs_data_clear(ffs); - ffs->epfiles = NULL; ffs->raw_descs_data = NULL; ffs->raw_descs = NULL; ffs->raw_strings = NULL; From 3a49d3b67726152ab584951beed27413d29d5d52 Mon Sep 17 00:00:00 2001 From: Udipto Goswami Date: Thu, 27 Jan 2022 09:39:55 +0530 Subject: [PATCH 42/52] FROMGIT: usb: f_fs: Fix use-after-free for epfile Consider a case where ffs_func_eps_disable is called from ffs_func_disable as part of composition switch and at the same time ffs_epfile_release get called from userspace. ffs_epfile_release will free up the read buffer and call ffs_data_closed which in turn destroys ffs->epfiles and mark it as NULL. While this was happening the driver has already initialized the local epfile in ffs_func_eps_disable which is now freed and waiting to acquire the spinlock. Once spinlock is acquired the driver proceeds with the stale value of epfile and tries to free the already freed read buffer causing use-after-free. Following is the illustration of the race: CPU1 CPU2 ffs_func_eps_disable epfiles (local copy) ffs_epfile_release ffs_data_closed if (last file closed) ffs_data_reset ffs_data_clear ffs_epfiles_destroy spin_lock dereference epfiles Fix this races by taking epfiles local copy & assigning it under spinlock and if epfiles(local) is null then update it in ffs->epfiles then finally destroy it. Extending the scope further from the race, protecting the ep related structures, and concurrent accesses. Fixes: a9e6f83c2df (usb: gadget: f_fs: stop sleeping in ffs_func_eps_disable) Reviewed-by: John Keeping Signed-off-by: Pratham Pratap Co-developed-by: Udipto Goswami Signed-off-by: Udipto Goswami Link: https://lore.kernel.org/r/1643256595-10797-1-git-send-email-quic_ugoswami@quicinc.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit ebe2b1add1055b903e2acd86b290a85297edc0b3 https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-linus) BUG: 217829161 Change-Id: Iab64af51aece85df3208afd7b6cd108b955eae45 Signed-off-by: Udipto Goswami --- drivers/usb/gadget/function/f_fs.c | 56 ++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index d8652321e15e..bb0d92837f67 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c @@ -1710,16 +1710,24 @@ static void ffs_data_put(struct ffs_data *ffs) static void ffs_data_closed(struct ffs_data *ffs) { + struct ffs_epfile *epfiles; + unsigned long flags; + ENTER(); if (atomic_dec_and_test(&ffs->opened)) { if (ffs->no_disconnect) { ffs->state = FFS_DEACTIVATED; - if (ffs->epfiles) { - ffs_epfiles_destroy(ffs->epfiles, - ffs->eps_count); - ffs->epfiles = NULL; - } + spin_lock_irqsave(&ffs->eps_lock, flags); + epfiles = ffs->epfiles; + ffs->epfiles = NULL; + spin_unlock_irqrestore(&ffs->eps_lock, + flags); + + if (epfiles) + ffs_epfiles_destroy(epfiles, + ffs->eps_count); + if (ffs->setup_state == FFS_SETUP_PENDING) __ffs_ep0_stall(ffs); } else { @@ -1766,14 +1774,27 @@ static struct ffs_data *ffs_data_new(const char *dev_name) static void ffs_data_clear(struct ffs_data *ffs) { + struct ffs_epfile *epfiles; + unsigned long flags; + ENTER(); ffs_closed(ffs); BUG_ON(ffs->gadget); - if (ffs->epfiles) { - ffs_epfiles_destroy(ffs->epfiles, ffs->eps_count); + spin_lock_irqsave(&ffs->eps_lock, flags); + epfiles = ffs->epfiles; + ffs->epfiles = NULL; + spin_unlock_irqrestore(&ffs->eps_lock, flags); + + /* + * potential race possible between ffs_func_eps_disable + * & ffs_epfile_release therefore maintaining a local + * copy of epfile will save us from use-after-free. + */ + if (epfiles) { + ffs_epfiles_destroy(epfiles, ffs->eps_count); ffs->epfiles = NULL; } @@ -1921,12 +1942,15 @@ static void ffs_epfiles_destroy(struct ffs_epfile *epfiles, unsigned count) static void ffs_func_eps_disable(struct ffs_function *func) { - struct ffs_ep *ep = func->eps; - struct ffs_epfile *epfile = func->ffs->epfiles; - unsigned count = func->ffs->eps_count; + struct ffs_ep *ep; + struct ffs_epfile *epfile; + unsigned short count; unsigned long flags; spin_lock_irqsave(&func->ffs->eps_lock, flags); + count = func->ffs->eps_count; + epfile = func->ffs->epfiles; + ep = func->eps; while (count--) { /* pending requests get nuked */ if (likely(ep->ep)) @@ -1944,14 +1968,18 @@ static void ffs_func_eps_disable(struct ffs_function *func) static int ffs_func_eps_enable(struct ffs_function *func) { - struct ffs_data *ffs = func->ffs; - struct ffs_ep *ep = func->eps; - struct ffs_epfile *epfile = ffs->epfiles; - unsigned count = ffs->eps_count; + struct ffs_data *ffs; + struct ffs_ep *ep; + struct ffs_epfile *epfile; + unsigned short count; unsigned long flags; int ret = 0; spin_lock_irqsave(&func->ffs->eps_lock, flags); + ffs = func->ffs; + ep = func->eps; + epfile = ffs->epfiles; + count = ffs->eps_count; while(count--) { ep->ep->driver_data = ep; From c34fa06f4bbba9e26fe50e5f6cde53c61560a794 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 31 Jan 2022 12:36:42 -0800 Subject: [PATCH 43/52] FROMLIST: rcu: Don't deboost before reporting expedited quiescent state Currently rcu_preempt_deferred_qs_irqrestore() releases rnp->boost_mtx before reporting the expedited quiescent state. Under heavy real-time load, this can result in this function being preempted before the quiescent state is reported, which can in turn prevent the expedited grace period from completing. Tim Murray reports that the resulting expedited grace periods can take hundreds of milliseconds and even more than one second, when they should normally complete in less than a millisecond. This patch follows Neeraj's suggestion (seconded by Tim and by Uladzislau Rezki) of simply reversing the two operations. Reported-by: Tim Murray Reported-by: Joel Fernandes Reported-by: Neeraj Upadhyay Signed-off-by: Paul E. McKenney Bug: 217236054 Link: https://lore.kernel.org/lkml/20220204232406.814-9-paulmck@kernel.org/ Signed-off-by: Tim Murray Change-Id: Ic0f0330b65a0c776a563e03e4b59bf4ab4fbccf6 --- kernel/rcu/tree_plugin.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h index 6ed153f226b3..33a725a03024 100644 --- a/kernel/rcu/tree_plugin.h +++ b/kernel/rcu/tree_plugin.h @@ -531,16 +531,16 @@ rcu_preempt_deferred_qs_irqrestore(struct task_struct *t, unsigned long flags) raw_spin_unlock_irqrestore_rcu_node(rnp, flags); } - /* Unboost if we were boosted. */ - if (IS_ENABLED(CONFIG_RCU_BOOST) && drop_boost_mutex) - rt_mutex_futex_unlock(&rnp->boost_mtx); - /* * If this was the last task on the expedited lists, * then we need to report up the rcu_node hierarchy. */ if (!empty_exp && empty_exp_now) rcu_report_exp_rnp(rnp, true); + + /* Unboost if we were boosted. */ + if (IS_ENABLED(CONFIG_RCU_BOOST) && drop_boost_mutex) + rt_mutex_futex_unlock(&rnp->boost_mtx); } else { local_irq_restore(flags); } From c8701aa0a76b72708abf6186b13b1b585741c157 Mon Sep 17 00:00:00 2001 From: Tim Murray Date: Mon, 31 Jan 2022 18:16:23 -0800 Subject: [PATCH 44/52] ANDROID: GKI: enable RCU_BOOST Now that RCU_BOOST handles CFS threads, enable it. Bug: 217236054 Test: ensure CFS threads are boosted, TH Signed-off-by: Tim Murray Change-Id: Idd02467f6caad063e14aa5496617b8bbaf0e9ab1 --- arch/arm64/configs/gki_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/gki_defconfig b/arch/arm64/configs/gki_defconfig index 27133a411ce4..42faae4a74aa 100644 --- a/arch/arm64/configs/gki_defconfig +++ b/arch/arm64/configs/gki_defconfig @@ -8,6 +8,7 @@ CONFIG_TASK_IO_ACCOUNTING=y CONFIG_PSI=y CONFIG_RCU_EXPERT=y CONFIG_RCU_FAST_NO_HZ=y +CONFIG_RCU_BOOST=y CONFIG_RCU_NOCB_CPU=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y From fa055ddfd5853ab4102bb189e79bb24648291df3 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 13 Dec 2021 13:28:40 -0800 Subject: [PATCH 45/52] BACKPORT: f2fs: avoid down_write on nat_tree_lock during checkpoint Let's cache nat entry if there's no lock contention only. Bug: 214413989 Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim (cherry picked from commit 0df035c7208c5e3e2ae7685548353ae536a19015 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master) [ Address merge conflict ] Change-Id: I0bf70451bc0b148ebb88429d6294ea8e68008e48 --- fs/f2fs/node.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 28cfc9a86010..52a030e8181d 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -428,6 +428,10 @@ static void cache_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, struct f2fs_nm_info *nm_i = NM_I(sbi); struct nat_entry *new, *e; + /* Let's mitigate lock contention of nat_tree_lock during checkpoint */ + if (rwsem_is_locked(&sbi->cp_global_sem)) + return; + new = __alloc_nat_entry(nid, false); if (!new) return; From 23686f5ee87076058cb4cc82c5059f4007fc6073 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Mon, 13 Dec 2021 14:16:32 -0800 Subject: [PATCH 46/52] UPSTREAM: f2fs: do not bother checkpoint by f2fs_get_node_info This patch tries to mitigate lock contention between f2fs_write_checkpoint and f2fs_get_node_info along with nat_tree_lock. The idea is, if checkpoint is currently running, other threads that try to grab nat_tree_lock would be better to wait for checkpoint. Bug: 214413989 Reviewed-by: Chao Yu Signed-off-by: Jaegeuk Kim (cherry picked from commit a9419b63bf414775e8aeee95d8c4a5e0df690748 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master) Change-Id: I7e253e8bf26012e451330ba6ce00bfc3839bdda3 --- fs/f2fs/checkpoint.c | 2 +- fs/f2fs/compress.c | 2 +- fs/f2fs/data.c | 8 ++++---- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 2 +- fs/f2fs/gc.c | 6 +++--- fs/f2fs/inline.c | 4 ++-- fs/f2fs/inode.c | 2 +- fs/f2fs/node.c | 19 ++++++++++--------- fs/f2fs/recovery.c | 2 +- fs/f2fs/segment.c | 2 +- 11 files changed, 26 insertions(+), 25 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 23d36de40317..4689f3e8a703 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -650,7 +650,7 @@ static int recover_orphan_inode(struct f2fs_sb_info *sbi, nid_t ino) /* truncate all the data during iput */ iput(inode); - err = f2fs_get_node_info(sbi, ino, &ni); + err = f2fs_get_node_info(sbi, ino, &ni, false); if (err) goto err_out; diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index b8b3f1160afa..2b6c20f2657b 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1222,7 +1222,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, psize = (loff_t)(cc->rpages[last_index]->index + 1) << PAGE_SHIFT; - err = f2fs_get_node_info(fio.sbi, dn.nid, &ni); + err = f2fs_get_node_info(fio.sbi, dn.nid, &ni, false); if (err) goto out_put_dnode; diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 4caf3e5653a7..e3aa49971091 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1356,7 +1356,7 @@ static int __allocate_data_block(struct dnode_of_data *dn, int seg_type) if (unlikely(is_inode_flag_set(dn->inode, FI_NO_ALLOC))) return -EPERM; - err = f2fs_get_node_info(sbi, dn->nid, &ni); + err = f2fs_get_node_info(sbi, dn->nid, &ni, false); if (err) return err; @@ -1791,7 +1791,7 @@ static int f2fs_xattr_fiemap(struct inode *inode, if (!page) return -ENOMEM; - err = f2fs_get_node_info(sbi, inode->i_ino, &ni); + err = f2fs_get_node_info(sbi, inode->i_ino, &ni, false); if (err) { f2fs_put_page(page, 1); return err; @@ -1823,7 +1823,7 @@ static int f2fs_xattr_fiemap(struct inode *inode, if (!page) return -ENOMEM; - err = f2fs_get_node_info(sbi, xnid, &ni); + err = f2fs_get_node_info(sbi, xnid, &ni, false); if (err) { f2fs_put_page(page, 1); return err; @@ -2655,7 +2655,7 @@ got_it: fio->need_lock = LOCK_REQ; } - err = f2fs_get_node_info(fio->sbi, dn.nid, &ni); + err = f2fs_get_node_info(fio->sbi, dn.nid, &ni, false); if (err) goto out_writepage; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index c129a91b31a1..1b105ba0e153 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3410,7 +3410,7 @@ int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid); bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid); bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino); int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, - struct node_info *ni); + struct node_info *ni, bool checkpoint_context); pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs); int f2fs_get_dnode_of_data(struct dnode_of_data *dn, pgoff_t index, int mode); int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index d183efa2c58e..720952b5e3df 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -1211,7 +1211,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode, if (ret) return ret; - ret = f2fs_get_node_info(sbi, dn.nid, &ni); + ret = f2fs_get_node_info(sbi, dn.nid, &ni, false); if (ret) { f2fs_put_dnode(&dn); return ret; diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 05baf72dce70..9ea94d01284d 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -941,7 +941,7 @@ next_step: continue; } - if (f2fs_get_node_info(sbi, nid, &ni)) { + if (f2fs_get_node_info(sbi, nid, &ni, false)) { f2fs_put_page(node_page, 1); continue; } @@ -1009,7 +1009,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, if (IS_ERR(node_page)) return false; - if (f2fs_get_node_info(sbi, nid, dni)) { + if (f2fs_get_node_info(sbi, nid, dni, false)) { f2fs_put_page(node_page, 1); return false; } @@ -1200,7 +1200,7 @@ static int move_data_block(struct inode *inode, block_t bidx, f2fs_wait_on_block_writeback(inode, dn.data_blkaddr); - err = f2fs_get_node_info(fio.sbi, dn.nid, &ni); + err = f2fs_get_node_info(fio.sbi, dn.nid, &ni, false); if (err) goto put_out; diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index 2311c76ffc37..a85eb4207d81 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -149,7 +149,7 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page) if (err) return err; - err = f2fs_get_node_info(fio.sbi, dn->nid, &ni); + err = f2fs_get_node_info(fio.sbi, dn->nid, &ni, false); if (err) { f2fs_truncate_data_blocks_range(dn, 1); f2fs_put_dnode(dn); @@ -804,7 +804,7 @@ int f2fs_inline_data_fiemap(struct inode *inode, ilen = start + len; ilen -= start; - err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni); + err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni, false); if (err) goto out; diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 1213f15ffd68..dbc4721ef121 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -868,7 +868,7 @@ void f2fs_handle_failed_inode(struct inode *inode) * so we can prevent losing this orphan when encoutering checkpoint * and following suddenly power-off. */ - err = f2fs_get_node_info(sbi, inode->i_ino, &ni); + err = f2fs_get_node_info(sbi, inode->i_ino, &ni, false); if (err) { set_sbi_flag(sbi, SBI_NEED_FSCK); f2fs_warn(sbi, "May loss orphan inode, run fsck to fix."); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 52a030e8181d..0bbac1043d93 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -541,7 +541,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) } int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, - struct node_info *ni) + struct node_info *ni, bool checkpoint_context) { struct f2fs_nm_info *nm_i = NM_I(sbi); struct curseg_info *curseg = CURSEG_I(sbi, CURSEG_HOT_DATA); @@ -574,9 +574,10 @@ retry: * nat_tree_lock. Therefore, we should retry, if we failed to grab here * while not bothering checkpoint. */ - if (!rwsem_is_locked(&sbi->cp_global_sem)) { + if (!rwsem_is_locked(&sbi->cp_global_sem) || checkpoint_context) { down_read(&curseg->journal_rwsem); - } else if (!down_read_trylock(&curseg->journal_rwsem)) { + } else if (rwsem_is_contended(&nm_i->nat_tree_lock) || + !down_read_trylock(&curseg->journal_rwsem)) { up_read(&nm_i->nat_tree_lock); goto retry; } @@ -869,7 +870,7 @@ static int truncate_node(struct dnode_of_data *dn) int err; pgoff_t index; - err = f2fs_get_node_info(sbi, dn->nid, &ni); + err = f2fs_get_node_info(sbi, dn->nid, &ni, false); if (err) return err; @@ -1268,7 +1269,7 @@ struct page *f2fs_new_node_page(struct dnode_of_data *dn, unsigned int ofs) goto fail; #ifdef CONFIG_F2FS_CHECK_FS - err = f2fs_get_node_info(sbi, dn->nid, &new_ni); + err = f2fs_get_node_info(sbi, dn->nid, &new_ni, false); if (err) { dec_valid_node_count(sbi, dn->inode, !ofs); goto fail; @@ -1330,7 +1331,7 @@ static int read_node_page(struct page *page, int op_flags) return LOCKED_PAGE; } - err = f2fs_get_node_info(sbi, page->index, &ni); + err = f2fs_get_node_info(sbi, page->index, &ni, false); if (err) return err; @@ -1583,7 +1584,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, nid = nid_of_node(page); f2fs_bug_on(sbi, page->index != nid); - if (f2fs_get_node_info(sbi, nid, &ni)) + if (f2fs_get_node_info(sbi, nid, &ni, !do_balance)) goto redirty_out; if (wbc->for_reclaim) { @@ -2666,7 +2667,7 @@ int f2fs_recover_xattr_data(struct inode *inode, struct page *page) goto recover_xnid; /* 1: invalidate the previous xattr nid */ - err = f2fs_get_node_info(sbi, prev_xnid, &ni); + err = f2fs_get_node_info(sbi, prev_xnid, &ni, false); if (err) return err; @@ -2706,7 +2707,7 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct page *page) struct page *ipage; int err; - err = f2fs_get_node_info(sbi, ino, &old_ni); + err = f2fs_get_node_info(sbi, ino, &old_ni, false); if (err) return err; diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 695eacfe776c..319ac27c624c 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -594,7 +594,7 @@ retry_dn: f2fs_wait_on_page_writeback(dn.node_page, NODE, true, true); - err = f2fs_get_node_info(sbi, dn.nid, &ni); + err = f2fs_get_node_info(sbi, dn.nid, &ni, false); if (err) goto err; diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 95bfcff5ce8c..719983364197 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -251,7 +251,7 @@ retry: goto next; } - err = f2fs_get_node_info(sbi, dn.nid, &ni); + err = f2fs_get_node_info(sbi, dn.nid, &ni, false); if (err) { f2fs_put_dnode(&dn); return err; From 7e6f112bebea24927f411a52c2da95f448777e27 Mon Sep 17 00:00:00 2001 From: Tim Murray Date: Fri, 7 Jan 2022 12:48:44 -0800 Subject: [PATCH 47/52] FROMGIT: f2fs: move f2fs to use reader-unfair rwsems f2fs rw_semaphores work better if writers can starve readers, especially for the checkpoint thread, because writers are strictly more important than reader threads. This prevents significant priority inversion between low-priority readers that blocked while trying to acquire the read lock and a second acquisition of the write lock that might be blocking high priority work. Bug: 214413989 Signed-off-by: Tim Murray Signed-off-by: Jaegeuk Kim (cherry picked from commit e4544b63a7ee49e7fbebf35ece0a6acd3b9617ae git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs.git dev) Change-Id: Ia0eb86447488c5ba9845a6b2eb98652200e08281 --- fs/f2fs/checkpoint.c | 35 +++++----- fs/f2fs/compress.c | 6 +- fs/f2fs/data.c | 72 ++++++++++----------- fs/f2fs/dir.c | 12 ++-- fs/f2fs/f2fs.h | 112 +++++++++++++++++++++++++------- fs/f2fs/file.c | 150 +++++++++++++++++++++---------------------- fs/f2fs/gc.c | 46 ++++++------- fs/f2fs/inline.c | 4 +- fs/f2fs/namei.c | 34 +++++----- fs/f2fs/node.c | 76 +++++++++++----------- fs/f2fs/recovery.c | 4 +- fs/f2fs/segment.c | 42 ++++++------ fs/f2fs/super.c | 58 ++++++++--------- fs/f2fs/sysfs.c | 4 +- fs/f2fs/verity.c | 4 +- fs/f2fs/xattr.c | 12 ++-- 16 files changed, 370 insertions(+), 301 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 4689f3e8a703..3390b8dcd634 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -350,13 +350,13 @@ static int f2fs_write_meta_pages(struct address_space *mapping, goto skip_write; /* if locked failed, cp will flush dirty pages instead */ - if (!down_write_trylock(&sbi->cp_global_sem)) + if (!f2fs_down_write_trylock(&sbi->cp_global_sem)) goto skip_write; trace_f2fs_writepages(mapping->host, wbc, META); diff = nr_pages_to_write(sbi, META, wbc); written = f2fs_sync_meta_pages(sbi, META, wbc->nr_to_write, FS_META_IO); - up_write(&sbi->cp_global_sem); + f2fs_up_write(&sbi->cp_global_sem); wbc->nr_to_write = max((long)0, wbc->nr_to_write - written - diff); return 0; @@ -1148,7 +1148,8 @@ static bool __need_flush_quota(struct f2fs_sb_info *sbi) if (!is_journalled_quota(sbi)) return false; - down_write(&sbi->quota_sem); + if (!f2fs_down_write_trylock(&sbi->quota_sem)) + return true; if (is_sbi_flag_set(sbi, SBI_QUOTA_SKIP_FLUSH)) { ret = false; } else if (is_sbi_flag_set(sbi, SBI_QUOTA_NEED_REPAIR)) { @@ -1159,7 +1160,7 @@ static bool __need_flush_quota(struct f2fs_sb_info *sbi) } else if (get_pages(sbi, F2FS_DIRTY_QDATA)) { ret = true; } - up_write(&sbi->quota_sem); + f2fs_up_write(&sbi->quota_sem); return ret; } @@ -1216,10 +1217,10 @@ retry_flush_dents: * POR: we should ensure that there are no dirty node pages * until finishing nat/sit flush. inode->i_blocks can be updated. */ - down_write(&sbi->node_change); + f2fs_down_write(&sbi->node_change); if (get_pages(sbi, F2FS_DIRTY_IMETA)) { - up_write(&sbi->node_change); + f2fs_up_write(&sbi->node_change); f2fs_unlock_all(sbi); err = f2fs_sync_inode_meta(sbi); if (err) @@ -1229,15 +1230,15 @@ retry_flush_dents: } retry_flush_nodes: - down_write(&sbi->node_write); + f2fs_down_write(&sbi->node_write); if (get_pages(sbi, F2FS_DIRTY_NODES)) { - up_write(&sbi->node_write); + f2fs_up_write(&sbi->node_write); atomic_inc(&sbi->wb_sync_req[NODE]); err = f2fs_sync_node_pages(sbi, &wbc, false, FS_CP_NODE_IO); atomic_dec(&sbi->wb_sync_req[NODE]); if (err) { - up_write(&sbi->node_change); + f2fs_up_write(&sbi->node_change); f2fs_unlock_all(sbi); return err; } @@ -1250,13 +1251,13 @@ retry_flush_nodes: * dirty node blocks and some checkpoint values by block allocation. */ __prepare_cp_block(sbi); - up_write(&sbi->node_change); + f2fs_up_write(&sbi->node_change); return err; } static void unblock_operations(struct f2fs_sb_info *sbi) { - up_write(&sbi->node_write); + f2fs_up_write(&sbi->node_write); f2fs_unlock_all(sbi); } @@ -1591,7 +1592,7 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) f2fs_warn(sbi, "Start checkpoint disabled!"); } if (cpc->reason != CP_RESIZE) - down_write(&sbi->cp_global_sem); + f2fs_down_write(&sbi->cp_global_sem); if (!is_sbi_flag_set(sbi, SBI_IS_DIRTY) && ((cpc->reason & CP_FASTBOOT) || (cpc->reason & CP_SYNC) || @@ -1666,7 +1667,7 @@ stop: trace_f2fs_write_checkpoint(sbi->sb, cpc->reason, "finish checkpoint"); out: if (cpc->reason != CP_RESIZE) - up_write(&sbi->cp_global_sem); + f2fs_up_write(&sbi->cp_global_sem); return err; } @@ -1714,9 +1715,9 @@ static int __write_checkpoint_sync(struct f2fs_sb_info *sbi) struct cp_control cpc = { .reason = CP_SYNC, }; int err; - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); err = f2fs_write_checkpoint(sbi, &cpc); - up_write(&sbi->gc_lock); + f2fs_up_write(&sbi->gc_lock); return err; } @@ -1804,9 +1805,9 @@ int f2fs_issue_checkpoint(struct f2fs_sb_info *sbi) if (!test_opt(sbi, MERGE_CHECKPOINT) || cpc.reason != CP_SYNC) { int ret; - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); ret = f2fs_write_checkpoint(sbi, &cpc); - up_write(&sbi->gc_lock); + f2fs_up_write(&sbi->gc_lock); return ret; } diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c index 2b6c20f2657b..5b0d8ae936d2 100644 --- a/fs/f2fs/compress.c +++ b/fs/f2fs/compress.c @@ -1203,7 +1203,7 @@ static int f2fs_write_compressed_pages(struct compress_ctx *cc, * checkpoint. This can only happen to quota writes which can cause * the below discard race condition. */ - down_read(&sbi->node_write); + f2fs_down_read(&sbi->node_write); } else if (!f2fs_trylock_op(sbi)) { goto out_free; } @@ -1320,7 +1320,7 @@ unlock_continue: f2fs_put_dnode(&dn); if (IS_NOQUOTA(inode)) - up_read(&sbi->node_write); + f2fs_up_read(&sbi->node_write); else f2fs_unlock_op(sbi); @@ -1346,7 +1346,7 @@ out_put_dnode: f2fs_put_dnode(&dn); out_unlock_op: if (IS_NOQUOTA(inode)) - up_read(&sbi->node_write); + f2fs_up_read(&sbi->node_write); else f2fs_unlock_op(sbi); out_free: diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index e3aa49971091..57fb77e57330 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -593,7 +593,7 @@ static void __f2fs_submit_merged_write(struct f2fs_sb_info *sbi, enum page_type btype = PAGE_TYPE_OF_BIO(type); struct f2fs_bio_info *io = sbi->write_io[btype] + temp; - down_write(&io->io_rwsem); + f2fs_down_write(&io->io_rwsem); /* change META to META_FLUSH in the checkpoint procedure */ if (type >= META_FLUSH) { @@ -604,7 +604,7 @@ static void __f2fs_submit_merged_write(struct f2fs_sb_info *sbi, io->fio.op_flags |= REQ_PREFLUSH | REQ_FUA; } __submit_merged_bio(io); - up_write(&io->io_rwsem); + f2fs_up_write(&io->io_rwsem); } static void __submit_merged_write_cond(struct f2fs_sb_info *sbi, @@ -619,9 +619,9 @@ static void __submit_merged_write_cond(struct f2fs_sb_info *sbi, enum page_type btype = PAGE_TYPE_OF_BIO(type); struct f2fs_bio_info *io = sbi->write_io[btype] + temp; - down_read(&io->io_rwsem); + f2fs_down_read(&io->io_rwsem); ret = __has_merged_page(io->bio, inode, page, ino); - up_read(&io->io_rwsem); + f2fs_up_read(&io->io_rwsem); } if (ret) __f2fs_submit_merged_write(sbi, type, temp); @@ -745,9 +745,9 @@ static void add_bio_entry(struct f2fs_sb_info *sbi, struct bio *bio, if (bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) f2fs_bug_on(sbi, 1); - down_write(&io->bio_list_lock); + f2fs_down_write(&io->bio_list_lock); list_add_tail(&be->list, &io->bio_list); - up_write(&io->bio_list_lock); + f2fs_up_write(&io->bio_list_lock); } static void del_bio_entry(struct bio_entry *be) @@ -769,7 +769,7 @@ static int add_ipu_page(struct f2fs_io_info *fio, struct bio **bio, struct list_head *head = &io->bio_list; struct bio_entry *be; - down_write(&io->bio_list_lock); + f2fs_down_write(&io->bio_list_lock); list_for_each_entry(be, head, list) { if (be->bio != *bio) continue; @@ -793,7 +793,7 @@ static int add_ipu_page(struct f2fs_io_info *fio, struct bio **bio, __submit_bio(sbi, *bio, DATA); break; } - up_write(&io->bio_list_lock); + f2fs_up_write(&io->bio_list_lock); } if (ret) { @@ -819,7 +819,7 @@ void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi, if (list_empty(head)) continue; - down_read(&io->bio_list_lock); + f2fs_down_read(&io->bio_list_lock); list_for_each_entry(be, head, list) { if (target) found = (target == be->bio); @@ -829,14 +829,14 @@ void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi, if (found) break; } - up_read(&io->bio_list_lock); + f2fs_up_read(&io->bio_list_lock); if (!found) continue; found = false; - down_write(&io->bio_list_lock); + f2fs_down_write(&io->bio_list_lock); list_for_each_entry(be, head, list) { if (target) found = (target == be->bio); @@ -849,7 +849,7 @@ void f2fs_submit_merged_ipu_write(struct f2fs_sb_info *sbi, break; } } - up_write(&io->bio_list_lock); + f2fs_up_write(&io->bio_list_lock); } if (found) @@ -909,7 +909,7 @@ void f2fs_submit_page_write(struct f2fs_io_info *fio) f2fs_bug_on(sbi, is_read_io(fio->op)); - down_write(&io->io_rwsem); + f2fs_down_write(&io->io_rwsem); next: if (fio->in_list) { spin_lock(&io->io_lock); @@ -976,7 +976,7 @@ out: if (is_sbi_flag_set(sbi, SBI_IS_SHUTDOWN) || !f2fs_is_checkpoint_ready(sbi)) __submit_merged_bio(io); - up_write(&io->io_rwsem); + f2fs_up_write(&io->io_rwsem); } static struct bio *f2fs_grab_read_bio(struct inode *inode, block_t blkaddr, @@ -1437,9 +1437,9 @@ void f2fs_do_map_lock(struct f2fs_sb_info *sbi, int flag, bool lock) { if (flag == F2FS_GET_BLOCK_PRE_AIO) { if (lock) - down_read(&sbi->node_change); + f2fs_down_read(&sbi->node_change); else - up_read(&sbi->node_change); + f2fs_up_read(&sbi->node_change); } else { if (lock) f2fs_lock_op(sbi); @@ -2768,13 +2768,13 @@ write: * the below discard race condition. */ if (IS_NOQUOTA(inode)) - down_read(&sbi->node_write); + f2fs_down_read(&sbi->node_write); fio.need_lock = LOCK_DONE; err = f2fs_do_write_data_page(&fio); if (IS_NOQUOTA(inode)) - up_read(&sbi->node_write); + f2fs_up_read(&sbi->node_write); goto done; } @@ -3232,14 +3232,14 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to) /* In the fs-verity case, f2fs_end_enable_verity() does the truncate */ if (to > i_size && !f2fs_verity_in_progress(inode)) { - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); truncate_pagecache(inode, i_size); f2fs_truncate_blocks(inode, i_size, true); - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); } } @@ -3646,21 +3646,21 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) iocb->ki_hint = WRITE_LIFE_NOT_SET; if (iocb->ki_flags & IOCB_NOWAIT) { - if (!down_read_trylock(&fi->i_gc_rwsem[rw])) { + if (!f2fs_down_read_trylock(&fi->i_gc_rwsem[rw])) { iocb->ki_hint = hint; err = -EAGAIN; goto out; } - if (do_opu && !down_read_trylock(&fi->i_gc_rwsem[READ])) { - up_read(&fi->i_gc_rwsem[rw]); + if (do_opu && !f2fs_down_read_trylock(&fi->i_gc_rwsem[READ])) { + f2fs_up_read(&fi->i_gc_rwsem[rw]); iocb->ki_hint = hint; err = -EAGAIN; goto out; } } else { - down_read(&fi->i_gc_rwsem[rw]); + f2fs_down_read(&fi->i_gc_rwsem[rw]); if (do_opu) - down_read(&fi->i_gc_rwsem[READ]); + f2fs_down_read(&fi->i_gc_rwsem[READ]); } err = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, @@ -3670,9 +3670,9 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter) DIO_SKIP_HOLES); if (do_opu) - up_read(&fi->i_gc_rwsem[READ]); + f2fs_up_read(&fi->i_gc_rwsem[READ]); - up_read(&fi->i_gc_rwsem[rw]); + f2fs_up_read(&fi->i_gc_rwsem[rw]); if (rw == WRITE) { if (whint_mode == WHINT_MODE_OFF) @@ -3944,13 +3944,13 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk, unsigned int end_sec = secidx + blkcnt / blk_per_sec; int ret = 0; - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); set_inode_flag(inode, FI_ALIGNED_WRITE); for (; secidx < end_sec; secidx++) { - down_write(&sbi->pin_sem); + f2fs_down_write(&sbi->pin_sem); f2fs_lock_op(sbi); f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false); @@ -3964,7 +3964,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk, page = f2fs_get_lock_data_page(inode, blkidx, true); if (IS_ERR(page)) { - up_write(&sbi->pin_sem); + f2fs_up_write(&sbi->pin_sem); ret = PTR_ERR(page); goto done; } @@ -3977,7 +3977,7 @@ static int f2fs_migrate_blocks(struct inode *inode, block_t start_blk, ret = filemap_fdatawrite(inode->i_mapping); - up_write(&sbi->pin_sem); + f2fs_up_write(&sbi->pin_sem); if (ret) break; @@ -3987,8 +3987,8 @@ done: clear_inode_flag(inode, FI_DO_DEFRAG); clear_inode_flag(inode, FI_ALIGNED_WRITE); - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); return ret; } diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 032ae4535ed7..9ee895af75e4 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -768,7 +768,7 @@ add_dentry: f2fs_wait_on_page_writeback(dentry_page, DATA, true, true); if (inode) { - down_write(&F2FS_I(inode)->i_sem); + f2fs_down_write(&F2FS_I(inode)->i_sem); page = f2fs_init_inode_metadata(inode, dir, fname, NULL); if (IS_ERR(page)) { err = PTR_ERR(page); @@ -795,7 +795,7 @@ add_dentry: f2fs_update_parent_metadata(dir, inode, current_depth); fail: if (inode) - up_write(&F2FS_I(inode)->i_sem); + f2fs_up_write(&F2FS_I(inode)->i_sem); f2fs_put_page(dentry_page, 1); @@ -860,7 +860,7 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode *dir) struct page *page; int err = 0; - down_write(&F2FS_I(inode)->i_sem); + f2fs_down_write(&F2FS_I(inode)->i_sem); page = f2fs_init_inode_metadata(inode, dir, NULL, NULL); if (IS_ERR(page)) { err = PTR_ERR(page); @@ -871,7 +871,7 @@ int f2fs_do_tmpfile(struct inode *inode, struct inode *dir) clear_inode_flag(inode, FI_NEW_INODE); f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); fail: - up_write(&F2FS_I(inode)->i_sem); + f2fs_up_write(&F2FS_I(inode)->i_sem); return err; } @@ -879,7 +879,7 @@ void f2fs_drop_nlink(struct inode *dir, struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(dir); - down_write(&F2FS_I(inode)->i_sem); + f2fs_down_write(&F2FS_I(inode)->i_sem); if (S_ISDIR(inode->i_mode)) f2fs_i_links_write(dir, false); @@ -890,7 +890,7 @@ void f2fs_drop_nlink(struct inode *dir, struct inode *inode) f2fs_i_links_write(inode, false); f2fs_i_size_write(inode, 0); } - up_write(&F2FS_I(inode)->i_sem); + f2fs_up_write(&F2FS_I(inode)->i_sem); if (inode->i_nlink == 0) f2fs_add_orphan_inode(inode); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 1b105ba0e153..ae06162e6e31 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -117,6 +117,18 @@ typedef u32 nid_t; #define COMPRESS_EXT_NUM 16 +/* + * An implementation of an rwsem that is explicitly unfair to readers. This + * prevents priority inversion when a low-priority reader acquires the read lock + * while sleeping on the write lock but the write lock is needed by + * higher-priority clients. + */ + +struct f2fs_rwsem { + struct rw_semaphore internal_rwsem; + wait_queue_head_t read_waiters; +}; + struct f2fs_mount_info { unsigned int opt; int write_io_size_bits; /* Write IO size bits */ @@ -726,7 +738,7 @@ struct f2fs_inode_info { /* Use below internally in f2fs*/ unsigned long flags[BITS_TO_LONGS(FI_MAX)]; /* use to pass per-file flags */ - struct rw_semaphore i_sem; /* protect fi info */ + struct f2fs_rwsem i_sem; /* protect fi info */ atomic_t dirty_pages; /* # of dirty pages */ f2fs_hash_t chash; /* hash value of given file name */ unsigned int clevel; /* maximum level of given file name */ @@ -751,9 +763,9 @@ struct f2fs_inode_info { struct extent_tree *extent_tree; /* cached extent_tree entry */ /* avoid racing between foreground op and gc */ - struct rw_semaphore i_gc_rwsem[2]; - struct rw_semaphore i_mmap_sem; - struct rw_semaphore i_xattr_sem; /* avoid racing between reading and changing EAs */ + struct f2fs_rwsem i_gc_rwsem[2]; + struct f2fs_rwsem i_mmap_sem; + struct f2fs_rwsem i_xattr_sem; /* avoid racing between reading and changing EAs */ int i_extra_isize; /* size of extra space located in i_addr */ kprojid_t i_projid; /* id for project quota */ @@ -870,7 +882,7 @@ struct f2fs_nm_info { /* NAT cache management */ struct radix_tree_root nat_root;/* root of the nat entry cache */ struct radix_tree_root nat_set_root;/* root of the nat set cache */ - struct rw_semaphore nat_tree_lock; /* protect nat entry tree */ + struct f2fs_rwsem nat_tree_lock; /* protect nat entry tree */ struct list_head nat_entries; /* cached nat entry list (clean) */ spinlock_t nat_list_lock; /* protect clean nat entry list */ unsigned int nat_cnt[MAX_NAT_STATE]; /* the # of cached nat entries */ @@ -983,7 +995,7 @@ struct f2fs_sm_info { struct dirty_seglist_info *dirty_info; /* dirty segment information */ struct curseg_info *curseg_array; /* active segment information */ - struct rw_semaphore curseg_lock; /* for preventing curseg change */ + struct f2fs_rwsem curseg_lock; /* for preventing curseg change */ block_t seg0_blkaddr; /* block address of 0'th segment */ block_t main_blkaddr; /* start block address of main area */ @@ -1166,11 +1178,11 @@ struct f2fs_bio_info { struct bio *bio; /* bios to merge */ sector_t last_block_in_bio; /* last block number */ struct f2fs_io_info fio; /* store buffered io info. */ - struct rw_semaphore io_rwsem; /* blocking op for bio */ + struct f2fs_rwsem io_rwsem; /* blocking op for bio */ spinlock_t io_lock; /* serialize DATA/NODE IOs */ struct list_head io_list; /* track fios */ struct list_head bio_list; /* bio entry list head */ - struct rw_semaphore bio_list_lock; /* lock to protect bio entry list */ + struct f2fs_rwsem bio_list_lock; /* lock to protect bio entry list */ }; #define FDEV(i) (sbi->devs[i]) @@ -1527,7 +1539,7 @@ struct f2fs_sb_info { struct super_block *sb; /* pointer to VFS super block */ struct proc_dir_entry *s_proc; /* proc entry */ struct f2fs_super_block *raw_super; /* raw super block pointer */ - struct rw_semaphore sb_lock; /* lock for raw super block */ + struct f2fs_rwsem sb_lock; /* lock for raw super block */ int valid_super_block; /* valid super block no */ unsigned long s_flag; /* flags for sbi */ struct mutex writepages; /* mutex for writepages() */ @@ -1547,7 +1559,7 @@ struct f2fs_sb_info { /* for bio operations */ struct f2fs_bio_info *write_io[NR_PAGE_TYPE]; /* for write bios */ /* keep migration IO order for LFS mode */ - struct rw_semaphore io_order_lock; + struct f2fs_rwsem io_order_lock; mempool_t *write_io_dummy; /* Dummy pages */ /* for checkpoint */ @@ -1555,10 +1567,10 @@ struct f2fs_sb_info { int cur_cp_pack; /* remain current cp pack */ spinlock_t cp_lock; /* for flag in ckpt */ struct inode *meta_inode; /* cache meta blocks */ - struct rw_semaphore cp_global_sem; /* checkpoint procedure lock */ - struct rw_semaphore cp_rwsem; /* blocking FS operations */ - struct rw_semaphore node_write; /* locking node writes */ - struct rw_semaphore node_change; /* locking node change */ + struct f2fs_rwsem cp_global_sem; /* checkpoint procedure lock */ + struct f2fs_rwsem cp_rwsem; /* blocking FS operations */ + struct f2fs_rwsem node_write; /* locking node writes */ + struct f2fs_rwsem node_change; /* locking node change */ wait_queue_head_t cp_wait; unsigned long last_time[MAX_TIME]; /* to store time in jiffies */ long interval_time[MAX_TIME]; /* to store thresholds */ @@ -1618,7 +1630,7 @@ struct f2fs_sb_info { block_t unusable_block_count; /* # of blocks saved by last cp */ unsigned int nquota_files; /* # of quota sysfile */ - struct rw_semaphore quota_sem; /* blocking cp for flags */ + struct f2fs_rwsem quota_sem; /* blocking cp for flags */ /* # of pages, see count_type */ atomic_t nr_pages[NR_COUNT_TYPE]; @@ -1634,7 +1646,7 @@ struct f2fs_sb_info { struct f2fs_mount_info mount_opt; /* mount options */ /* for cleaning operations */ - struct rw_semaphore gc_lock; /* + struct f2fs_rwsem gc_lock; /* * semaphore for GC, avoid * race between GC and GC or CP */ @@ -1651,7 +1663,7 @@ struct f2fs_sb_info { /* threshold for gc trials on pinned files */ u64 gc_pin_file_threshold; - struct rw_semaphore pin_sem; + struct f2fs_rwsem pin_sem; /* maximum # of trials to find a victim segment for SSR and GC */ unsigned int max_victim_search; @@ -2068,29 +2080,85 @@ static inline bool enabled_nat_bits(struct f2fs_sb_info *sbi, return (cpc) ? (cpc->reason & CP_UMOUNT) && set : set; } +static inline void init_f2fs_rwsem(struct f2fs_rwsem *sem) +{ + init_rwsem(&sem->internal_rwsem); + init_waitqueue_head(&sem->read_waiters); +} + +static inline int f2fs_rwsem_is_locked(struct f2fs_rwsem *sem) +{ + return rwsem_is_locked(&sem->internal_rwsem); +} + +static inline int f2fs_rwsem_is_contended(struct f2fs_rwsem *sem) +{ + return rwsem_is_contended(&sem->internal_rwsem); +} + +static inline void f2fs_down_read(struct f2fs_rwsem *sem) +{ + wait_event(sem->read_waiters, down_read_trylock(&sem->internal_rwsem)); +} + +static inline int f2fs_down_read_trylock(struct f2fs_rwsem *sem) +{ + return down_read_trylock(&sem->internal_rwsem); +} + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +static inline void f2fs_down_read_nested(struct f2fs_rwsem *sem, int subclass) +{ + down_read_nested(&sem->internal_rwsem, subclass); +} +#else +#define f2fs_down_read_nested(sem, subclass) f2fs_down_read(sem) +#endif + +static inline void f2fs_up_read(struct f2fs_rwsem *sem) +{ + up_read(&sem->internal_rwsem); +} + +static inline void f2fs_down_write(struct f2fs_rwsem *sem) +{ + down_write(&sem->internal_rwsem); +} + +static inline int f2fs_down_write_trylock(struct f2fs_rwsem *sem) +{ + return down_write_trylock(&sem->internal_rwsem); +} + +static inline void f2fs_up_write(struct f2fs_rwsem *sem) +{ + up_write(&sem->internal_rwsem); + wake_up_all(&sem->read_waiters); +} + static inline void f2fs_lock_op(struct f2fs_sb_info *sbi) { - down_read(&sbi->cp_rwsem); + f2fs_down_read(&sbi->cp_rwsem); } static inline int f2fs_trylock_op(struct f2fs_sb_info *sbi) { - return down_read_trylock(&sbi->cp_rwsem); + return f2fs_down_read_trylock(&sbi->cp_rwsem); } static inline void f2fs_unlock_op(struct f2fs_sb_info *sbi) { - up_read(&sbi->cp_rwsem); + f2fs_up_read(&sbi->cp_rwsem); } static inline void f2fs_lock_all(struct f2fs_sb_info *sbi) { - down_write(&sbi->cp_rwsem); + f2fs_down_write(&sbi->cp_rwsem); } static inline void f2fs_unlock_all(struct f2fs_sb_info *sbi) { - up_write(&sbi->cp_rwsem); + f2fs_up_write(&sbi->cp_rwsem); } static inline int __get_cp_reason(struct f2fs_sb_info *sbi) diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 720952b5e3df..19b568d61d62 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -37,9 +37,9 @@ static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) struct inode *inode = file_inode(vmf->vma->vm_file); vm_fault_t ret; - down_read(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_read(&F2FS_I(inode)->i_mmap_sem); ret = filemap_fault(vmf); - up_read(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_read(&F2FS_I(inode)->i_mmap_sem); if (!ret) f2fs_update_iostat(F2FS_I_SB(inode), APP_MAPPED_READ_IO, @@ -100,7 +100,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) f2fs_bug_on(sbi, f2fs_has_inline_data(inode)); file_update_time(vmf->vma->vm_file); - down_read(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_read(&F2FS_I(inode)->i_mmap_sem); lock_page(page); if (unlikely(page->mapping != inode->i_mapping || page_offset(page) > i_size_read(inode) || @@ -158,7 +158,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf) trace_f2fs_vm_page_mkwrite(page, DATA); out_sem: - up_read(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_read(&F2FS_I(inode)->i_mmap_sem); sb_end_pagefault(inode->i_sb); err: @@ -239,13 +239,13 @@ static void try_to_fix_pino(struct inode *inode) struct f2fs_inode_info *fi = F2FS_I(inode); nid_t pino; - down_write(&fi->i_sem); + f2fs_down_write(&fi->i_sem); if (file_wrong_pino(inode) && inode->i_nlink == 1 && get_parent_ino(inode, &pino)) { f2fs_i_pino_write(inode, pino); file_got_pino(inode); } - up_write(&fi->i_sem); + f2fs_up_write(&fi->i_sem); } static int f2fs_do_sync_file(struct file *file, loff_t start, loff_t end, @@ -308,9 +308,9 @@ go_write: * Both of fdatasync() and fsync() are able to be recovered from * sudden-power-off. */ - down_read(&F2FS_I(inode)->i_sem); + f2fs_down_read(&F2FS_I(inode)->i_sem); cp_reason = need_do_checkpoint(inode); - up_read(&F2FS_I(inode)->i_sem); + f2fs_up_read(&F2FS_I(inode)->i_sem); if (cp_reason) { /* all the dirty node pages should be flushed for POR */ @@ -938,8 +938,8 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) return err; } - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); truncate_setsize(inode, attr->ia_size); @@ -949,8 +949,8 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) * do not trim all blocks after i_size if target size is * larger than i_size. */ - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); if (err) return err; @@ -1090,8 +1090,8 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) blk_start = (loff_t)pg_start << PAGE_SHIFT; blk_end = (loff_t)pg_end << PAGE_SHIFT; - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); truncate_pagecache_range(inode, blk_start, blk_end - 1); @@ -1099,8 +1099,8 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) ret = f2fs_truncate_hole(inode, pg_start, pg_end); f2fs_unlock_op(sbi); - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); } } @@ -1333,8 +1333,8 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len) f2fs_balance_fs(sbi, true); /* avoid gc operation during block exchange */ - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); f2fs_lock_op(sbi); f2fs_drop_extent_tree(inode); @@ -1342,8 +1342,8 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len) ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true); f2fs_unlock_op(sbi); - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); return ret; } @@ -1373,13 +1373,13 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len) return ret; /* write out all moved pages, if possible */ - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); truncate_pagecache(inode, offset); new_size = i_size_read(inode) - len; ret = f2fs_truncate_blocks(inode, new_size, true); - up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); if (!ret) f2fs_i_size_write(inode, new_size); return ret; @@ -1478,8 +1478,8 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, unsigned int end_offset; pgoff_t end; - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); truncate_pagecache_range(inode, (loff_t)index << PAGE_SHIFT, @@ -1491,8 +1491,8 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, ret = f2fs_get_dnode_of_data(&dn, index, ALLOC_NODE); if (ret) { f2fs_unlock_op(sbi); - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); goto out; } @@ -1503,8 +1503,8 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len, f2fs_put_dnode(&dn); f2fs_unlock_op(sbi); - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); f2fs_balance_fs(sbi, dn.node_changed); @@ -1560,9 +1560,9 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) f2fs_balance_fs(sbi, true); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); ret = f2fs_truncate_blocks(inode, i_size_read(inode), true); - up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); if (ret) return ret; @@ -1577,8 +1577,8 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); /* avoid gc operation during block exchange */ - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); truncate_pagecache(inode, offset); while (!ret && idx > pg_start) { @@ -1594,14 +1594,14 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len) idx + delta, nr, false); f2fs_unlock_op(sbi); } - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); /* write out all moved pages, if possible */ - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); truncate_pagecache(inode, offset); - up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); if (!ret) f2fs_i_size_write(inode, new_size); @@ -1651,13 +1651,13 @@ static int expand_inode_data(struct inode *inode, loff_t offset, next_alloc: if (has_not_enough_free_secs(sbi, 0, GET_SEC_FROM_SEG(sbi, overprovision_segments(sbi)))) { - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); err = f2fs_gc(sbi, true, false, false, NULL_SEGNO); if (err && err != -ENODATA && err != -EAGAIN) goto out_err; } - down_write(&sbi->pin_sem); + f2fs_down_write(&sbi->pin_sem); f2fs_lock_op(sbi); f2fs_allocate_new_section(sbi, CURSEG_COLD_DATA_PINNED, false); @@ -1666,7 +1666,7 @@ next_alloc: map.m_seg_type = CURSEG_COLD_DATA_PINNED; err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO); - up_write(&sbi->pin_sem); + f2fs_up_write(&sbi->pin_sem); expanded += map.m_len; sec_len -= map.m_len; @@ -2050,7 +2050,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) if (ret) goto out; - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); /* * Should wait end_io to count F2FS_WB_CP_DATA correctly by @@ -2061,7 +2061,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) inode->i_ino, get_dirty_pages(inode)); ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX); if (ret) { - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); goto out; } @@ -2074,7 +2074,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp) /* add inode in inmem_list first and set atomic_file */ set_inode_flag(inode, FI_ATOMIC_FILE); clear_inode_flag(inode, FI_ATOMIC_REVOKE_REQUEST); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); F2FS_I(inode)->inmem_task = current; @@ -2381,7 +2381,7 @@ static int f2fs_ioc_get_encryption_pwsalt(struct file *filp, unsigned long arg) if (err) return err; - down_write(&sbi->sb_lock); + f2fs_down_write(&sbi->sb_lock); if (uuid_is_nonzero(sbi->raw_super->encrypt_pw_salt)) goto got_it; @@ -2400,7 +2400,7 @@ got_it: 16)) err = -EFAULT; out_err: - up_write(&sbi->sb_lock); + f2fs_up_write(&sbi->sb_lock); mnt_drop_write_file(filp); return err; } @@ -2477,12 +2477,12 @@ static int f2fs_ioc_gc(struct file *filp, unsigned long arg) return ret; if (!sync) { - if (!down_write_trylock(&sbi->gc_lock)) { + if (!f2fs_down_write_trylock(&sbi->gc_lock)) { ret = -EBUSY; goto out; } } else { - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); } ret = f2fs_gc(sbi, sync, true, false, NULL_SEGNO); @@ -2513,12 +2513,12 @@ static int __f2fs_ioc_gc_range(struct file *filp, struct f2fs_gc_range *range) do_more: if (!range->sync) { - if (!down_write_trylock(&sbi->gc_lock)) { + if (!f2fs_down_write_trylock(&sbi->gc_lock)) { ret = -EBUSY; goto out; } } else { - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); } ret = f2fs_gc(sbi, range->sync, true, false, @@ -2850,10 +2850,10 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in, f2fs_balance_fs(sbi, true); - down_write(&F2FS_I(src)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(src)->i_gc_rwsem[WRITE]); if (src != dst) { ret = -EBUSY; - if (!down_write_trylock(&F2FS_I(dst)->i_gc_rwsem[WRITE])) + if (!f2fs_down_write_trylock(&F2FS_I(dst)->i_gc_rwsem[WRITE])) goto out_src; } @@ -2871,9 +2871,9 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in, f2fs_unlock_op(sbi); if (src != dst) - up_write(&F2FS_I(dst)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(dst)->i_gc_rwsem[WRITE]); out_src: - up_write(&F2FS_I(src)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(src)->i_gc_rwsem[WRITE]); out_unlock: if (src != dst) inode_unlock(dst); @@ -2968,7 +2968,7 @@ static int f2fs_ioc_flush_device(struct file *filp, unsigned long arg) end_segno = min(start_segno + range.segments, dev_end_segno); while (start_segno < end_segno) { - if (!down_write_trylock(&sbi->gc_lock)) { + if (!f2fs_down_write_trylock(&sbi->gc_lock)) { ret = -EBUSY; goto out; } @@ -3314,9 +3314,9 @@ int f2fs_precache_extents(struct inode *inode) while (map.m_lblk < end) { map.m_len = end - map.m_lblk; - down_write(&fi->i_gc_rwsem[WRITE]); + f2fs_down_write(&fi->i_gc_rwsem[WRITE]); err = f2fs_map_blocks(inode, &map, 0, F2FS_GET_BLOCK_PRECACHE); - up_write(&fi->i_gc_rwsem[WRITE]); + f2fs_up_write(&fi->i_gc_rwsem[WRITE]); if (err) return err; @@ -3393,11 +3393,11 @@ static int f2fs_ioc_getfslabel(struct file *filp, unsigned long arg) if (!vbuf) return -ENOMEM; - down_read(&sbi->sb_lock); + f2fs_down_read(&sbi->sb_lock); count = utf16s_to_utf8s(sbi->raw_super->volume_name, ARRAY_SIZE(sbi->raw_super->volume_name), UTF16_LITTLE_ENDIAN, vbuf, MAX_VOLUME_NAME); - up_read(&sbi->sb_lock); + f2fs_up_read(&sbi->sb_lock); if (copy_to_user((char __user *)arg, vbuf, min(FSLABEL_MAX, count))) @@ -3425,7 +3425,7 @@ static int f2fs_ioc_setfslabel(struct file *filp, unsigned long arg) if (err) goto out; - down_write(&sbi->sb_lock); + f2fs_down_write(&sbi->sb_lock); memset(sbi->raw_super->volume_name, 0, sizeof(sbi->raw_super->volume_name)); @@ -3435,7 +3435,7 @@ static int f2fs_ioc_setfslabel(struct file *filp, unsigned long arg) err = f2fs_commit_super(sbi, false); - up_write(&sbi->sb_lock); + f2fs_up_write(&sbi->sb_lock); mnt_drop_write_file(filp); out: @@ -3561,8 +3561,8 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) if (!atomic_read(&F2FS_I(inode)->i_compr_blocks)) goto out; - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); @@ -3597,8 +3597,8 @@ static int f2fs_release_compress_blocks(struct file *filp, unsigned long arg) released_blocks += ret; } - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); out: inode_unlock(inode); @@ -3714,8 +3714,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) goto unlock_inode; } - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); last_idx = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE); @@ -3750,8 +3750,8 @@ static int f2fs_reserve_compress_blocks(struct file *filp, unsigned long arg) reserved_blocks += ret; } - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); if (ret >= 0) { clear_inode_flag(inode, FI_COMPRESS_RELEASED); @@ -3869,8 +3869,8 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg) if (ret) goto err; - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); ret = filemap_write_and_wait_range(mapping, range.start, to_end ? LLONG_MAX : end_addr - 1); @@ -3957,8 +3957,8 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg) ret = f2fs_secure_erase(prev_bdev, inode, prev_index, prev_block, len, range.flags); out: - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); err: inode_unlock(inode); file_end_write(filp); @@ -4442,11 +4442,11 @@ write: /* if we couldn't write data, we should deallocate blocks. */ if (preallocated && i_size_read(inode) < target_size) { - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); - down_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_mmap_sem); f2fs_truncate(inode); - up_write(&F2FS_I(inode)->i_mmap_sem); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_mmap_sem); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); } if (ret > 0) diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 9ea94d01284d..3246f6cc397e 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -91,21 +91,21 @@ static int gc_thread_func(void *data) */ if (sbi->gc_mode == GC_URGENT_HIGH) { wait_ms = gc_th->urgent_sleep_time; - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); goto do_gc; } if (foreground) { - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); goto do_gc; - } else if (!down_write_trylock(&sbi->gc_lock)) { + } else if (!f2fs_down_write_trylock(&sbi->gc_lock)) { stat_other_skip_bggc_count(sbi); goto next; } if (!is_idle(sbi, GC_TIME)) { increase_sleep_time(gc_th, &wait_ms); - up_write(&sbi->gc_lock); + f2fs_up_write(&sbi->gc_lock); stat_io_skip_bggc_count(sbi); goto next; } @@ -1209,7 +1209,7 @@ static int move_data_block(struct inode *inode, block_t bidx, fio.new_blkaddr = fio.old_blkaddr = dn.data_blkaddr; if (lfs_mode) - down_write(&fio.sbi->io_order_lock); + f2fs_down_write(&fio.sbi->io_order_lock); mpage = f2fs_grab_cache_page(META_MAPPING(fio.sbi), fio.old_blkaddr, false); @@ -1295,7 +1295,7 @@ recover_block: true, true, true); up_out: if (lfs_mode) - up_write(&fio.sbi->io_order_lock); + f2fs_up_write(&fio.sbi->io_order_lock); put_out: f2fs_put_dnode(&dn); out: @@ -1454,7 +1454,7 @@ next_step: if (IS_ERR(inode) || is_bad_inode(inode)) continue; - if (!down_write_trylock( + if (!f2fs_down_write_trylock( &F2FS_I(inode)->i_gc_rwsem[WRITE])) { iput(inode); sbi->skipped_gc_rwsem++; @@ -1467,7 +1467,7 @@ next_step: if (f2fs_post_read_required(inode)) { int err = ra_data_block(inode, start_bidx); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); if (err) { iput(inode); continue; @@ -1478,7 +1478,7 @@ next_step: data_page = f2fs_get_read_data_page(inode, start_bidx, REQ_RAHEAD, true); - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); if (IS_ERR(data_page)) { iput(inode); continue; @@ -1497,14 +1497,14 @@ next_step: int err; if (S_ISREG(inode->i_mode)) { - if (!down_write_trylock(&fi->i_gc_rwsem[READ])) { + if (!f2fs_down_write_trylock(&fi->i_gc_rwsem[READ])) { sbi->skipped_gc_rwsem++; continue; } - if (!down_write_trylock( + if (!f2fs_down_write_trylock( &fi->i_gc_rwsem[WRITE])) { sbi->skipped_gc_rwsem++; - up_write(&fi->i_gc_rwsem[READ]); + f2fs_up_write(&fi->i_gc_rwsem[READ]); continue; } locked = true; @@ -1527,8 +1527,8 @@ next_step: submitted++; if (locked) { - up_write(&fi->i_gc_rwsem[WRITE]); - up_write(&fi->i_gc_rwsem[READ]); + f2fs_up_write(&fi->i_gc_rwsem[WRITE]); + f2fs_up_write(&fi->i_gc_rwsem[READ]); } stat_inc_data_blk_count(sbi, 1, gc_type); @@ -1786,7 +1786,7 @@ stop: reserved_segments(sbi), prefree_segments(sbi)); - up_write(&sbi->gc_lock); + f2fs_up_write(&sbi->gc_lock); put_gc_inode(&gc_list); @@ -1915,7 +1915,7 @@ static void update_sb_metadata(struct f2fs_sb_info *sbi, int secs) long long block_count; int segs = secs * sbi->segs_per_sec; - down_write(&sbi->sb_lock); + f2fs_down_write(&sbi->sb_lock); section_count = le32_to_cpu(raw_sb->section_count); segment_count = le32_to_cpu(raw_sb->segment_count); @@ -1936,7 +1936,7 @@ static void update_sb_metadata(struct f2fs_sb_info *sbi, int secs) cpu_to_le32(dev_segs + segs); } - up_write(&sbi->sb_lock); + f2fs_up_write(&sbi->sb_lock); } static void update_fs_metadata(struct f2fs_sb_info *sbi, int secs) @@ -2010,7 +2010,7 @@ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count) secs = div_u64(shrunk_blocks, BLKS_PER_SEC(sbi)); /* stop other GC */ - if (!down_write_trylock(&sbi->gc_lock)) + if (!f2fs_down_write_trylock(&sbi->gc_lock)) return -EAGAIN; /* stop CP to protect MAIN_SEC in free_segment_range */ @@ -2030,15 +2030,15 @@ int f2fs_resize_fs(struct f2fs_sb_info *sbi, __u64 block_count) out_unlock: f2fs_unlock_op(sbi); - up_write(&sbi->gc_lock); + f2fs_up_write(&sbi->gc_lock); if (err) return err; set_sbi_flag(sbi, SBI_IS_RESIZEFS); freeze_super(sbi->sb); - down_write(&sbi->gc_lock); - down_write(&sbi->cp_global_sem); + f2fs_down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->cp_global_sem); spin_lock(&sbi->stat_lock); if (shrunk_blocks + valid_user_blocks(sbi) + @@ -2083,8 +2083,8 @@ recover_out: spin_unlock(&sbi->stat_lock); } out_err: - up_write(&sbi->cp_global_sem); - up_write(&sbi->gc_lock); + f2fs_up_write(&sbi->cp_global_sem); + f2fs_up_write(&sbi->gc_lock); thaw_super(sbi->sb); clear_sbi_flag(sbi, SBI_IS_RESIZEFS); return err; diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c index a85eb4207d81..bb50338a38c9 100644 --- a/fs/f2fs/inline.c +++ b/fs/f2fs/inline.c @@ -647,7 +647,7 @@ int f2fs_add_inline_entry(struct inode *dir, const struct f2fs_filename *fname, } if (inode) { - down_write(&F2FS_I(inode)->i_sem); + f2fs_down_write(&F2FS_I(inode)->i_sem); page = f2fs_init_inode_metadata(inode, dir, fname, ipage); if (IS_ERR(page)) { err = PTR_ERR(page); @@ -676,7 +676,7 @@ int f2fs_add_inline_entry(struct inode *dir, const struct f2fs_filename *fname, f2fs_update_parent_metadata(dir, inode, 0); fail: if (inode) - up_write(&F2FS_I(inode)->i_sem); + f2fs_up_write(&F2FS_I(inode)->i_sem); out: f2fs_put_page(ipage, 1); return err; diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 8e7aa2b2973e..3048074618ff 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -196,7 +196,7 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; int i, cold_count, hot_count; - down_read(&sbi->sb_lock); + f2fs_down_read(&sbi->sb_lock); cold_count = le32_to_cpu(sbi->raw_super->extension_count); hot_count = sbi->raw_super->hot_ext_count; @@ -206,7 +206,7 @@ static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode * break; } - up_read(&sbi->sb_lock); + f2fs_up_read(&sbi->sb_lock); if (i == cold_count + hot_count) return; @@ -297,19 +297,19 @@ static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, !f2fs_may_compress(inode)) return; - down_read(&sbi->sb_lock); + f2fs_down_read(&sbi->sb_lock); cold_count = le32_to_cpu(sbi->raw_super->extension_count); hot_count = sbi->raw_super->hot_ext_count; for (i = cold_count; i < cold_count + hot_count; i++) { if (is_extension_exist(name, extlist[i], false)) { - up_read(&sbi->sb_lock); + f2fs_up_read(&sbi->sb_lock); return; } } - up_read(&sbi->sb_lock); + f2fs_up_read(&sbi->sb_lock); ext = F2FS_OPTION(sbi).extensions; @@ -1012,11 +1012,11 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, new_page = NULL; new_inode->i_ctime = current_time(new_inode); - down_write(&F2FS_I(new_inode)->i_sem); + f2fs_down_write(&F2FS_I(new_inode)->i_sem); if (old_dir_entry) f2fs_i_links_write(new_inode, false); f2fs_i_links_write(new_inode, false); - up_write(&F2FS_I(new_inode)->i_sem); + f2fs_up_write(&F2FS_I(new_inode)->i_sem); if (!new_inode->i_nlink) f2fs_add_orphan_inode(new_inode); @@ -1037,13 +1037,13 @@ static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry, f2fs_i_links_write(new_dir, true); } - down_write(&F2FS_I(old_inode)->i_sem); + f2fs_down_write(&F2FS_I(old_inode)->i_sem); if (!old_dir_entry || whiteout) file_lost_pino(old_inode); else /* adjust dir's i_pino to pass fsck check */ f2fs_i_pino_write(old_inode, new_dir->i_ino); - up_write(&F2FS_I(old_inode)->i_sem); + f2fs_up_write(&F2FS_I(old_inode)->i_sem); old_inode->i_ctime = current_time(old_inode); f2fs_mark_inode_dirty_sync(old_inode, false); @@ -1203,38 +1203,38 @@ static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, /* update directory entry info of old dir inode */ f2fs_set_link(old_dir, old_entry, old_page, new_inode); - down_write(&F2FS_I(old_inode)->i_sem); + f2fs_down_write(&F2FS_I(old_inode)->i_sem); if (!old_dir_entry) file_lost_pino(old_inode); else /* adjust dir's i_pino to pass fsck check */ f2fs_i_pino_write(old_inode, new_dir->i_ino); - up_write(&F2FS_I(old_inode)->i_sem); + f2fs_up_write(&F2FS_I(old_inode)->i_sem); old_dir->i_ctime = current_time(old_dir); if (old_nlink) { - down_write(&F2FS_I(old_dir)->i_sem); + f2fs_down_write(&F2FS_I(old_dir)->i_sem); f2fs_i_links_write(old_dir, old_nlink > 0); - up_write(&F2FS_I(old_dir)->i_sem); + f2fs_up_write(&F2FS_I(old_dir)->i_sem); } f2fs_mark_inode_dirty_sync(old_dir, false); /* update directory entry info of new dir inode */ f2fs_set_link(new_dir, new_entry, new_page, old_inode); - down_write(&F2FS_I(new_inode)->i_sem); + f2fs_down_write(&F2FS_I(new_inode)->i_sem); if (!new_dir_entry) file_lost_pino(new_inode); else /* adjust dir's i_pino to pass fsck check */ f2fs_i_pino_write(new_inode, old_dir->i_ino); - up_write(&F2FS_I(new_inode)->i_sem); + f2fs_up_write(&F2FS_I(new_inode)->i_sem); new_dir->i_ctime = current_time(new_dir); if (new_nlink) { - down_write(&F2FS_I(new_dir)->i_sem); + f2fs_down_write(&F2FS_I(new_dir)->i_sem); f2fs_i_links_write(new_dir, new_nlink > 0); - up_write(&F2FS_I(new_dir)->i_sem); + f2fs_up_write(&F2FS_I(new_dir)->i_sem); } f2fs_mark_inode_dirty_sync(new_dir, false); diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 0bbac1043d93..7e2846407d5b 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -380,14 +380,14 @@ int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid) struct nat_entry *e; bool need = false; - down_read(&nm_i->nat_tree_lock); + f2fs_down_read(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); if (e) { if (!get_nat_flag(e, IS_CHECKPOINTED) && !get_nat_flag(e, HAS_FSYNCED_INODE)) need = true; } - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); return need; } @@ -397,11 +397,11 @@ bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid) struct nat_entry *e; bool is_cp = true; - down_read(&nm_i->nat_tree_lock); + f2fs_down_read(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); if (e && !get_nat_flag(e, IS_CHECKPOINTED)) is_cp = false; - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); return is_cp; } @@ -411,13 +411,13 @@ bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino) struct nat_entry *e; bool need_update = true; - down_read(&nm_i->nat_tree_lock); + f2fs_down_read(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, ino); if (e && get_nat_flag(e, HAS_LAST_FSYNC) && (get_nat_flag(e, IS_CHECKPOINTED) || get_nat_flag(e, HAS_FSYNCED_INODE))) need_update = false; - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); return need_update; } @@ -429,14 +429,14 @@ static void cache_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, struct nat_entry *new, *e; /* Let's mitigate lock contention of nat_tree_lock during checkpoint */ - if (rwsem_is_locked(&sbi->cp_global_sem)) + if (f2fs_rwsem_is_locked(&sbi->cp_global_sem)) return; new = __alloc_nat_entry(nid, false); if (!new) return; - down_write(&nm_i->nat_tree_lock); + f2fs_down_write(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); if (!e) e = __init_nat_entry(nm_i, new, ne, false); @@ -445,7 +445,7 @@ static void cache_nat_entry(struct f2fs_sb_info *sbi, nid_t nid, nat_get_blkaddr(e) != le32_to_cpu(ne->block_addr) || nat_get_version(e) != ne->version); - up_write(&nm_i->nat_tree_lock); + f2fs_up_write(&nm_i->nat_tree_lock); if (e != new) __free_nat_entry(new); } @@ -457,7 +457,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, struct nat_entry *e; struct nat_entry *new = __alloc_nat_entry(ni->nid, true); - down_write(&nm_i->nat_tree_lock); + f2fs_down_write(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, ni->nid); if (!e) { e = __init_nat_entry(nm_i, new, NULL, true); @@ -506,7 +506,7 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, set_nat_flag(e, HAS_FSYNCED_INODE, true); set_nat_flag(e, HAS_LAST_FSYNC, fsync_done); } - up_write(&nm_i->nat_tree_lock); + f2fs_up_write(&nm_i->nat_tree_lock); } int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) @@ -514,7 +514,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) struct f2fs_nm_info *nm_i = NM_I(sbi); int nr = nr_shrink; - if (!down_write_trylock(&nm_i->nat_tree_lock)) + if (!f2fs_down_write_trylock(&nm_i->nat_tree_lock)) return 0; spin_lock(&nm_i->nat_list_lock); @@ -536,7 +536,7 @@ int f2fs_try_to_free_nats(struct f2fs_sb_info *sbi, int nr_shrink) } spin_unlock(&nm_i->nat_list_lock); - up_write(&nm_i->nat_tree_lock); + f2fs_up_write(&nm_i->nat_tree_lock); return nr - nr_shrink; } @@ -558,13 +558,13 @@ int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid, ni->nid = nid; retry: /* Check nat cache */ - down_read(&nm_i->nat_tree_lock); + f2fs_down_read(&nm_i->nat_tree_lock); e = __lookup_nat_cache(nm_i, nid); if (e) { ni->ino = nat_get_ino(e); ni->blk_addr = nat_get_blkaddr(e); ni->version = nat_get_version(e); - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); return 0; } @@ -574,11 +574,11 @@ retry: * nat_tree_lock. Therefore, we should retry, if we failed to grab here * while not bothering checkpoint. */ - if (!rwsem_is_locked(&sbi->cp_global_sem) || checkpoint_context) { + if (!f2fs_rwsem_is_locked(&sbi->cp_global_sem) || checkpoint_context) { down_read(&curseg->journal_rwsem); - } else if (rwsem_is_contended(&nm_i->nat_tree_lock) || + } else if (f2fs_rwsem_is_contended(&nm_i->nat_tree_lock) || !down_read_trylock(&curseg->journal_rwsem)) { - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); goto retry; } @@ -587,15 +587,15 @@ retry: ne = nat_in_journal(journal, i); node_info_from_raw_nat(ni, &ne); } - up_read(&curseg->journal_rwsem); + up_read(&curseg->journal_rwsem); if (i >= 0) { - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); goto cache; } /* Fill node_info from nat page */ index = current_nat_addr(sbi, nid); - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); page = f2fs_get_meta_page(sbi, index); if (IS_ERR(page)) @@ -1588,17 +1588,17 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, goto redirty_out; if (wbc->for_reclaim) { - if (!down_read_trylock(&sbi->node_write)) + if (!f2fs_down_read_trylock(&sbi->node_write)) goto redirty_out; } else { - down_read(&sbi->node_write); + f2fs_down_read(&sbi->node_write); } /* This page is already truncated */ if (unlikely(ni.blk_addr == NULL_ADDR)) { ClearPageUptodate(page); dec_page_count(sbi, F2FS_DIRTY_NODES); - up_read(&sbi->node_write); + f2fs_up_read(&sbi->node_write); unlock_page(page); return 0; } @@ -1606,7 +1606,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, if (__is_valid_data_blkaddr(ni.blk_addr) && !f2fs_is_valid_blkaddr(sbi, ni.blk_addr, DATA_GENERIC_ENHANCE)) { - up_read(&sbi->node_write); + f2fs_up_read(&sbi->node_write); goto redirty_out; } @@ -1627,7 +1627,7 @@ static int __write_node_page(struct page *page, bool atomic, bool *submitted, f2fs_do_write_node_page(nid, &fio); set_node_addr(sbi, &ni, fio.new_blkaddr, is_fsync_dnode(page)); dec_page_count(sbi, F2FS_DIRTY_NODES); - up_read(&sbi->node_write); + f2fs_up_read(&sbi->node_write); if (wbc->for_reclaim) { f2fs_submit_merged_write_cond(sbi, NULL, page, 0, NODE); @@ -2376,7 +2376,7 @@ static void scan_free_nid_bits(struct f2fs_sb_info *sbi) unsigned int i, idx; nid_t nid; - down_read(&nm_i->nat_tree_lock); + f2fs_down_read(&nm_i->nat_tree_lock); for (i = 0; i < nm_i->nat_blocks; i++) { if (!test_bit_le(i, nm_i->nat_block_bitmap)) @@ -2399,7 +2399,7 @@ static void scan_free_nid_bits(struct f2fs_sb_info *sbi) out: scan_curseg_cache(sbi); - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); } static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi, @@ -2434,7 +2434,7 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi, f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nid), FREE_NID_PAGES, META_NAT, true); - down_read(&nm_i->nat_tree_lock); + f2fs_down_read(&nm_i->nat_tree_lock); while (1) { if (!test_bit_le(NAT_BLOCK_OFFSET(nid), @@ -2449,7 +2449,7 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi, } if (ret) { - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); f2fs_err(sbi, "NAT is corrupt, run fsck to fix it"); return ret; } @@ -2469,7 +2469,7 @@ static int __f2fs_build_free_nids(struct f2fs_sb_info *sbi, /* find free nids from current sum_pages */ scan_curseg_cache(sbi); - up_read(&nm_i->nat_tree_lock); + f2fs_up_read(&nm_i->nat_tree_lock); f2fs_ra_meta_pages(sbi, NAT_BLOCK_OFFSET(nm_i->next_scan_nid), nm_i->ra_nid_pages, META_NAT, false); @@ -2997,15 +2997,15 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) * nat_cnt[DIRTY_NAT]. */ if (enabled_nat_bits(sbi, cpc)) { - down_write(&nm_i->nat_tree_lock); + f2fs_down_write(&nm_i->nat_tree_lock); remove_nats_in_journal(sbi); - up_write(&nm_i->nat_tree_lock); + f2fs_up_write(&nm_i->nat_tree_lock); } if (!nm_i->nat_cnt[DIRTY_NAT]) return 0; - down_write(&nm_i->nat_tree_lock); + f2fs_down_write(&nm_i->nat_tree_lock); /* * if there are no enough space in journal to store dirty nat @@ -3034,7 +3034,7 @@ int f2fs_flush_nat_entries(struct f2fs_sb_info *sbi, struct cp_control *cpc) break; } - up_write(&nm_i->nat_tree_lock); + f2fs_up_write(&nm_i->nat_tree_lock); /* Allow dirty nats by node block allocation in write_begin */ return err; @@ -3152,7 +3152,7 @@ static int init_node_manager(struct f2fs_sb_info *sbi) mutex_init(&nm_i->build_lock); spin_lock_init(&nm_i->nid_list_lock); - init_rwsem(&nm_i->nat_tree_lock); + init_f2fs_rwsem(&nm_i->nat_tree_lock); nm_i->next_scan_nid = le32_to_cpu(sbi->ckpt->next_free_nid); nm_i->bitmap_size = __bitmap_size(sbi, NAT_BITMAP); @@ -3258,7 +3258,7 @@ void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi) spin_unlock(&nm_i->nid_list_lock); /* destroy nat cache */ - down_write(&nm_i->nat_tree_lock); + f2fs_down_write(&nm_i->nat_tree_lock); while ((found = __gang_lookup_nat_cache(nm_i, nid, NATVEC_SIZE, natvec))) { unsigned idx; @@ -3288,7 +3288,7 @@ void f2fs_destroy_node_manager(struct f2fs_sb_info *sbi) kmem_cache_free(nat_entry_set_slab, setvec[idx]); } } - up_write(&nm_i->nat_tree_lock); + f2fs_up_write(&nm_i->nat_tree_lock); kvfree(nm_i->nat_block_bitmap); if (nm_i->free_nid_bitmap) { diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c index 319ac27c624c..564cec003beb 100644 --- a/fs/f2fs/recovery.c +++ b/fs/f2fs/recovery.c @@ -797,7 +797,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only) INIT_LIST_HEAD(&dir_list); /* prevent checkpoint */ - down_write(&sbi->cp_global_sem); + f2fs_down_write(&sbi->cp_global_sem); /* step #1: find fsynced inode numbers */ err = find_fsync_dnodes(sbi, &inode_list, check_only); @@ -848,7 +848,7 @@ skip: if (!err) clear_sbi_flag(sbi, SBI_POR_DOING); - up_write(&sbi->cp_global_sem); + f2fs_up_write(&sbi->cp_global_sem); /* let's drop all the directory inodes for clean checkpoint */ destroy_fsync_dnodes(&dir_list, err); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 719983364197..f739bae3c443 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -471,7 +471,7 @@ int f2fs_commit_inmem_pages(struct inode *inode) f2fs_balance_fs(sbi, true); - down_write(&fi->i_gc_rwsem[WRITE]); + f2fs_down_write(&fi->i_gc_rwsem[WRITE]); f2fs_lock_op(sbi); set_inode_flag(inode, FI_ATOMIC_COMMIT); @@ -483,7 +483,7 @@ int f2fs_commit_inmem_pages(struct inode *inode) clear_inode_flag(inode, FI_ATOMIC_COMMIT); f2fs_unlock_op(sbi); - up_write(&fi->i_gc_rwsem[WRITE]); + f2fs_up_write(&fi->i_gc_rwsem[WRITE]); return err; } @@ -521,7 +521,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need) io_schedule(); finish_wait(&sbi->gc_thread->fggc_wq, &wait); } else { - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); f2fs_gc(sbi, false, false, false, NULL_SEGNO); } } @@ -551,7 +551,7 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi, bool from_bg) /* there is background inflight IO or foreground operation recently */ if (is_inflight_io(sbi, REQ_TIME) || - (!f2fs_time_over(sbi, REQ_TIME) && rwsem_is_locked(&sbi->cp_rwsem))) + (!f2fs_time_over(sbi, REQ_TIME) && f2fs_rwsem_is_locked(&sbi->cp_rwsem))) return; /* exceed periodical checkpoint timeout threshold */ @@ -2746,7 +2746,7 @@ static void __f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi) if (!sbi->am.atgc_enabled) return; - down_read(&SM_I(sbi)->curseg_lock); + f2fs_down_read(&SM_I(sbi)->curseg_lock); mutex_lock(&curseg->curseg_mutex); down_write(&SIT_I(sbi)->sentry_lock); @@ -2756,7 +2756,7 @@ static void __f2fs_init_atgc_curseg(struct f2fs_sb_info *sbi) up_write(&SIT_I(sbi)->sentry_lock); mutex_unlock(&curseg->curseg_mutex); - up_read(&SM_I(sbi)->curseg_lock); + f2fs_up_read(&SM_I(sbi)->curseg_lock); } void f2fs_init_inmem_curseg(struct f2fs_sb_info *sbi) @@ -2907,7 +2907,7 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type, struct curseg_info *curseg = CURSEG_I(sbi, type); unsigned int segno; - down_read(&SM_I(sbi)->curseg_lock); + f2fs_down_read(&SM_I(sbi)->curseg_lock); mutex_lock(&curseg->curseg_mutex); down_write(&SIT_I(sbi)->sentry_lock); @@ -2931,7 +2931,7 @@ unlock: type, segno, curseg->segno); mutex_unlock(&curseg->curseg_mutex); - up_read(&SM_I(sbi)->curseg_lock); + f2fs_up_read(&SM_I(sbi)->curseg_lock); } static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type, @@ -2963,23 +2963,23 @@ static void __allocate_new_section(struct f2fs_sb_info *sbi, void f2fs_allocate_new_section(struct f2fs_sb_info *sbi, int type, bool force) { - down_read(&SM_I(sbi)->curseg_lock); + f2fs_down_read(&SM_I(sbi)->curseg_lock); down_write(&SIT_I(sbi)->sentry_lock); __allocate_new_section(sbi, type, force); up_write(&SIT_I(sbi)->sentry_lock); - up_read(&SM_I(sbi)->curseg_lock); + f2fs_up_read(&SM_I(sbi)->curseg_lock); } void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi) { int i; - down_read(&SM_I(sbi)->curseg_lock); + f2fs_down_read(&SM_I(sbi)->curseg_lock); down_write(&SIT_I(sbi)->sentry_lock); for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) __allocate_new_segment(sbi, i, false, false); up_write(&SIT_I(sbi)->sentry_lock); - up_read(&SM_I(sbi)->curseg_lock); + f2fs_up_read(&SM_I(sbi)->curseg_lock); } static const struct segment_allocation default_salloc_ops = { @@ -3117,9 +3117,9 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) if (sbi->discard_blks == 0) goto out; - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); err = f2fs_write_checkpoint(sbi, &cpc); - up_write(&sbi->gc_lock); + f2fs_up_write(&sbi->gc_lock); if (err) goto out; @@ -3356,7 +3356,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, bool from_gc = (type == CURSEG_ALL_DATA_ATGC); struct seg_entry *se = NULL; - down_read(&SM_I(sbi)->curseg_lock); + f2fs_down_read(&SM_I(sbi)->curseg_lock); mutex_lock(&curseg->curseg_mutex); down_write(&sit_i->sentry_lock); @@ -3439,7 +3439,7 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, mutex_unlock(&curseg->curseg_mutex); - up_read(&SM_I(sbi)->curseg_lock); + f2fs_up_read(&SM_I(sbi)->curseg_lock); } static void update_device_state(struct f2fs_io_info *fio) @@ -3469,7 +3469,7 @@ static void do_write_page(struct f2fs_summary *sum, struct f2fs_io_info *fio) bool keep_order = (f2fs_lfs_mode(fio->sbi) && type == CURSEG_COLD_DATA); if (keep_order) - down_read(&fio->sbi->io_order_lock); + f2fs_down_read(&fio->sbi->io_order_lock); reallocate: f2fs_allocate_data_block(fio->sbi, fio->page, fio->old_blkaddr, &fio->new_blkaddr, sum, type, fio); @@ -3489,7 +3489,7 @@ reallocate: update_device_state(fio); if (keep_order) - up_read(&fio->sbi->io_order_lock); + f2fs_up_read(&fio->sbi->io_order_lock); } void f2fs_do_write_meta_page(struct f2fs_sb_info *sbi, struct page *page, @@ -3620,7 +3620,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, se = get_seg_entry(sbi, segno); type = se->type; - down_write(&SM_I(sbi)->curseg_lock); + f2fs_down_write(&SM_I(sbi)->curseg_lock); if (!recover_curseg) { /* for recovery flow */ @@ -3689,7 +3689,7 @@ void f2fs_do_replace_block(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, up_write(&sit_i->sentry_lock); mutex_unlock(&curseg->curseg_mutex); - up_write(&SM_I(sbi)->curseg_lock); + f2fs_up_write(&SM_I(sbi)->curseg_lock); } void f2fs_replace_block(struct f2fs_sb_info *sbi, struct dnode_of_data *dn, @@ -5165,7 +5165,7 @@ int f2fs_build_segment_manager(struct f2fs_sb_info *sbi) INIT_LIST_HEAD(&sm_info->sit_entry_set); - init_rwsem(&sm_info->curseg_lock); + init_f2fs_rwsem(&sm_info->curseg_lock); if (!f2fs_readonly(sbi->sb)) { err = f2fs_create_flush_cmd_control(sbi); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index e03c0a095e1c..ec33b54bf009 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1208,17 +1208,17 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) /* Initialize f2fs-specific inode info */ atomic_set(&fi->dirty_pages, 0); atomic_set(&fi->i_compr_blocks, 0); - init_rwsem(&fi->i_sem); + init_f2fs_rwsem(&fi->i_sem); spin_lock_init(&fi->i_size_lock); INIT_LIST_HEAD(&fi->dirty_list); INIT_LIST_HEAD(&fi->gdirty_list); INIT_LIST_HEAD(&fi->inmem_ilist); INIT_LIST_HEAD(&fi->inmem_pages); mutex_init(&fi->inmem_lock); - init_rwsem(&fi->i_gc_rwsem[READ]); - init_rwsem(&fi->i_gc_rwsem[WRITE]); - init_rwsem(&fi->i_mmap_sem); - init_rwsem(&fi->i_xattr_sem); + init_f2fs_rwsem(&fi->i_gc_rwsem[READ]); + init_f2fs_rwsem(&fi->i_gc_rwsem[WRITE]); + init_f2fs_rwsem(&fi->i_mmap_sem); + init_f2fs_rwsem(&fi->i_xattr_sem); /* Will be used by directory only */ fi->i_dir_level = F2FS_SB(sb)->dir_level; @@ -1923,7 +1923,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) f2fs_update_time(sbi, DISABLE_TIME); while (!f2fs_time_over(sbi, DISABLE_TIME)) { - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); err = f2fs_gc(sbi, true, false, false, NULL_SEGNO); if (err == -ENODATA) { err = 0; @@ -1945,7 +1945,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) goto restore_flag; } - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); cpc.reason = CP_PAUSE; set_sbi_flag(sbi, SBI_CP_DISABLED); err = f2fs_write_checkpoint(sbi, &cpc); @@ -1957,7 +1957,7 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi) spin_unlock(&sbi->stat_lock); out_unlock: - up_write(&sbi->gc_lock); + f2fs_up_write(&sbi->gc_lock); restore_flag: sbi->sb->s_flags = s_flags; /* Restore SB_RDONLY status */ return err; @@ -1977,12 +1977,12 @@ static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi) if (unlikely(retry < 0)) f2fs_warn(sbi, "checkpoint=enable has some unwritten data."); - down_write(&sbi->gc_lock); + f2fs_down_write(&sbi->gc_lock); f2fs_dirty_to_prefree(sbi); clear_sbi_flag(sbi, SBI_CP_DISABLED); set_sbi_flag(sbi, SBI_IS_DIRTY); - up_write(&sbi->gc_lock); + f2fs_up_write(&sbi->gc_lock); f2fs_sync_fs(sbi->sb, 1); } @@ -2504,18 +2504,18 @@ int f2fs_quota_sync(struct super_block *sb, int type) /* * do_quotactl * f2fs_quota_sync - * down_read(quota_sem) + * f2fs_down_read(quota_sem) * dquot_writeback_dquots() * f2fs_dquot_commit * block_operation - * down_read(quota_sem) + * f2fs_down_read(quota_sem) */ f2fs_lock_op(sbi); - down_read(&sbi->quota_sem); + f2fs_down_read(&sbi->quota_sem); ret = f2fs_quota_sync_file(sbi, cnt); - up_read(&sbi->quota_sem); + f2fs_up_read(&sbi->quota_sem); f2fs_unlock_op(sbi); inode_unlock(dqopt->files[cnt]); @@ -2640,11 +2640,11 @@ static int f2fs_dquot_commit(struct dquot *dquot) struct f2fs_sb_info *sbi = F2FS_SB(dquot->dq_sb); int ret; - down_read_nested(&sbi->quota_sem, SINGLE_DEPTH_NESTING); + f2fs_down_read_nested(&sbi->quota_sem, SINGLE_DEPTH_NESTING); ret = dquot_commit(dquot); if (ret < 0) set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); - up_read(&sbi->quota_sem); + f2fs_up_read(&sbi->quota_sem); return ret; } @@ -2653,11 +2653,11 @@ static int f2fs_dquot_acquire(struct dquot *dquot) struct f2fs_sb_info *sbi = F2FS_SB(dquot->dq_sb); int ret; - down_read(&sbi->quota_sem); + f2fs_down_read(&sbi->quota_sem); ret = dquot_acquire(dquot); if (ret < 0) set_sbi_flag(sbi, SBI_QUOTA_NEED_REPAIR); - up_read(&sbi->quota_sem); + f2fs_up_read(&sbi->quota_sem); return ret; } @@ -3390,14 +3390,14 @@ static void init_sb_info(struct f2fs_sb_info *sbi) INIT_LIST_HEAD(&sbi->s_list); mutex_init(&sbi->umount_mutex); - init_rwsem(&sbi->io_order_lock); + init_f2fs_rwsem(&sbi->io_order_lock); spin_lock_init(&sbi->cp_lock); sbi->dirty_device = 0; spin_lock_init(&sbi->dev_lock); - init_rwsem(&sbi->sb_lock); - init_rwsem(&sbi->pin_sem); + init_f2fs_rwsem(&sbi->sb_lock); + init_f2fs_rwsem(&sbi->pin_sem); } static int init_percpu_info(struct f2fs_sb_info *sbi) @@ -3841,11 +3841,11 @@ try_onemore: /* init f2fs-specific super block info */ sbi->valid_super_block = valid_super_block; - init_rwsem(&sbi->gc_lock); + init_f2fs_rwsem(&sbi->gc_lock); mutex_init(&sbi->writepages); - init_rwsem(&sbi->cp_global_sem); - init_rwsem(&sbi->node_write); - init_rwsem(&sbi->node_change); + init_f2fs_rwsem(&sbi->cp_global_sem); + init_f2fs_rwsem(&sbi->node_write); + init_f2fs_rwsem(&sbi->node_change); /* disallow all the data/node/meta page writes */ set_sbi_flag(sbi, SBI_POR_DOING); @@ -3871,18 +3871,18 @@ try_onemore: } for (j = HOT; j < n; j++) { - init_rwsem(&sbi->write_io[i][j].io_rwsem); + init_f2fs_rwsem(&sbi->write_io[i][j].io_rwsem); sbi->write_io[i][j].sbi = sbi; sbi->write_io[i][j].bio = NULL; spin_lock_init(&sbi->write_io[i][j].io_lock); INIT_LIST_HEAD(&sbi->write_io[i][j].io_list); INIT_LIST_HEAD(&sbi->write_io[i][j].bio_list); - init_rwsem(&sbi->write_io[i][j].bio_list_lock); + init_f2fs_rwsem(&sbi->write_io[i][j].bio_list_lock); } } - init_rwsem(&sbi->cp_rwsem); - init_rwsem(&sbi->quota_sem); + init_f2fs_rwsem(&sbi->cp_rwsem); + init_f2fs_rwsem(&sbi->quota_sem); init_waitqueue_head(&sbi->cp_wait); init_sb_info(sbi); diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index 78c6c67b43d7..da5bc58d2706 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -363,7 +363,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a, if (strlen(name) >= F2FS_EXTENSION_LEN) return -EINVAL; - down_write(&sbi->sb_lock); + f2fs_down_write(&sbi->sb_lock); ret = f2fs_update_extension_list(sbi, name, hot, set); if (ret) @@ -373,7 +373,7 @@ static ssize_t __sbi_store(struct f2fs_attr *a, if (ret) f2fs_update_extension_list(sbi, name, hot, !set); out: - up_write(&sbi->sb_lock); + f2fs_up_write(&sbi->sb_lock); return ret ? ret : count; } diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c index 15ba36926fad..c700fb47e895 100644 --- a/fs/f2fs/verity.c +++ b/fs/f2fs/verity.c @@ -208,7 +208,7 @@ cleanup: * from re-instantiating cached pages we are truncating (since unlike * normal file accesses, garbage collection isn't limited by i_size). */ - down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); truncate_inode_pages(inode->i_mapping, inode->i_size); err2 = f2fs_truncate(inode); if (err2) { @@ -216,7 +216,7 @@ cleanup: err2); set_sbi_flag(sbi, SBI_NEED_FSCK); } - up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); + f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); clear_inode_flag(inode, FI_VERITY_IN_PROGRESS); return err ?: err2; } diff --git a/fs/f2fs/xattr.c b/fs/f2fs/xattr.c index e8f7fbb3c386..87b2cd37d1b2 100644 --- a/fs/f2fs/xattr.c +++ b/fs/f2fs/xattr.c @@ -529,10 +529,10 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name, if (len > F2FS_NAME_LEN) return -ERANGE; - down_read(&F2FS_I(inode)->i_xattr_sem); + f2fs_down_read(&F2FS_I(inode)->i_xattr_sem); error = lookup_all_xattrs(inode, ipage, index, len, name, &entry, &base_addr, &base_size, &is_inline); - up_read(&F2FS_I(inode)->i_xattr_sem); + f2fs_up_read(&F2FS_I(inode)->i_xattr_sem); if (error) return error; @@ -566,9 +566,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) int error; size_t rest = buffer_size; - down_read(&F2FS_I(inode)->i_xattr_sem); + f2fs_down_read(&F2FS_I(inode)->i_xattr_sem); error = read_all_xattrs(inode, NULL, &base_addr); - up_read(&F2FS_I(inode)->i_xattr_sem); + f2fs_up_read(&F2FS_I(inode)->i_xattr_sem); if (error) return error; @@ -781,9 +781,9 @@ int f2fs_setxattr(struct inode *inode, int index, const char *name, f2fs_balance_fs(sbi, true); f2fs_lock_op(sbi); - down_write(&F2FS_I(inode)->i_xattr_sem); + f2fs_down_write(&F2FS_I(inode)->i_xattr_sem); err = __f2fs_setxattr(inode, index, name, value, size, ipage, flags); - up_write(&F2FS_I(inode)->i_xattr_sem); + f2fs_up_write(&F2FS_I(inode)->i_xattr_sem); f2fs_unlock_op(sbi); f2fs_update_time(sbi, REQ_TIME); From ee1e2de73cc54ecdcb657311d3e594542b65c7c6 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 20 Jan 2022 11:04:01 -0600 Subject: [PATCH 48/52] UPSTREAM: cgroup-v1: Require capabilities to set release_agent The cgroup release_agent is called with call_usermodehelper. The function call_usermodehelper starts the release_agent with a full set fo capabilities. Therefore require capabilities when setting the release_agaent. Reported-by: Tabitha Sable Tested-by: Tabitha Sable Fixes: 81a6a5cdd2c5 ("Task Control Groups: automatic userspace notification of idle cgroups") Cc: stable@vger.kernel.org # v2.6.24+ Signed-off-by: "Eric W. Biederman" Signed-off-by: Tejun Heo (cherry picked from commit 24f6008564183aa120d07c03d9289519c2fe02af) Signed-off-by: Greg Kroah-Hartman Change-Id: If663568d24f781c58c882d69a5b81a9327c0e6fe --- kernel/cgroup/cgroup-v1.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index a1e8068d17cc..f931f6547423 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c @@ -548,6 +548,14 @@ static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, BUILD_BUG_ON(sizeof(cgrp->root->release_agent_path) < PATH_MAX); + /* + * Release agent gets called with all capabilities, + * require capabilities to set release agent. + */ + if ((of->file->f_cred->user_ns != &init_user_ns) || + !capable(CAP_SYS_ADMIN)) + return -EPERM; + cgrp = cgroup_kn_lock_live(of->kn, false); if (!cgrp) return -ENODEV; @@ -961,6 +969,12 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param) /* Specifying two release agents is forbidden */ if (ctx->release_agent) return invalfc(fc, "release_agent respecified"); + /* + * Release agent gets called with all capabilities, + * require capabilities to set release agent. + */ + if ((fc->user_ns != &init_user_ns) || !capable(CAP_SYS_ADMIN)) + return invalfc(fc, "Setting release_agent not allowed"); ctx->release_agent = param->string; param->string = NULL; break; From 1eb3049da0eb2c7060a5562bbe59d1d4b8babce2 Mon Sep 17 00:00:00 2001 From: Udipto Goswami Date: Mon, 7 Feb 2022 09:55:58 +0530 Subject: [PATCH 49/52] FROMGIT: usb: dwc3: gadget: Prevent core from processing stale TRBs With CPU re-ordering on write instructions, there might be a chance that the HWO is set before the TRB is updated with the new mapped buffer address. And in the case where core is processing a list of TRBs it is possible that it fetched the TRBs when the HWO is set but before the buffer address is updated. Prevent this by adding a memory barrier before the HWO is updated to ensure that the core always process the updated TRBs. Fixes: f6bafc6a1c9d ("usb: dwc3: convert TRBs into bitshifts") Cc: stable Reviewed-by: Pavankumar Kondeti Signed-off-by: Udipto Goswami Link: https://lore.kernel.org/r/1644207958-18287-1-git-send-email-quic_ugoswami@quicinc.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 117b4e96c7f362eb6459543883fc07f77662472c https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-linus) BUG: 218446155 Change-Id: I214ba60eebb6f00e4204171be6c26b93060b7512 Signed-off-by: Udipto Goswami --- drivers/usb/dwc3/gadget.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index c4ebfb1cff0d..0d3728c7b659 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1258,6 +1258,19 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb, if (usb_endpoint_xfer_bulk(dep->endpoint.desc) && dep->stream_capable) trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(stream_id); + /* + * As per data book 4.2.3.2TRB Control Bit Rules section + * + * The controller autonomously checks the HWO field of a TRB to determine if the + * entire TRB is valid. Therefore, software must ensure that the rest of the TRB + * is valid before setting the HWO field to '1'. In most systems, this means that + * software must update the fourth DWORD of a TRB last. + * + * However there is a possibility of CPU re-ordering here which can cause + * controller to observe the HWO bit set prematurely. + * Add a write memory barrier to prevent CPU re-ordering. + */ + wmb(); trb->ctrl |= DWC3_TRB_CTRL_HWO; dwc3_ep_inc_enq(dep); From fc64efcd068c9f723ff047f32c1c1302ad146469 Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Tue, 8 Feb 2022 12:38:49 -0800 Subject: [PATCH 50/52] Revert "UPSTREAM: tracefs: Have tracefs directories not set OTH permission bits by default" This reverts commit 9c63be2adac9788180d892351052b9f2bcdb3d37. Reason for revert: android12 still relies on OTH bits being set. Bug: 218458907 Signed-off-by: Elliot Berman Change-Id: Idac3d9a515188d718b7bf5c01105531f2e9bacdc --- fs/tracefs/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c index ade05887070d..5a3f09d7d821 100644 --- a/fs/tracefs/inode.c +++ b/fs/tracefs/inode.c @@ -504,8 +504,7 @@ static struct dentry *__create_dir(const char *name, struct dentry *parent, if (unlikely(!inode)) return failed_creating(dentry); - /* Do not set bits for OTH */ - inode->i_mode = S_IFDIR | S_IRWXU | S_IRUSR| S_IRGRP | S_IXUSR | S_IXGRP; + inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; inode->i_op = ops; inode->i_fop = &simple_dir_operations; inode->i_uid = d_inode(dentry->d_parent)->i_uid; From b90fe5ef8f963ff2ef7306bf7163dcad91a6614b Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Mon, 13 Dec 2021 15:51:16 +0530 Subject: [PATCH 51/52] FROMLIST: power_supply: Register cooling device outside of probe Registering the cooling device from the probe can result in the execution of get_property() function before it gets initialized. To avoid this, register the cooling device from a workqueue instead of registering in the probe. Signed-off-by: Manaf Meethalavalappu Pallikunhi Bug: 211709650 Link: https://lore.kernel.org/linux-pm/1640162489-7847-1-git-send-email-quic_manafm@quicinc.com/ Change-Id: Id1aa63da9c4e43272c78b50b8b61a92b2d4f617d Signed-off-by: Manaf Meethalavalappu Pallikunhi --- drivers/power/supply/power_supply_core.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index 668369b26f99..ef6f290f6d7b 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -132,6 +132,7 @@ void power_supply_changed(struct power_supply *psy) } EXPORT_SYMBOL_GPL(power_supply_changed); +static int psy_register_cooler(struct power_supply *psy); /* * Notify that power supply was registered after parent finished the probing. * @@ -139,6 +140,8 @@ EXPORT_SYMBOL_GPL(power_supply_changed); * calling power_supply_changed() directly from power_supply_register() * would lead to execution of get_property() function provided by the driver * too early - before the probe ends. + * Also, registering cooling device from the probe will execute the + * get_property() function. So register the cooling device after the probe. * * Avoid that by waiting on parent's mutex. */ @@ -156,6 +159,7 @@ static void power_supply_deferred_register_work(struct work_struct *work) } power_supply_changed(psy); + psy_register_cooler(psy); if (psy->dev.parent) mutex_unlock(&psy->dev.parent->mutex); @@ -1238,10 +1242,6 @@ __power_supply_register(struct device *parent, if (rc) goto register_thermal_failed; - rc = psy_register_cooler(psy); - if (rc) - goto register_cooler_failed; - rc = power_supply_create_triggers(psy); if (rc) goto create_triggers_failed; @@ -1271,8 +1271,6 @@ __power_supply_register(struct device *parent, add_hwmon_sysfs_failed: power_supply_remove_triggers(psy); create_triggers_failed: - psy_unregister_cooler(psy); -register_cooler_failed: psy_unregister_thermal(psy); register_thermal_failed: device_del(dev); From 2a2327c4e8ac335069586354b280031105b9980e Mon Sep 17 00:00:00 2001 From: Manaf Meethalavalappu Pallikunhi Date: Tue, 14 Dec 2021 11:49:26 +0530 Subject: [PATCH 52/52] FROMLIST: power_supply: Use of-thermal cdev registration API With thermal frameworks of-thermal interface, thermal zone parameters can be defined in devicetree. This includes cooling device mitigation levels for a thermal zone. To take advantage of this, cooling device should use the thermal_of_cooling_device_register API to register a cooling device. Use thermal_of_cooling_device_register API to register the power supply cooling device. This enables power supply cooling device be included in the thermal zone parameter in devicetree. Signed-off-by: Manaf Meethalavalappu Pallikunhi Bug: 211709650 Link: https://lore.kernel.org/linux-pm/1640162489-7847-2-git-send-email-quic_manafm@quicinc.com/ Change-Id: Ie0d527543adb8590ec52df96bf3e4d0f1f022d0a Signed-off-by: Manaf Meethalavalappu Pallikunhi --- drivers/power/supply/power_supply_core.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c index ef6f290f6d7b..f42031c539a7 100644 --- a/drivers/power/supply/power_supply_core.c +++ b/drivers/power/supply/power_supply_core.c @@ -1134,9 +1134,15 @@ static int psy_register_cooler(struct power_supply *psy) for (i = 0; i < psy->desc->num_properties; i++) { if (psy->desc->properties[i] == POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT) { - psy->tcd = thermal_cooling_device_register( - (char *)psy->desc->name, - psy, &psy_tcd_ops); + if (psy->dev.parent) + psy->tcd = thermal_of_cooling_device_register( + dev_of_node(psy->dev.parent), + (char *)psy->desc->name, + psy, &psy_tcd_ops); + else + psy->tcd = thermal_cooling_device_register( + (char *)psy->desc->name, + psy, &psy_tcd_ops); return PTR_ERR_OR_ZERO(psy->tcd); } }