From: Ingo Molnar <mingo@kernel.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: linux-kernel@vger.kernel.org,
"Thomas Gleixner" <tglx@linutronix.de>,
"Peter Zijlstra" <a.p.zijlstra@chello.nl>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Frédéric Weisbecker" <fweisbec@gmail.com>
Subject: [GIT PULL] core kernel fixes
Date: Sun, 3 Apr 2016 12:45:36 +0200 [thread overview]
Message-ID: <20160403104536.GA16924@gmail.com> (raw)
Linus,
Please pull the latest core-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus
# HEAD: 353def94606fda16d9ae1761b4b0583286481ec5 MAINTAINERS: Update my email address
This contains the nohz/atomic cleanup/fix for the fetch_or() ugliness you noted
during the original nohz pull request, plus there's also misc fixes:
- fix liblockdep build bug
- fix uapi header build bug
- print more lockdep hash collision info to help debug recent reports of hash collisions
- update MAINTAINERS email address
Thanks,
Ingo
------------------>
Alfredo Alvarez Fernandez (1):
locking/lockdep: Print chain_key collision information
Denys Vlasenko (1):
uapi/linux/stddef.h: Provide __always_inline to userspace headers
Frederic Weisbecker (3):
locking/atomic: Introduce atomic_fetch_or()
timers/nohz: Convert tick dependency mask to atomic_t
locking/atomic, sched: Unexport fetch_or()
Masami Hiramatsu (1):
MAINTAINERS: Update my email address
Sedat Dilek (1):
tools/lib/lockdep: Fix unsupported 'basename -s' in run_tests.sh
MAINTAINERS | 2 +-
include/linux/atomic.h | 34 +++++++++---------
include/linux/sched.h | 4 +--
include/uapi/linux/stddef.h | 4 +++
kernel/locking/lockdep.c | 79 ++++++++++++++++++++++++++++++++++++++++--
kernel/sched/core.c | 18 ++++++++++
kernel/time/tick-sched.c | 61 ++++++++++++++++----------------
kernel/time/tick-sched.h | 2 +-
tools/lib/lockdep/run_tests.sh | 12 ++++---
9 files changed, 158 insertions(+), 58 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 378ebfff2d1f..ed121a5b9319 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6402,7 +6402,7 @@ KPROBES
M: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
M: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
M: "David S. Miller" <davem@davemloft.net>
-M: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
+M: Masami Hiramatsu <mhiramat@kernel.org>
S: Maintained
F: Documentation/kprobes.txt
F: include/linux/kprobes.h
diff --git a/include/linux/atomic.h b/include/linux/atomic.h
index df4f369254c0..506c3531832e 100644
--- a/include/linux/atomic.h
+++ b/include/linux/atomic.h
@@ -559,25 +559,25 @@ static inline int atomic_dec_if_positive(atomic_t *v)
#endif
/**
- * fetch_or - perform *ptr |= mask and return old value of *ptr
- * @ptr: pointer to value
- * @mask: mask to OR on the value
- *
- * cmpxchg based fetch_or, macro so it works for different integer types
+ * atomic_fetch_or - perform *p |= mask and return old value of *p
+ * @p: pointer to atomic_t
+ * @mask: mask to OR on the atomic_t
*/
-#ifndef fetch_or
-#define fetch_or(ptr, mask) \
-({ typeof(*(ptr)) __old, __val = *(ptr); \
- for (;;) { \
- __old = cmpxchg((ptr), __val, __val | (mask)); \
- if (__old == __val) \
- break; \
- __val = __old; \
- } \
- __old; \
-})
-#endif
+#ifndef atomic_fetch_or
+static inline int atomic_fetch_or(atomic_t *p, int mask)
+{
+ int old, val = atomic_read(p);
+
+ for (;;) {
+ old = atomic_cmpxchg(p, val, val | mask);
+ if (old == val)
+ break;
+ val = old;
+ }
+ return old;
+}
+#endif
#ifdef CONFIG_GENERIC_ATOMIC64
#include <asm-generic/atomic64.h>
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 60bba7e032dc..52c4847b05e2 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -720,7 +720,7 @@ struct signal_struct {
struct task_cputime cputime_expires;
#ifdef CONFIG_NO_HZ_FULL
- unsigned long tick_dep_mask;
+ atomic_t tick_dep_mask;
#endif
struct list_head cpu_timers[3];
@@ -1549,7 +1549,7 @@ struct task_struct {
#endif
#ifdef CONFIG_NO_HZ_FULL
- unsigned long tick_dep_mask;
+ atomic_t tick_dep_mask;
#endif
unsigned long nvcsw, nivcsw; /* context switch counts */
u64 start_time; /* monotonic time in nsec */
diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h
index aa9f10428743..621fa8ac4425 100644
--- a/include/uapi/linux/stddef.h
+++ b/include/uapi/linux/stddef.h
@@ -1 +1,5 @@
#include <linux/compiler.h>
+
+#ifndef __always_inline
+#define __always_inline inline
+#endif
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 53ab2f85d77e..2324ba5310db 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -2000,6 +2000,77 @@ static inline int get_first_held_lock(struct task_struct *curr,
}
/*
+ * Returns the next chain_key iteration
+ */
+static u64 print_chain_key_iteration(int class_idx, u64 chain_key)
+{
+ u64 new_chain_key = iterate_chain_key(chain_key, class_idx);
+
+ printk(" class_idx:%d -> chain_key:%016Lx",
+ class_idx,
+ (unsigned long long)new_chain_key);
+ return new_chain_key;
+}
+
+static void
+print_chain_keys_held_locks(struct task_struct *curr, struct held_lock *hlock_next)
+{
+ struct held_lock *hlock;
+ u64 chain_key = 0;
+ int depth = curr->lockdep_depth;
+ int i;
+
+ printk("depth: %u\n", depth + 1);
+ for (i = get_first_held_lock(curr, hlock_next); i < depth; i++) {
+ hlock = curr->held_locks + i;
+ chain_key = print_chain_key_iteration(hlock->class_idx, chain_key);
+
+ print_lock(hlock);
+ }
+
+ print_chain_key_iteration(hlock_next->class_idx, chain_key);
+ print_lock(hlock_next);
+}
+
+static void print_chain_keys_chain(struct lock_chain *chain)
+{
+ int i;
+ u64 chain_key = 0;
+ int class_id;
+
+ printk("depth: %u\n", chain->depth);
+ for (i = 0; i < chain->depth; i++) {
+ class_id = chain_hlocks[chain->base + i];
+ chain_key = print_chain_key_iteration(class_id + 1, chain_key);
+
+ print_lock_name(lock_classes + class_id);
+ printk("\n");
+ }
+}
+
+static void print_collision(struct task_struct *curr,
+ struct held_lock *hlock_next,
+ struct lock_chain *chain)
+{
+ printk("\n");
+ printk("======================\n");
+ printk("[chain_key collision ]\n");
+ print_kernel_ident();
+ printk("----------------------\n");
+ printk("%s/%d: ", current->comm, task_pid_nr(current));
+ printk("Hash chain already cached but the contents don't match!\n");
+
+ printk("Held locks:");
+ print_chain_keys_held_locks(curr, hlock_next);
+
+ printk("Locks in cached chain:");
+ print_chain_keys_chain(chain);
+
+ printk("\nstack backtrace:\n");
+ dump_stack();
+}
+
+/*
* Checks whether the chain and the current held locks are consistent
* in depth and also in content. If they are not it most likely means
* that there was a collision during the calculation of the chain_key.
@@ -2014,14 +2085,18 @@ static int check_no_collision(struct task_struct *curr,
i = get_first_held_lock(curr, hlock);
- if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1)))
+ if (DEBUG_LOCKS_WARN_ON(chain->depth != curr->lockdep_depth - (i - 1))) {
+ print_collision(curr, hlock, chain);
return 0;
+ }
for (j = 0; j < chain->depth - 1; j++, i++) {
id = curr->held_locks[i].class_idx - 1;
- if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id))
+ if (DEBUG_LOCKS_WARN_ON(chain_hlocks[chain->base + j] != id)) {
+ print_collision(curr, hlock, chain);
return 0;
+ }
}
#endif
return 1;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d8465eeab8b3..8b489fcac37b 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -321,6 +321,24 @@ static inline void init_hrtick(void)
}
#endif /* CONFIG_SCHED_HRTICK */
+/*
+ * cmpxchg based fetch_or, macro so it works for different integer types
+ */
+#define fetch_or(ptr, mask) \
+ ({ \
+ typeof(ptr) _ptr = (ptr); \
+ typeof(mask) _mask = (mask); \
+ typeof(*_ptr) _old, _val = *_ptr; \
+ \
+ for (;;) { \
+ _old = cmpxchg(_ptr, _val, _val | _mask); \
+ if (_old == _val) \
+ break; \
+ _val = _old; \
+ } \
+ _old; \
+})
+
#if defined(CONFIG_SMP) && defined(TIF_POLLING_NRFLAG)
/*
* Atomically set TIF_NEED_RESCHED and test for TIF_POLLING_NRFLAG,
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 084b79f5917e..58e3310c9b21 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -157,52 +157,50 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
cpumask_var_t tick_nohz_full_mask;
cpumask_var_t housekeeping_mask;
bool tick_nohz_full_running;
-static unsigned long tick_dep_mask;
+static atomic_t tick_dep_mask;
-static void trace_tick_dependency(unsigned long dep)
+static bool check_tick_dependency(atomic_t *dep)
{
- if (dep & TICK_DEP_MASK_POSIX_TIMER) {
+ int val = atomic_read(dep);
+
+ if (val & TICK_DEP_MASK_POSIX_TIMER) {
trace_tick_stop(0, TICK_DEP_MASK_POSIX_TIMER);
- return;
+ return true;
}
- if (dep & TICK_DEP_MASK_PERF_EVENTS) {
+ if (val & TICK_DEP_MASK_PERF_EVENTS) {
trace_tick_stop(0, TICK_DEP_MASK_PERF_EVENTS);
- return;
+ return true;
}
- if (dep & TICK_DEP_MASK_SCHED) {
+ if (val & TICK_DEP_MASK_SCHED) {
trace_tick_stop(0, TICK_DEP_MASK_SCHED);
- return;
+ return true;
}
- if (dep & TICK_DEP_MASK_CLOCK_UNSTABLE)
+ if (val & TICK_DEP_MASK_CLOCK_UNSTABLE) {
trace_tick_stop(0, TICK_DEP_MASK_CLOCK_UNSTABLE);
+ return true;
+ }
+
+ return false;
}
static bool can_stop_full_tick(struct tick_sched *ts)
{
WARN_ON_ONCE(!irqs_disabled());
- if (tick_dep_mask) {
- trace_tick_dependency(tick_dep_mask);
+ if (check_tick_dependency(&tick_dep_mask))
return false;
- }
- if (ts->tick_dep_mask) {
- trace_tick_dependency(ts->tick_dep_mask);
+ if (check_tick_dependency(&ts->tick_dep_mask))
return false;
- }
- if (current->tick_dep_mask) {
- trace_tick_dependency(current->tick_dep_mask);
+ if (check_tick_dependency(¤t->tick_dep_mask))
return false;
- }
- if (current->signal->tick_dep_mask) {
- trace_tick_dependency(current->signal->tick_dep_mask);
+ if (check_tick_dependency(¤t->signal->tick_dep_mask))
return false;
- }
return true;
}
@@ -259,12 +257,12 @@ static void tick_nohz_full_kick_all(void)
preempt_enable();
}
-static void tick_nohz_dep_set_all(unsigned long *dep,
+static void tick_nohz_dep_set_all(atomic_t *dep,
enum tick_dep_bits bit)
{
- unsigned long prev;
+ int prev;
- prev = fetch_or(dep, BIT_MASK(bit));
+ prev = atomic_fetch_or(dep, BIT(bit));
if (!prev)
tick_nohz_full_kick_all();
}
@@ -280,7 +278,7 @@ void tick_nohz_dep_set(enum tick_dep_bits bit)
void tick_nohz_dep_clear(enum tick_dep_bits bit)
{
- clear_bit(bit, &tick_dep_mask);
+ atomic_andnot(BIT(bit), &tick_dep_mask);
}
/*
@@ -289,12 +287,12 @@ void tick_nohz_dep_clear(enum tick_dep_bits bit)
*/
void tick_nohz_dep_set_cpu(int cpu, enum tick_dep_bits bit)
{
- unsigned long prev;
+ int prev;
struct tick_sched *ts;
ts = per_cpu_ptr(&tick_cpu_sched, cpu);
- prev = fetch_or(&ts->tick_dep_mask, BIT_MASK(bit));
+ prev = atomic_fetch_or(&ts->tick_dep_mask, BIT(bit));
if (!prev) {
preempt_disable();
/* Perf needs local kick that is NMI safe */
@@ -313,7 +311,7 @@ void tick_nohz_dep_clear_cpu(int cpu, enum tick_dep_bits bit)
{
struct tick_sched *ts = per_cpu_ptr(&tick_cpu_sched, cpu);
- clear_bit(bit, &ts->tick_dep_mask);
+ atomic_andnot(BIT(bit), &ts->tick_dep_mask);
}
/*
@@ -331,7 +329,7 @@ void tick_nohz_dep_set_task(struct task_struct *tsk, enum tick_dep_bits bit)
void tick_nohz_dep_clear_task(struct task_struct *tsk, enum tick_dep_bits bit)
{
- clear_bit(bit, &tsk->tick_dep_mask);
+ atomic_andnot(BIT(bit), &tsk->tick_dep_mask);
}
/*
@@ -345,7 +343,7 @@ void tick_nohz_dep_set_signal(struct signal_struct *sig, enum tick_dep_bits bit)
void tick_nohz_dep_clear_signal(struct signal_struct *sig, enum tick_dep_bits bit)
{
- clear_bit(bit, &sig->tick_dep_mask);
+ atomic_andnot(BIT(bit), &sig->tick_dep_mask);
}
/*
@@ -366,7 +364,8 @@ void __tick_nohz_task_switch(void)
ts = this_cpu_ptr(&tick_cpu_sched);
if (ts->tick_stopped) {
- if (current->tick_dep_mask || current->signal->tick_dep_mask)
+ if (atomic_read(¤t->tick_dep_mask) ||
+ atomic_read(¤t->signal->tick_dep_mask))
tick_nohz_full_kick();
}
out:
diff --git a/kernel/time/tick-sched.h b/kernel/time/tick-sched.h
index eb4e32566a83..bf38226e5c17 100644
--- a/kernel/time/tick-sched.h
+++ b/kernel/time/tick-sched.h
@@ -60,7 +60,7 @@ struct tick_sched {
u64 next_timer;
ktime_t idle_expires;
int do_timer_last;
- unsigned long tick_dep_mask;
+ atomic_t tick_dep_mask;
};
extern struct tick_sched *tick_get_tick_sched(int cpu);
diff --git a/tools/lib/lockdep/run_tests.sh b/tools/lib/lockdep/run_tests.sh
index 5334ad9d39b7..1069d96248c1 100755
--- a/tools/lib/lockdep/run_tests.sh
+++ b/tools/lib/lockdep/run_tests.sh
@@ -3,7 +3,7 @@
make &> /dev/null
for i in `ls tests/*.c`; do
- testname=$(basename -s .c "$i")
+ testname=$(basename "$i" .c)
gcc -o tests/$testname -pthread -lpthread $i liblockdep.a -Iinclude -D__USE_LIBLOCKDEP &> /dev/null
echo -ne "$testname... "
if [ $(timeout 1 ./tests/$testname | wc -l) -gt 0 ]; then
@@ -11,11 +11,13 @@ for i in `ls tests/*.c`; do
else
echo "FAILED!"
fi
- rm tests/$testname
+ if [ -f "tests/$testname" ]; then
+ rm tests/$testname
+ fi
done
for i in `ls tests/*.c`; do
- testname=$(basename -s .c "$i")
+ testname=$(basename "$i" .c)
gcc -o tests/$testname -pthread -lpthread -Iinclude $i &> /dev/null
echo -ne "(PRELOAD) $testname... "
if [ $(timeout 1 ./lockdep ./tests/$testname | wc -l) -gt 0 ]; then
@@ -23,5 +25,7 @@ for i in `ls tests/*.c`; do
else
echo "FAILED!"
fi
- rm tests/$testname
+ if [ -f "tests/$testname" ]; then
+ rm tests/$testname
+ fi
done
next reply other threads:[~2016-04-03 10:45 UTC|newest]
Thread overview: 90+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-04-03 10:45 Ingo Molnar [this message]
-- strict thread matches above, loose matches on Subject: below --
2017-12-06 22:01 [GIT PULL] core kernel fixes Ingo Molnar
2017-11-05 14:33 Ingo Molnar
2017-11-05 18:09 ` Linus Torvalds
2017-11-05 19:53 ` Josh Poimboeuf
2017-11-05 20:12 ` Linus Torvalds
2017-11-05 21:01 ` Josh Poimboeuf
2017-07-21 10:01 Ingo Molnar
2016-10-18 10:14 Ingo Molnar
2016-07-13 10:55 Ingo Molnar
2015-02-06 18:28 Ingo Molnar
2012-10-23 10:57 Ingo Molnar
2012-08-03 16:31 Ingo Molnar
2012-08-03 16:55 ` Darren Hart
2012-08-03 17:01 ` Ingo Molnar
2012-08-03 17:24 ` Darren Hart
2012-06-15 18:45 Ingo Molnar
2012-01-26 18:05 Ingo Molnar
2011-08-04 20:45 Ingo Molnar
2011-04-02 10:21 Ingo Molnar
2011-03-25 12:52 Ingo Molnar
2011-01-21 2:11 Ingo Molnar
2011-01-15 15:15 Ingo Molnar
2010-10-05 19:12 Ingo Molnar
2010-10-05 20:15 ` Linus Torvalds
2010-10-05 21:09 ` Paul E. McKenney
2010-10-05 21:45 ` Linus Torvalds
2010-10-05 22:05 ` Paul E. McKenney
2010-10-06 2:56 ` Eric Dumazet
2010-10-06 4:59 ` Paul E. McKenney
2010-10-06 18:20 ` Ingo Molnar
2010-10-06 21:27 ` Paul E. McKenney
2010-10-07 8:11 ` Ingo Molnar
2010-10-07 17:42 ` Paul E. McKenney
2010-09-08 13:04 Ingo Molnar
2010-03-26 14:53 Ingo Molnar
2010-03-13 16:35 Ingo Molnar
2009-12-18 18:52 Ingo Molnar
2009-11-10 17:53 Ingo Molnar
2009-10-23 14:53 Ingo Molnar
2009-10-13 18:29 Ingo Molnar
2009-10-08 19:06 Ingo Molnar
2009-10-08 19:16 ` Linus Torvalds
2009-10-08 19:20 ` Ingo Molnar
2009-09-21 13:13 Ingo Molnar
2009-08-13 18:54 Ingo Molnar
2009-08-09 16:07 Ingo Molnar
2009-08-09 18:41 ` Darren Hart
2009-07-10 16:28 Ingo Molnar
2009-07-10 19:06 ` Linus Torvalds
2009-07-10 19:31 ` Ingo Molnar
2009-07-10 19:52 ` Linus Torvalds
2009-07-10 20:02 ` Ingo Molnar
2009-07-13 14:52 ` Joerg Roedel
2009-06-20 17:30 Ingo Molnar
2009-06-20 18:49 ` Linus Torvalds
2009-06-20 19:01 ` Linus Torvalds
2009-06-20 20:27 ` Ingo Molnar
2009-06-21 17:12 ` Thomas Gleixner
2009-06-21 17:37 ` Linus Torvalds
2009-06-21 17:57 ` Linus Torvalds
2009-06-21 19:26 ` Thomas Gleixner
2009-05-18 14:23 Ingo Molnar
2009-05-18 15:48 ` Linus Torvalds
2009-05-18 19:20 ` Thomas Gleixner
2009-05-19 20:52 ` Linus Torvalds
2009-05-19 21:45 ` Thomas Gleixner
2009-05-19 22:20 ` Darren Hart
2009-05-05 9:33 Ingo Molnar
2009-01-30 23:12 [git pull] " Ingo Molnar
2009-01-26 17:24 Ingo Molnar
2009-01-11 14:36 Ingo Molnar
2008-12-04 19:39 Ingo Molnar
2008-11-29 19:36 Ingo Molnar
2008-11-18 14:14 Ingo Molnar
2008-11-07 16:28 Ingo Molnar
2008-10-30 23:29 Ingo Molnar
2008-10-15 12:50 [git pull] core kernel updates for v2.6.28 Ingo Molnar
2008-10-16 22:32 ` Linus Torvalds
2008-10-17 6:23 ` [git pull] core kernel fixes Ingo Molnar
2008-08-28 11:44 Ingo Molnar
2008-08-18 18:35 Ingo Molnar
2008-07-24 15:13 Ingo Molnar
2008-06-30 15:32 Ingo Molnar
2008-06-30 17:02 ` Vegard Nossum
2008-06-30 18:20 ` Ingo Molnar
2008-06-30 18:43 ` Vegard Nossum
2008-06-30 19:46 ` Thomas Gleixner
2008-06-30 19:51 ` Vegard Nossum
2008-06-30 19:54 ` Thomas Gleixner
2008-06-23 19:45 Ingo Molnar
2008-06-19 15:16 Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160403104536.GA16924@gmail.com \
--to=mingo@kernel.org \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=fweisbec@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.