diff --git a/kernel/scs.c b/kernel/scs.c index ad74d13f2c0f..c8e53358e20a 100644 --- a/kernel/scs.c +++ b/kernel/scs.c @@ -185,36 +185,31 @@ int scs_prepare(struct task_struct *tsk, int node) } #ifdef CONFIG_DEBUG_STACK_USAGE -static inline unsigned long scs_used(struct task_struct *tsk) -{ - unsigned long *p = __scs_base(tsk); - unsigned long *end = scs_magic(p); - unsigned long s = (unsigned long)p; - - while (p < end && READ_ONCE_NOCHECK(*p)) - p++; - - return (unsigned long)p - s; -} - static void scs_check_usage(struct task_struct *tsk) { - static DEFINE_SPINLOCK(lock); static unsigned long highest; - unsigned long used = scs_used(tsk); - if (used <= highest) - return; + unsigned long *p = __scs_base(tsk); + unsigned long *end = scs_magic(p); + unsigned long prev, curr = highest, used = 0; - spin_lock(&lock); - - if (used > highest) { - pr_info("%s (%d): highest shadow stack usage: %lu bytes\n", - tsk->comm, task_pid_nr(tsk), used); - highest = used; + for (; p < end; ++p) { + if (!READ_ONCE_NOCHECK(*p)) + break; + used += sizeof(*p); } - spin_unlock(&lock); + while (used > curr) { + prev = cmpxchg_relaxed(&highest, curr, used); + + if (prev == curr) { + pr_info("%s (%d): highest shadow stack usage: %lu bytes\n", + tsk->comm, task_pid_nr(tsk), used); + break; + } + + curr = prev; + } } #else static inline void scs_check_usage(struct task_struct *tsk)