* [PATCH v5 0/9] cross-release: Enhence performance and fix false positives
@ 2017-10-25 8:55 Byungchul Park
2017-10-25 8:55 ` [PATCH v5 1/9] block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait Byungchul Park
` (8 more replies)
0 siblings, 9 replies; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:55 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
Changes from v4
- Use a prefix "(completion)" instead of "(complete)" for completions
- Use a prefix "(wq_completion)" instead of "(complete)" for workqueue's map
- Use a prefix "(work_completion)" instead of "(complete)" for work's map
- Use a prefix "(gendisk_completion)" instead of "(complete)" for gendisk's map
- Provide empty lockdep_map structure for !CONFIG_LOCKDEP
- Remove #ifdef in this series as much as possible
- Use canocical variable names in all_disk_node() macro
Changes from v3
- Exclude a patch removing white space
- Enhance commit messages as Ingo suggested
- Re-design patches adding a boot param and a Kconfig allowing unwind
- Simplify a patch assigning lock classes to genhds as Ingo suggested
- Add proper tags in commit messages e.g. reported-by and analyzed-by
Changes from v2
- Combine 2 serises, fixing false positives and enhance performance
- Add Christoph Hellwig's patch simplifying submit_bio_wait() code
- Add 2 more 'init with lockdep map' macros for completionm
- Rename init_completion_with_map() to init_completion_map()
Changes from v1
- Fix kconfig description as Ingo suggested
- Fix commit message writing out CONFIG_ variable
- Introduce a new kernel parameter, crossrelease_fullstack
- Replace the number with the output of *perf*
- Separate a patch removing white space
Byungchul Park (8):
locking/lockdep: Provide empty lockdep_map structure for
!CONFIG_LOCKDEP
completion: Change the prefix of lock name for completion variable
locking/lockdep: Add a boot parameter allowing unwind in cross-release
and disable it by default
locking/lockdep: Remove the BROKEN flag from
CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS
locking/lockdep: Introduce
CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
completion: Add support for initializing completion with lockdep_map
workqueue: Remove unnecessary acquisitions wrt workqueue flush
block: Assign a lock_class per gendisk used for wait_for_completion()
Christoph Hellwig (1):
block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait
Documentation/admin-guide/kernel-parameters.txt | 3 +++
block/bio.c | 19 +++++--------------
block/genhd.c | 10 ++--------
include/linux/completion.h | 18 ++++++++++++++++--
include/linux/genhd.h | 22 ++++++++++++++++++++--
include/linux/lockdep.h | 5 +++++
include/linux/workqueue.h | 4 ++--
kernel/locking/lockdep.c | 23 +++++++++++++++++++++--
kernel/workqueue.c | 19 +++----------------
lib/Kconfig.debug | 19 +++++++++++++++++--
10 files changed, 94 insertions(+), 48 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH v5 1/9] block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
@ 2017-10-25 8:55 ` Byungchul Park
2017-10-25 11:10 ` [tip:locking/core] block: Use DECLARE_COMPLETION_ONSTACK() in submit_bio_wait() tip-bot for Christoph Hellwig
2017-10-25 8:55 ` [PATCH v5 2/9] locking/lockdep: Provide empty lockdep_map structure for !CONFIG_LOCKDEP Byungchul Park
` (7 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:55 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team, Christoph Hellwig
From: Christoph Hellwig <hch@lst.de>
Simplify the code by getting rid of the submit_bio_ret structure.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
block/bio.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 5f5472e..99d0ca5 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -917,17 +917,9 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
}
EXPORT_SYMBOL_GPL(bio_iov_iter_get_pages);
-struct submit_bio_ret {
- struct completion event;
- int error;
-};
-
static void submit_bio_wait_endio(struct bio *bio)
{
- struct submit_bio_ret *ret = bio->bi_private;
-
- ret->error = blk_status_to_errno(bio->bi_status);
- complete(&ret->event);
+ complete(bio->bi_private);
}
/**
@@ -943,16 +935,15 @@ static void submit_bio_wait_endio(struct bio *bio)
*/
int submit_bio_wait(struct bio *bio)
{
- struct submit_bio_ret ret;
+ DECLARE_COMPLETION_ONSTACK(done);
- init_completion(&ret.event);
- bio->bi_private = &ret;
+ bio->bi_private = &done;
bio->bi_end_io = submit_bio_wait_endio;
bio->bi_opf |= REQ_SYNC;
submit_bio(bio);
- wait_for_completion_io(&ret.event);
+ wait_for_completion_io(&done);
- return ret.error;
+ return blk_status_to_errno(bio->bi_status);
}
EXPORT_SYMBOL(submit_bio_wait);
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v5 2/9] locking/lockdep: Provide empty lockdep_map structure for !CONFIG_LOCKDEP
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
2017-10-25 8:55 ` [PATCH v5 1/9] block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait Byungchul Park
@ 2017-10-25 8:55 ` Byungchul Park
2017-10-25 11:11 ` [tip:locking/core] " tip-bot for Byungchul Park
2017-10-25 8:55 ` [PATCH v5 3/9] completion: Change the prefix of lock name for completion variable Byungchul Park
` (6 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:55 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
By this patch, the lockdep_map structure takes no space if lockdep is
disabled, making a debug facility's impact on unreleated kernel less.
Thanks to this, we don't need #ifdef to sparate code due to the
lockdep_map structure.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
include/linux/lockdep.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index bfa8e0b..b6662d0 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -527,6 +527,11 @@ static inline void lockdep_on(void)
*/
struct lock_class_key { };
+/*
+ * The lockdep_map takes no space if lockdep is disabled:
+ */
+struct lockdep_map { };
+
#define lockdep_depth(tsk) (0)
#define lockdep_is_held_type(l, r) (1)
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v5 3/9] completion: Change the prefix of lock name for completion variable
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
2017-10-25 8:55 ` [PATCH v5 1/9] block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait Byungchul Park
2017-10-25 8:55 ` [PATCH v5 2/9] locking/lockdep: Provide empty lockdep_map structure for !CONFIG_LOCKDEP Byungchul Park
@ 2017-10-25 8:55 ` Byungchul Park
2017-10-25 11:11 ` [tip:locking/core] locking/lockdep, sched/completions: Change the prefix of lock name for completion variables tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 4/9] locking/lockdep: Add a boot parameter allowing unwind in cross-release and disable it by default Byungchul Park
` (5 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:55 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
CONFIG_LOCKDEP_COMPLETIONS uses "(complete)" as a prefix of lock name
for completion variable.
However, "complete" is a verb or adjective and lock symbol names
should be nouns. Use "(completion)" instead, for normal completions.
Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
include/linux/completion.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/completion.h b/include/linux/completion.h
index cae5400..9121803 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -53,7 +53,7 @@ static inline void complete_release_commit(struct completion *x)
do { \
static struct lock_class_key __key; \
lockdep_init_map_crosslock((struct lockdep_map *)&(x)->map, \
- "(complete)" #x, \
+ "(completion)" #x, \
&__key, 0); \
__init_completion(x); \
} while (0)
@@ -67,7 +67,7 @@ static inline void complete_release_commit(struct completion *x) {}
#ifdef CONFIG_LOCKDEP_COMPLETIONS
#define COMPLETION_INITIALIZER(work) \
{ 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait), \
- STATIC_CROSS_LOCKDEP_MAP_INIT("(complete)" #work, &(work)) }
+ STATIC_CROSS_LOCKDEP_MAP_INIT("(completion)" #work, &(work)) }
#else
#define COMPLETION_INITIALIZER(work) \
{ 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v5 4/9] locking/lockdep: Add a boot parameter allowing unwind in cross-release and disable it by default
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
` (2 preceding siblings ...)
2017-10-25 8:55 ` [PATCH v5 3/9] completion: Change the prefix of lock name for completion variable Byungchul Park
@ 2017-10-25 8:56 ` Byungchul Park
2017-10-25 11:11 ` [tip:locking/core] " tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 5/9] locking/lockdep: Remove the BROKEN flag from CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS Byungchul Park
` (4 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:56 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
Johan Hovold reported a heavy performance regression caused by lockdep
cross-release:
> Boot time (from "Linux version" to login prompt) had in fact doubled
> since 4.13 where it took 17 seconds (with my current config) compared to
> the 35 seconds I now see with 4.14-rc4.
>
> I quick bisect pointed to lockdep and specifically the following commit:
>
> 28a903f63ec0 ("locking/lockdep: Handle non(or multi)-acquisition
> of a crosslock")
>
> which I've verified is the commit which doubled the boot time (compared
> to 28a903f63ec0^) (added by lockdep crossrelease series [1]).
Currently cross-release performs unwind on every acquisition, but that
is very expensive.
This patch makes unwind optional and disables it by default and only
records acquire_ip.
Full stack traces are sometimes required for full analysis, in which
case a boot paramter, crossrelease_fullstack, can be specified.
On my qemu Ubuntu machine (x86_64, 4 cores, 512M), the regression was
fixed. We measure boot times with 'perf stat --null --repeat 10 $QEMU',
where $QEMU launches a kernel with init=/bin/true:
1. No lockdep enabled:
Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):
2.756558155 seconds time elapsed ( +- 0.09% )
2. Lockdep enabled:
Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):
2.968710420 seconds time elapsed ( +- 0.12% )
3. Lockdep enabled + cross-release enabled:
Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):
3.153839636 seconds time elapsed ( +- 0.31% )
4. Lockdep enabled + cross-release enabled + this patch applied:
Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):
2.963669551 seconds time elapsed ( +- 0.11% )
I.e. lockdep cross-release performance is now indistinguishable from
vanilla lockdep.
Reported-by: Johan Hovold <johan@kernel.org>
Bisected-by: Johan Hovold <johan@kernel.org>
Analyzed-by: Thomas Gleixner <tglx@linutronix.de>
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
Documentation/admin-guide/kernel-parameters.txt | 3 +++
kernel/locking/lockdep.c | 19 +++++++++++++++++--
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index ead7f40..4107b01 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -709,6 +709,9 @@
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
+ crossrelease_fullstack
+ [KNL] Allow to record full stack trace in cross-release
+
cryptomgr.notests
[KNL] Disable crypto self-tests
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e36e652..160b5d6 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -76,6 +76,15 @@
#define lock_stat 0
#endif
+static int crossrelease_fullstack;
+static int __init allow_crossrelease_fullstack(char *str)
+{
+ crossrelease_fullstack = 1;
+ return 0;
+}
+
+early_param("crossrelease_fullstack", allow_crossrelease_fullstack);
+
/*
* lockdep_lock: protects the lockdep graph, the hashes and the
* class/list/hash allocators.
@@ -4863,8 +4872,14 @@ static void add_xhlock(struct held_lock *hlock)
xhlock->trace.nr_entries = 0;
xhlock->trace.max_entries = MAX_XHLOCK_TRACE_ENTRIES;
xhlock->trace.entries = xhlock->trace_entries;
- xhlock->trace.skip = 3;
- save_stack_trace(&xhlock->trace);
+
+ if (crossrelease_fullstack) {
+ xhlock->trace.skip = 3;
+ save_stack_trace(&xhlock->trace);
+ } else {
+ xhlock->trace.nr_entries = 1;
+ xhlock->trace.entries[0] = hlock->acquire_ip;
+ }
}
static inline int same_context_xhlock(struct hist_lock *xhlock)
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v5 5/9] locking/lockdep: Remove the BROKEN flag from CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
` (3 preceding siblings ...)
2017-10-25 8:56 ` [PATCH v5 4/9] locking/lockdep: Add a boot parameter allowing unwind in cross-release and disable it by default Byungchul Park
@ 2017-10-25 8:56 ` Byungchul Park
2017-10-25 11:12 ` [tip:locking/core] " tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 6/9] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK Byungchul Park
` (3 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:56 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
Now that the performance regression is fixed, re-enable
CONFIG_LOCKDEP_CROSSRELEASE=y and CONFIG_LOCKDEP_COMPLETIONS=y.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
lib/Kconfig.debug | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 3db9167..4bef610 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1138,8 +1138,8 @@ config PROVE_LOCKING
select DEBUG_MUTEXES
select DEBUG_RT_MUTEXES if RT_MUTEXES
select DEBUG_LOCK_ALLOC
- select LOCKDEP_CROSSRELEASE if BROKEN
- select LOCKDEP_COMPLETIONS if BROKEN
+ select LOCKDEP_CROSSRELEASE
+ select LOCKDEP_COMPLETIONS
select TRACE_IRQFLAGS
default n
help
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v5 6/9] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
` (4 preceding siblings ...)
2017-10-25 8:56 ` [PATCH v5 5/9] locking/lockdep: Remove the BROKEN flag from CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS Byungchul Park
@ 2017-10-25 8:56 ` Byungchul Park
2017-10-25 11:12 ` [tip:locking/core] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK=y tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 7/9] completion: Add support for initializing completion with lockdep_map Byungchul Park
` (2 subsequent siblings)
8 siblings, 1 reply; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:56 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
The boot parameter, crossrelease_fullstack, was introduced to control
whether to enable unwind in cross-release or not. Add a Kconfig doing
the same thing.
Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
kernel/locking/lockdep.c | 4 ++++
lib/Kconfig.debug | 15 +++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 160b5d6..db933d0 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -76,7 +76,11 @@
#define lock_stat 0
#endif
+#ifdef CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
+static int crossrelease_fullstack = 1;
+#else
static int crossrelease_fullstack;
+#endif
static int __init allow_crossrelease_fullstack(char *str)
{
crossrelease_fullstack = 1;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 4bef610..e4b54a5 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1225,6 +1225,21 @@ config LOCKDEP_COMPLETIONS
A deadlock caused by wait_for_completion() and complete() can be
detected by lockdep using crossrelease feature.
+config BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
+ bool "Enable the boot parameter, crossrelease_fullstack"
+ depends on LOCKDEP_CROSSRELEASE
+ default n
+ help
+ The lockdep "cross-release" feature needs to record stack traces
+ (of calling functions) for all acquisitions, for eventual later
+ use during analysis. By default only a single caller is recorded,
+ because the unwind operation can be very expensive with deeper
+ stack chains.
+
+ However a boot parameter, crossrelease_fullstack, was
+ introduced since sometimes deeper traces are required for full
+ analysis. This option turns on the boot parameter.
+
config DEBUG_LOCKDEP
bool "Lock dependency engine debugging"
depends on DEBUG_KERNEL && LOCKDEP
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v5 7/9] completion: Add support for initializing completion with lockdep_map
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
` (5 preceding siblings ...)
2017-10-25 8:56 ` [PATCH v5 6/9] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK Byungchul Park
@ 2017-10-25 8:56 ` Byungchul Park
2017-10-25 11:12 ` [tip:locking/core] sched/completions: Add support for initializing completions " tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 8/9] workqueue: Remove unnecessary acquisitions wrt workqueue flush Byungchul Park
2017-10-25 8:56 ` [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion() Byungchul Park
8 siblings, 1 reply; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:56 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
Sometimes, we want to initialize completions with sparate lockdep maps
to assign lock classes as desired. For example, the workqueue code
needs to directly manage lockdep maps, since only the code is aware of
how to classify lockdep maps properly.
Provide additional macros initializing completions in that way.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
include/linux/completion.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/linux/completion.h b/include/linux/completion.h
index 9121803..4da4991 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -49,6 +49,13 @@ static inline void complete_release_commit(struct completion *x)
lock_commit_crosslock((struct lockdep_map *)&x->map);
}
+#define init_completion_map(x, m) \
+do { \
+ lockdep_init_map_crosslock((struct lockdep_map *)&(x)->map, \
+ (m)->name, (m)->key, 0); \
+ __init_completion(x); \
+} while (0)
+
#define init_completion(x) \
do { \
static struct lock_class_key __key; \
@@ -58,6 +65,7 @@ static inline void complete_release_commit(struct completion *x)
__init_completion(x); \
} while (0)
#else
+#define init_completion_map(x, m) __init_completion(x)
#define init_completion(x) __init_completion(x)
static inline void complete_acquire(struct completion *x) {}
static inline void complete_release(struct completion *x) {}
@@ -73,6 +81,9 @@ static inline void complete_release_commit(struct completion *x) {}
{ 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
#endif
+#define COMPLETION_INITIALIZER_ONSTACK_MAP(work, map) \
+ (*({ init_completion_map(&(work), &(map)); &(work); }))
+
#define COMPLETION_INITIALIZER_ONSTACK(work) \
(*({ init_completion(&work); &work; }))
@@ -102,8 +113,11 @@ static inline void complete_release_commit(struct completion *x) {}
#ifdef CONFIG_LOCKDEP
# define DECLARE_COMPLETION_ONSTACK(work) \
struct completion work = COMPLETION_INITIALIZER_ONSTACK(work)
+# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) \
+ struct completion work = COMPLETION_INITIALIZER_ONSTACK_MAP(work, map)
#else
# define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
+# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) DECLARE_COMPLETION(work)
#endif
/**
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v5 8/9] workqueue: Remove unnecessary acquisitions wrt workqueue flush
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
` (6 preceding siblings ...)
2017-10-25 8:56 ` [PATCH v5 7/9] completion: Add support for initializing completion with lockdep_map Byungchul Park
@ 2017-10-25 8:56 ` Byungchul Park
2017-10-25 11:13 ` [tip:locking/core] workqueue: Remove now redundant lock acquisitions wrt. workqueue flushes tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion() Byungchul Park
8 siblings, 1 reply; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:56 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
The workqueue added manual acquisitions to catch deadlock cases.
Now crossrelease was introduced, some of those are redundant, since
wait_for_completion() already includes the acquisition for itself.
Remove it.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
include/linux/workqueue.h | 4 ++--
kernel/workqueue.c | 19 +++----------------
2 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index f3c47a0..0544ad3 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -218,7 +218,7 @@ static inline void destroy_delayed_work_on_stack(struct delayed_work *work) { }
\
__init_work((_work), _onstack); \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
- lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0); \
+ lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, &__key, 0); \
INIT_LIST_HEAD(&(_work)->entry); \
(_work)->func = (_func); \
} while (0)
@@ -399,7 +399,7 @@ enum {
static struct lock_class_key __key; \
const char *__lock_name; \
\
- __lock_name = #fmt#args; \
+ __lock_name = "(wq_completion)"#fmt#args; \
\
__alloc_workqueue_key((fmt), (flags), (max_active), \
&__key, __lock_name, ##args); \
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index c77fdf6..ee05d19 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2496,15 +2496,8 @@ static void insert_wq_barrier(struct pool_workqueue *pwq,
INIT_WORK_ONSTACK(&barr->work, wq_barrier_func);
__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&barr->work));
- /*
- * Explicitly init the crosslock for wq_barrier::done, make its lock
- * key a subkey of the corresponding work. As a result we won't
- * build a dependency between wq_barrier::done and unrelated work.
- */
- lockdep_init_map_crosslock((struct lockdep_map *)&barr->done.map,
- "(complete)wq_barr::done",
- target->lockdep_map.key, 1);
- __init_completion(&barr->done);
+ init_completion_map(&barr->done, &target->lockdep_map);
+
barr->task = current;
/*
@@ -2610,16 +2603,13 @@ void flush_workqueue(struct workqueue_struct *wq)
struct wq_flusher this_flusher = {
.list = LIST_HEAD_INIT(this_flusher.list),
.flush_color = -1,
- .done = COMPLETION_INITIALIZER_ONSTACK(this_flusher.done),
+ .done = COMPLETION_INITIALIZER_ONSTACK_MAP(this_flusher.done, wq->lockdep_map),
};
int next_color;
if (WARN_ON(!wq_online))
return;
- lock_map_acquire(&wq->lockdep_map);
- lock_map_release(&wq->lockdep_map);
-
mutex_lock(&wq->mutex);
/*
@@ -2882,9 +2872,6 @@ bool flush_work(struct work_struct *work)
if (WARN_ON(!wq_online))
return false;
- lock_map_acquire(&work->lockdep_map);
- lock_map_release(&work->lockdep_map);
-
if (start_flush_work(work, &barr)) {
wait_for_completion(&barr.done);
destroy_work_on_stack(&barr.work);
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion()
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
` (7 preceding siblings ...)
2017-10-25 8:56 ` [PATCH v5 8/9] workqueue: Remove unnecessary acquisitions wrt workqueue flush Byungchul Park
@ 2017-10-25 8:56 ` Byungchul Park
2017-10-25 10:13 ` Ingo Molnar
2017-10-26 9:31 ` [tip:locking/core] block, locking/lockdep: " tip-bot for Byungchul Park
8 siblings, 2 replies; 23+ messages in thread
From: Byungchul Park @ 2017-10-25 8:56 UTC (permalink / raw)
To: peterz, mingo, axboe
Cc: johan, tglx, linux-kernel, linux-mm, tj, johannes.berg, oleg,
amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
Darrick posted the following warning and Dave Chinner analyzed it:
> ======================================================
> WARNING: possible circular locking dependency detected
> 4.14.0-rc1-fixes #1 Tainted: G W
> ------------------------------------------------------
> loop0/31693 is trying to acquire lock:
> (&(&ip->i_mmaplock)->mr_lock){++++}, at: [<ffffffffa00f1b0c>] xfs_ilock+0x23c/0x330 [xfs]
>
> but now in release context of a crosslock acquired at the following:
> ((complete)&ret.event){+.+.}, at: [<ffffffff81326c1f>] submit_bio_wait+0x7f/0xb0
>
> which lock already depends on the new lock.
>
> the existing dependency chain (in reverse order) is:
>
> -> #2 ((complete)&ret.event){+.+.}:
> lock_acquire+0xab/0x200
> wait_for_completion_io+0x4e/0x1a0
> submit_bio_wait+0x7f/0xb0
> blkdev_issue_zeroout+0x71/0xa0
> xfs_bmapi_convert_unwritten+0x11f/0x1d0 [xfs]
> xfs_bmapi_write+0x374/0x11f0 [xfs]
> xfs_iomap_write_direct+0x2ac/0x430 [xfs]
> xfs_file_iomap_begin+0x20d/0xd50 [xfs]
> iomap_apply+0x43/0xe0
> dax_iomap_rw+0x89/0xf0
> xfs_file_dax_write+0xcc/0x220 [xfs]
> xfs_file_write_iter+0xf0/0x130 [xfs]
> __vfs_write+0xd9/0x150
> vfs_write+0xc8/0x1c0
> SyS_write+0x45/0xa0
> entry_SYSCALL_64_fastpath+0x1f/0xbe
>
> -> #1 (&xfs_nondir_ilock_class){++++}:
> lock_acquire+0xab/0x200
> down_write_nested+0x4a/0xb0
> xfs_ilock+0x263/0x330 [xfs]
> xfs_setattr_size+0x152/0x370 [xfs]
> xfs_vn_setattr+0x6b/0x90 [xfs]
> notify_change+0x27d/0x3f0
> do_truncate+0x5b/0x90
> path_openat+0x237/0xa90
> do_filp_open+0x8a/0xf0
> do_sys_open+0x11c/0x1f0
> entry_SYSCALL_64_fastpath+0x1f/0xbe
>
> -> #0 (&(&ip->i_mmaplock)->mr_lock){++++}:
> up_write+0x1c/0x40
> xfs_iunlock+0x1d0/0x310 [xfs]
> xfs_file_fallocate+0x8a/0x310 [xfs]
> loop_queue_work+0xb7/0x8d0
> kthread_worker_fn+0xb9/0x1f0
>
> Chain exists of:
> &(&ip->i_mmaplock)->mr_lock --> &xfs_nondir_ilock_class --> (complete)&ret.event
>
> Possible unsafe locking scenario by crosslock:
>
> CPU0 CPU1
> ---- ----
> lock(&xfs_nondir_ilock_class);
> lock((complete)&ret.event);
> lock(&(&ip->i_mmaplock)->mr_lock);
> unlock((complete)&ret.event);
>
> *** DEADLOCK ***
The warning is a false positive, caused by the fact that all
wait_for_completion()s in submit_bio_wait() are waiting with the same
lock class.
However, some bios have nothing to do with others, for example, the case
might happen while using loop devices, between bios of an upper device
and a lower device(=loop device).
The safest way to assign different lock classes to different devices is
to do it for each gendisk. In other words, this patch assigns a
lockdep_map per gendisk and uses it when initializing completion in
submit_bio_wait().
Of course, it might be too conservative. But, making it safest for now
and extended by block layer experts later is good, at the moment.
Reported-by: Darrick J. Wong <darrick.wong@oracle.com>
Analyzed-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
---
block/bio.c | 2 +-
block/genhd.c | 10 ++--------
include/linux/genhd.h | 22 ++++++++++++++++++++--
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 99d0ca5..a3cb1d1 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -935,7 +935,7 @@ static void submit_bio_wait_endio(struct bio *bio)
*/
int submit_bio_wait(struct bio *bio)
{
- DECLARE_COMPLETION_ONSTACK(done);
+ DECLARE_COMPLETION_ONSTACK_MAP(done, bio->bi_disk->lockdep_map);
bio->bi_private = &done;
bio->bi_end_io = submit_bio_wait_endio;
diff --git a/block/genhd.c b/block/genhd.c
index dd305c6..630c0da 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1354,13 +1354,7 @@ dev_t blk_lookup_devt(const char *name, int partno)
}
EXPORT_SYMBOL(blk_lookup_devt);
-struct gendisk *alloc_disk(int minors)
-{
- return alloc_disk_node(minors, NUMA_NO_NODE);
-}
-EXPORT_SYMBOL(alloc_disk);
-
-struct gendisk *alloc_disk_node(int minors, int node_id)
+struct gendisk *__alloc_disk_node(int minors, int node_id)
{
struct gendisk *disk;
struct disk_part_tbl *ptbl;
@@ -1411,7 +1405,7 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
}
return disk;
}
-EXPORT_SYMBOL(alloc_disk_node);
+EXPORT_SYMBOL(__alloc_disk_node);
struct kobject *get_disk(struct gendisk *disk)
{
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 6d85a75..6c24b04 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -206,6 +206,7 @@ struct gendisk {
#endif /* CONFIG_BLK_DEV_INTEGRITY */
int node_id;
struct badblocks *bb;
+ struct lockdep_map lockdep_map;
};
static inline struct gendisk *part_to_disk(struct hd_struct *part)
@@ -590,8 +591,7 @@ extern struct hd_struct * __must_check add_partition(struct gendisk *disk,
extern void delete_partition(struct gendisk *, int);
extern void printk_all_partitions(void);
-extern struct gendisk *alloc_disk_node(int minors, int node_id);
-extern struct gendisk *alloc_disk(int minors);
+extern struct gendisk *__alloc_disk_node(int minors, int node_id);
extern struct kobject *get_disk(struct gendisk *disk);
extern void put_disk(struct gendisk *disk);
extern void blk_register_region(dev_t devt, unsigned long range,
@@ -615,6 +615,24 @@ extern ssize_t part_fail_store(struct device *dev,
const char *buf, size_t count);
#endif /* CONFIG_FAIL_MAKE_REQUEST */
+#define alloc_disk_node(minors, node_id) \
+({ \
+ static struct lock_class_key __key; \
+ const char *__name; \
+ struct gendisk *__disk; \
+ \
+ __name = "(gendisk_completion)"#minors"("#node_id")"; \
+ \
+ __disk = __alloc_disk_node(minors, node_id); \
+ \
+ if (__disk) \
+ lockdep_init_map(&__disk->lockdep_map, __name, &__key, 0); \
+ \
+ __disk; \
+})
+
+#define alloc_disk(minors) alloc_disk_node(minors, NUMA_NO_NODE)
+
static inline int hd_ref_init(struct hd_struct *part)
{
if (percpu_ref_init(&part->ref, __delete_partition, 0,
--
1.9.1
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion()
2017-10-25 8:56 ` [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion() Byungchul Park
@ 2017-10-25 10:13 ` Ingo Molnar
2017-10-25 18:20 ` Jens Axboe
2017-10-26 9:31 ` [tip:locking/core] block, locking/lockdep: " tip-bot for Byungchul Park
1 sibling, 1 reply; 23+ messages in thread
From: Ingo Molnar @ 2017-10-25 10:13 UTC (permalink / raw)
To: Byungchul Park, Jens Axboe
Cc: peterz, axboe, johan, tglx, linux-kernel, linux-mm, tj,
johannes.berg, oleg, amir73il, david, darrick.wong, linux-xfs,
linux-fsdevel, linux-block, hch, idryomov, kernel-team
* Byungchul Park <byungchul.park@lge.com> wrote:
> Darrick posted the following warning and Dave Chinner analyzed it:
>
> > ======================================================
> > WARNING: possible circular locking dependency detected
> > 4.14.0-rc1-fixes #1 Tainted: G W
> Reported-by: Darrick J. Wong <darrick.wong@oracle.com>
> Analyzed-by: Dave Chinner <david@fromorbit.com>
> Signed-off-by: Byungchul Park <byungchul.park@lge.com>
> ---
> block/bio.c | 2 +-
> block/genhd.c | 10 ++--------
> include/linux/genhd.h | 22 ++++++++++++++++++++--
> 3 files changed, 23 insertions(+), 11 deletions(-)
Ok, this patch looks good to me now, I'll wait to get an Ack or Nak from Jens for
these changes.
Jens: this patch has some dependencies in prior lockdep changes, so I'd like to
carry it in the locking tree for a v4.15 merge.
Thanks,
Ingo
^ permalink raw reply [flat|nested] 23+ messages in thread
* [tip:locking/core] block: Use DECLARE_COMPLETION_ONSTACK() in submit_bio_wait()
2017-10-25 8:55 ` [PATCH v5 1/9] block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait Byungchul Park
@ 2017-10-25 11:10 ` tip-bot for Christoph Hellwig
0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Christoph Hellwig @ 2017-10-25 11:10 UTC (permalink / raw)
To: linux-tip-commits; +Cc: linux-kernel, tglx, peterz, hch, hpa, torvalds, mingo
Commit-ID: 65e53aab6d54385dea799356defcbdcc456fb1a7
Gitweb: https://git.kernel.org/tip/65e53aab6d54385dea799356defcbdcc456fb1a7
Author: Christoph Hellwig <hch@lst.de>
AuthorDate: Wed, 25 Oct 2017 17:55:57 +0900
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 25 Oct 2017 12:18:59 +0200
block: Use DECLARE_COMPLETION_ONSTACK() in submit_bio_wait()
Simplify the code by getting rid of the submit_bio_ret structure.
(This also helps address a lockdep false positive.)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: amir73il@gmail.com
Cc: axboe@kernel.dk
Cc: darrick.wong@oracle.com
Cc: david@fromorbit.com
Cc: hch@infradead.org
Cc: idryomov@gmail.com
Cc: johan@kernel.org
Cc: johannes.berg@intel.com
Cc: kernel-team@lge.com
Cc: linux-block@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-xfs@vger.kernel.org
Cc: oleg@redhat.com
Cc: tj@kernel.org
Link: http://lkml.kernel.org/r/1508921765-15396-2-git-send-email-byungchul.park@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
block/bio.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 101c2a9..5e901bf 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -917,17 +917,9 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
}
EXPORT_SYMBOL_GPL(bio_iov_iter_get_pages);
-struct submit_bio_ret {
- struct completion event;
- int error;
-};
-
static void submit_bio_wait_endio(struct bio *bio)
{
- struct submit_bio_ret *ret = bio->bi_private;
-
- ret->error = blk_status_to_errno(bio->bi_status);
- complete(&ret->event);
+ complete(bio->bi_private);
}
/**
@@ -943,16 +935,15 @@ static void submit_bio_wait_endio(struct bio *bio)
*/
int submit_bio_wait(struct bio *bio)
{
- struct submit_bio_ret ret;
+ DECLARE_COMPLETION_ONSTACK(done);
- init_completion(&ret.event);
- bio->bi_private = &ret;
+ bio->bi_private = &done;
bio->bi_end_io = submit_bio_wait_endio;
bio->bi_opf |= REQ_SYNC;
submit_bio(bio);
- wait_for_completion_io(&ret.event);
+ wait_for_completion_io(&done);
- return ret.error;
+ return blk_status_to_errno(bio->bi_status);
}
EXPORT_SYMBOL(submit_bio_wait);
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:locking/core] locking/lockdep: Provide empty lockdep_map structure for !CONFIG_LOCKDEP
2017-10-25 8:55 ` [PATCH v5 2/9] locking/lockdep: Provide empty lockdep_map structure for !CONFIG_LOCKDEP Byungchul Park
@ 2017-10-25 11:11 ` tip-bot for Byungchul Park
0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Byungchul Park @ 2017-10-25 11:11 UTC (permalink / raw)
To: linux-tip-commits
Cc: mingo, byungchul.park, peterz, tglx, linux-kernel, hpa, torvalds
Commit-ID: 6f0397d7e100f3b3978d6ebb6b2dea29ee7c4a95
Gitweb: https://git.kernel.org/tip/6f0397d7e100f3b3978d6ebb6b2dea29ee7c4a95
Author: Byungchul Park <byungchul.park@lge.com>
AuthorDate: Wed, 25 Oct 2017 17:55:58 +0900
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 25 Oct 2017 12:19:00 +0200
locking/lockdep: Provide empty lockdep_map structure for !CONFIG_LOCKDEP
After this patch the lockdep_map structure takes no space if lockdep is
disabled, reducing the number of #ifdefs in unrelated kernel code.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: amir73il@gmail.com
Cc: axboe@kernel.dk
Cc: darrick.wong@oracle.com
Cc: david@fromorbit.com
Cc: hch@infradead.org
Cc: idryomov@gmail.com
Cc: johan@kernel.org
Cc: johannes.berg@intel.com
Cc: kernel-team@lge.com
Cc: linux-block@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-xfs@vger.kernel.org
Cc: oleg@redhat.com
Cc: tj@kernel.org
Link: http://lkml.kernel.org/r/1508921765-15396-3-git-send-email-byungchul.park@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
include/linux/lockdep.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h
index bfa8e0b..b6662d0 100644
--- a/include/linux/lockdep.h
+++ b/include/linux/lockdep.h
@@ -527,6 +527,11 @@ static inline void lockdep_on(void)
*/
struct lock_class_key { };
+/*
+ * The lockdep_map takes no space if lockdep is disabled:
+ */
+struct lockdep_map { };
+
#define lockdep_depth(tsk) (0)
#define lockdep_is_held_type(l, r) (1)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:locking/core] locking/lockdep, sched/completions: Change the prefix of lock name for completion variables
2017-10-25 8:55 ` [PATCH v5 3/9] completion: Change the prefix of lock name for completion variable Byungchul Park
@ 2017-10-25 11:11 ` tip-bot for Byungchul Park
0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Byungchul Park @ 2017-10-25 11:11 UTC (permalink / raw)
To: linux-tip-commits
Cc: torvalds, byungchul.park, linux-kernel, peterz, tglx, hpa, mingo
Commit-ID: 24208435e343679b21502fb90786084dfaf15369
Gitweb: https://git.kernel.org/tip/24208435e343679b21502fb90786084dfaf15369
Author: Byungchul Park <byungchul.park@lge.com>
AuthorDate: Wed, 25 Oct 2017 17:55:59 +0900
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 25 Oct 2017 12:19:00 +0200
locking/lockdep, sched/completions: Change the prefix of lock name for completion variables
CONFIG_LOCKDEP_COMPLETIONS uses "(complete)" as a prefix of lock name
for completion variable.
However, what we should use here is a noun - so use "(completion)" instead.
Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: amir73il@gmail.com
Cc: axboe@kernel.dk
Cc: darrick.wong@oracle.com
Cc: david@fromorbit.com
Cc: hch@infradead.org
Cc: idryomov@gmail.com
Cc: johan@kernel.org
Cc: johannes.berg@intel.com
Cc: kernel-team@lge.com
Cc: linux-block@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-xfs@vger.kernel.org
Cc: oleg@redhat.com
Cc: tj@kernel.org
Link: http://lkml.kernel.org/r/1508921765-15396-4-git-send-email-byungchul.park@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
include/linux/completion.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/linux/completion.h b/include/linux/completion.h
index cae5400..9121803 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -53,7 +53,7 @@ static inline void complete_release_commit(struct completion *x)
do { \
static struct lock_class_key __key; \
lockdep_init_map_crosslock((struct lockdep_map *)&(x)->map, \
- "(complete)" #x, \
+ "(completion)" #x, \
&__key, 0); \
__init_completion(x); \
} while (0)
@@ -67,7 +67,7 @@ static inline void complete_release_commit(struct completion *x) {}
#ifdef CONFIG_LOCKDEP_COMPLETIONS
#define COMPLETION_INITIALIZER(work) \
{ 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait), \
- STATIC_CROSS_LOCKDEP_MAP_INIT("(complete)" #work, &(work)) }
+ STATIC_CROSS_LOCKDEP_MAP_INIT("(completion)" #work, &(work)) }
#else
#define COMPLETION_INITIALIZER(work) \
{ 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:locking/core] locking/lockdep: Add a boot parameter allowing unwind in cross-release and disable it by default
2017-10-25 8:56 ` [PATCH v5 4/9] locking/lockdep: Add a boot parameter allowing unwind in cross-release and disable it by default Byungchul Park
@ 2017-10-25 11:11 ` tip-bot for Byungchul Park
0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Byungchul Park @ 2017-10-25 11:11 UTC (permalink / raw)
To: linux-tip-commits
Cc: torvalds, hpa, linux-kernel, byungchul.park, mingo, tglx, peterz,
johan
Commit-ID: d141babe4244945f1d001118578e0eb3ce12729d
Gitweb: https://git.kernel.org/tip/d141babe4244945f1d001118578e0eb3ce12729d
Author: Byungchul Park <byungchul.park@lge.com>
AuthorDate: Wed, 25 Oct 2017 17:56:00 +0900
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 25 Oct 2017 12:19:01 +0200
locking/lockdep: Add a boot parameter allowing unwind in cross-release and disable it by default
Johan Hovold reported a heavy performance regression caused by lockdep
cross-release:
> Boot time (from "Linux version" to login prompt) had in fact doubled
> since 4.13 where it took 17 seconds (with my current config) compared to
> the 35 seconds I now see with 4.14-rc4.
>
> I quick bisect pointed to lockdep and specifically the following commit:
>
> 28a903f63ec0 ("locking/lockdep: Handle non(or multi)-acquisition
> of a crosslock")
>
> which I've verified is the commit which doubled the boot time (compared
> to 28a903f63ec0^) (added by lockdep crossrelease series [1]).
Currently cross-release performs unwind on every acquisition, but that
is very expensive.
This patch makes unwind optional and disables it by default and only
records acquire_ip.
Full stack traces are sometimes required for full analysis, in which
case a boot paramter, crossrelease_fullstack, can be specified.
On my qemu Ubuntu machine (x86_64, 4 cores, 512M), the regression was
fixed. We measure boot times with 'perf stat --null --repeat 10 $QEMU',
where $QEMU launches a kernel with init=/bin/true:
1. No lockdep enabled:
Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):
2.756558155 seconds time elapsed ( +- 0.09% )
2. Lockdep enabled:
Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):
2.968710420 seconds time elapsed ( +- 0.12% )
3. Lockdep enabled + cross-release enabled:
Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):
3.153839636 seconds time elapsed ( +- 0.31% )
4. Lockdep enabled + cross-release enabled + this patch applied:
Performance counter stats for 'qemu_booting_time.sh bzImage' (10 runs):
2.963669551 seconds time elapsed ( +- 0.11% )
I.e. lockdep cross-release performance is now indistinguishable from
vanilla lockdep.
Bisected-by: Johan Hovold <johan@kernel.org>
Analyzed-by: Thomas Gleixner <tglx@linutronix.de>
Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Reported-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: amir73il@gmail.com
Cc: axboe@kernel.dk
Cc: darrick.wong@oracle.com
Cc: david@fromorbit.com
Cc: hch@infradead.org
Cc: idryomov@gmail.com
Cc: johannes.berg@intel.com
Cc: kernel-team@lge.com
Cc: linux-block@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-xfs@vger.kernel.org
Cc: oleg@redhat.com
Cc: tj@kernel.org
Link: http://lkml.kernel.org/r/1508921765-15396-5-git-send-email-byungchul.park@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
Documentation/admin-guide/kernel-parameters.txt | 3 +++
kernel/locking/lockdep.c | 19 +++++++++++++++++--
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 0549662..f20ed5e 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -709,6 +709,9 @@
It will be ignored when crashkernel=X,high is not used
or memory reserved is below 4G.
+ crossrelease_fullstack
+ [KNL] Allow to record full stack trace in cross-release
+
cryptomgr.notests
[KNL] Disable crypto self-tests
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e36e652..160b5d6 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -76,6 +76,15 @@ module_param(lock_stat, int, 0644);
#define lock_stat 0
#endif
+static int crossrelease_fullstack;
+static int __init allow_crossrelease_fullstack(char *str)
+{
+ crossrelease_fullstack = 1;
+ return 0;
+}
+
+early_param("crossrelease_fullstack", allow_crossrelease_fullstack);
+
/*
* lockdep_lock: protects the lockdep graph, the hashes and the
* class/list/hash allocators.
@@ -4863,8 +4872,14 @@ static void add_xhlock(struct held_lock *hlock)
xhlock->trace.nr_entries = 0;
xhlock->trace.max_entries = MAX_XHLOCK_TRACE_ENTRIES;
xhlock->trace.entries = xhlock->trace_entries;
- xhlock->trace.skip = 3;
- save_stack_trace(&xhlock->trace);
+
+ if (crossrelease_fullstack) {
+ xhlock->trace.skip = 3;
+ save_stack_trace(&xhlock->trace);
+ } else {
+ xhlock->trace.nr_entries = 1;
+ xhlock->trace.entries[0] = hlock->acquire_ip;
+ }
}
static inline int same_context_xhlock(struct hist_lock *xhlock)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:locking/core] locking/lockdep: Remove the BROKEN flag from CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS
2017-10-25 8:56 ` [PATCH v5 5/9] locking/lockdep: Remove the BROKEN flag from CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS Byungchul Park
@ 2017-10-25 11:12 ` tip-bot for Byungchul Park
0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Byungchul Park @ 2017-10-25 11:12 UTC (permalink / raw)
To: linux-tip-commits
Cc: mingo, peterz, hpa, tglx, linux-kernel, byungchul.park, torvalds
Commit-ID: 2dcd5adfb7401b762ddbe4b86dcacc2f3de6b97b
Gitweb: https://git.kernel.org/tip/2dcd5adfb7401b762ddbe4b86dcacc2f3de6b97b
Author: Byungchul Park <byungchul.park@lge.com>
AuthorDate: Wed, 25 Oct 2017 17:56:01 +0900
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 25 Oct 2017 12:19:01 +0200
locking/lockdep: Remove the BROKEN flag from CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS
Now that the performance regression is fixed, re-enable
CONFIG_LOCKDEP_CROSSRELEASE=y and CONFIG_LOCKDEP_COMPLETIONS=y.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: amir73il@gmail.com
Cc: axboe@kernel.dk
Cc: darrick.wong@oracle.com
Cc: david@fromorbit.com
Cc: hch@infradead.org
Cc: idryomov@gmail.com
Cc: johan@kernel.org
Cc: johannes.berg@intel.com
Cc: kernel-team@lge.com
Cc: linux-block@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-xfs@vger.kernel.org
Cc: oleg@redhat.com
Cc: tj@kernel.org
Link: http://lkml.kernel.org/r/1508921765-15396-6-git-send-email-byungchul.park@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
lib/Kconfig.debug | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index dfdad67..c1e720a 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1092,8 +1092,8 @@ config PROVE_LOCKING
select DEBUG_MUTEXES
select DEBUG_RT_MUTEXES if RT_MUTEXES
select DEBUG_LOCK_ALLOC
- select LOCKDEP_CROSSRELEASE if BROKEN
- select LOCKDEP_COMPLETIONS if BROKEN
+ select LOCKDEP_CROSSRELEASE
+ select LOCKDEP_COMPLETIONS
select TRACE_IRQFLAGS
default n
help
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:locking/core] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK=y
2017-10-25 8:56 ` [PATCH v5 6/9] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK Byungchul Park
@ 2017-10-25 11:12 ` tip-bot for Byungchul Park
0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Byungchul Park @ 2017-10-25 11:12 UTC (permalink / raw)
To: linux-tip-commits
Cc: peterz, torvalds, mingo, tglx, hpa, byungchul.park, linux-kernel
Commit-ID: e121d64e16484d4a5eba94cd2fa9eb3848b7c9c2
Gitweb: https://git.kernel.org/tip/e121d64e16484d4a5eba94cd2fa9eb3848b7c9c2
Author: Byungchul Park <byungchul.park@lge.com>
AuthorDate: Wed, 25 Oct 2017 17:56:02 +0900
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 25 Oct 2017 12:19:02 +0200
locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK=y
Add a Kconfig knob that enables the lockdep "crossrelease_fullstack" boot parameter.
Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: amir73il@gmail.com
Cc: axboe@kernel.dk
Cc: darrick.wong@oracle.com
Cc: david@fromorbit.com
Cc: hch@infradead.org
Cc: idryomov@gmail.com
Cc: johan@kernel.org
Cc: johannes.berg@intel.com
Cc: kernel-team@lge.com
Cc: linux-block@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-xfs@vger.kernel.org
Cc: oleg@redhat.com
Cc: tj@kernel.org
Link: http://lkml.kernel.org/r/1508921765-15396-7-git-send-email-byungchul.park@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
kernel/locking/lockdep.c | 4 ++++
lib/Kconfig.debug | 15 +++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 160b5d6..db933d0 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -76,7 +76,11 @@ module_param(lock_stat, int, 0644);
#define lock_stat 0
#endif
+#ifdef CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
+static int crossrelease_fullstack = 1;
+#else
static int crossrelease_fullstack;
+#endif
static int __init allow_crossrelease_fullstack(char *str)
{
crossrelease_fullstack = 1;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index c1e720a..2b439a5 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -1179,6 +1179,21 @@ config LOCKDEP_COMPLETIONS
A deadlock caused by wait_for_completion() and complete() can be
detected by lockdep using crossrelease feature.
+config BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK
+ bool "Enable the boot parameter, crossrelease_fullstack"
+ depends on LOCKDEP_CROSSRELEASE
+ default n
+ help
+ The lockdep "cross-release" feature needs to record stack traces
+ (of calling functions) for all acquisitions, for eventual later
+ use during analysis. By default only a single caller is recorded,
+ because the unwind operation can be very expensive with deeper
+ stack chains.
+
+ However a boot parameter, crossrelease_fullstack, was
+ introduced since sometimes deeper traces are required for full
+ analysis. This option turns on the boot parameter.
+
config DEBUG_LOCKDEP
bool "Lock dependency engine debugging"
depends on DEBUG_KERNEL && LOCKDEP
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:locking/core] sched/completions: Add support for initializing completions with lockdep_map
2017-10-25 8:56 ` [PATCH v5 7/9] completion: Add support for initializing completion with lockdep_map Byungchul Park
@ 2017-10-25 11:12 ` tip-bot for Byungchul Park
0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Byungchul Park @ 2017-10-25 11:12 UTC (permalink / raw)
To: linux-tip-commits
Cc: byungchul.park, peterz, linux-kernel, tglx, torvalds, hpa, mingo
Commit-ID: a7967bc31584bd282682981295861e7bcba19e65
Gitweb: https://git.kernel.org/tip/a7967bc31584bd282682981295861e7bcba19e65
Author: Byungchul Park <byungchul.park@lge.com>
AuthorDate: Wed, 25 Oct 2017 17:56:03 +0900
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 25 Oct 2017 12:19:03 +0200
sched/completions: Add support for initializing completions with lockdep_map
Sometimes we want to initialize completions with sparate lockdep maps
to assign lock classes as desired. For example, the workqueue code
needs to directly manage lockdep maps, since only the code is aware of
how to classify lockdep maps properly.
Provide additional macros initializing completions in that way.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: amir73il@gmail.com
Cc: axboe@kernel.dk
Cc: darrick.wong@oracle.com
Cc: david@fromorbit.com
Cc: hch@infradead.org
Cc: idryomov@gmail.com
Cc: johan@kernel.org
Cc: johannes.berg@intel.com
Cc: kernel-team@lge.com
Cc: linux-block@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-xfs@vger.kernel.org
Cc: oleg@redhat.com
Cc: tj@kernel.org
Link: http://lkml.kernel.org/r/1508921765-15396-8-git-send-email-byungchul.park@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
include/linux/completion.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/include/linux/completion.h b/include/linux/completion.h
index 9121803..4da4991 100644
--- a/include/linux/completion.h
+++ b/include/linux/completion.h
@@ -49,6 +49,13 @@ static inline void complete_release_commit(struct completion *x)
lock_commit_crosslock((struct lockdep_map *)&x->map);
}
+#define init_completion_map(x, m) \
+do { \
+ lockdep_init_map_crosslock((struct lockdep_map *)&(x)->map, \
+ (m)->name, (m)->key, 0); \
+ __init_completion(x); \
+} while (0)
+
#define init_completion(x) \
do { \
static struct lock_class_key __key; \
@@ -58,6 +65,7 @@ do { \
__init_completion(x); \
} while (0)
#else
+#define init_completion_map(x, m) __init_completion(x)
#define init_completion(x) __init_completion(x)
static inline void complete_acquire(struct completion *x) {}
static inline void complete_release(struct completion *x) {}
@@ -73,6 +81,9 @@ static inline void complete_release_commit(struct completion *x) {}
{ 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) }
#endif
+#define COMPLETION_INITIALIZER_ONSTACK_MAP(work, map) \
+ (*({ init_completion_map(&(work), &(map)); &(work); }))
+
#define COMPLETION_INITIALIZER_ONSTACK(work) \
(*({ init_completion(&work); &work; }))
@@ -102,8 +113,11 @@ static inline void complete_release_commit(struct completion *x) {}
#ifdef CONFIG_LOCKDEP
# define DECLARE_COMPLETION_ONSTACK(work) \
struct completion work = COMPLETION_INITIALIZER_ONSTACK(work)
+# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) \
+ struct completion work = COMPLETION_INITIALIZER_ONSTACK_MAP(work, map)
#else
# define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work)
+# define DECLARE_COMPLETION_ONSTACK_MAP(work, map) DECLARE_COMPLETION(work)
#endif
/**
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:locking/core] workqueue: Remove now redundant lock acquisitions wrt. workqueue flushes
2017-10-25 8:56 ` [PATCH v5 8/9] workqueue: Remove unnecessary acquisitions wrt workqueue flush Byungchul Park
@ 2017-10-25 11:13 ` tip-bot for Byungchul Park
0 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Byungchul Park @ 2017-10-25 11:13 UTC (permalink / raw)
To: linux-tip-commits
Cc: peterz, tglx, hpa, torvalds, mingo, byungchul.park, linux-kernel
Commit-ID: fd1a5b04dfb899f84ddeb8acdaea6b98283df1e5
Gitweb: https://git.kernel.org/tip/fd1a5b04dfb899f84ddeb8acdaea6b98283df1e5
Author: Byungchul Park <byungchul.park@lge.com>
AuthorDate: Wed, 25 Oct 2017 17:56:04 +0900
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 25 Oct 2017 12:19:03 +0200
workqueue: Remove now redundant lock acquisitions wrt. workqueue flushes
The workqueue code added manual lock acquisition annotations to catch
deadlocks.
After lockdepcrossrelease was introduced, some of those became redundant,
since wait_for_completion() already does the acquisition and tracking.
Remove the duplicate annotations.
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: amir73il@gmail.com
Cc: axboe@kernel.dk
Cc: darrick.wong@oracle.com
Cc: david@fromorbit.com
Cc: hch@infradead.org
Cc: idryomov@gmail.com
Cc: johan@kernel.org
Cc: johannes.berg@intel.com
Cc: kernel-team@lge.com
Cc: linux-block@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-xfs@vger.kernel.org
Cc: oleg@redhat.com
Cc: tj@kernel.org
Link: http://lkml.kernel.org/r/1508921765-15396-9-git-send-email-byungchul.park@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
include/linux/workqueue.h | 4 ++--
kernel/workqueue.c | 19 +++----------------
2 files changed, 5 insertions(+), 18 deletions(-)
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 1c49431..c8a572c 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -218,7 +218,7 @@ static inline unsigned int work_static(struct work_struct *work) { return 0; }
\
__init_work((_work), _onstack); \
(_work)->data = (atomic_long_t) WORK_DATA_INIT(); \
- lockdep_init_map(&(_work)->lockdep_map, #_work, &__key, 0); \
+ lockdep_init_map(&(_work)->lockdep_map, "(work_completion)"#_work, &__key, 0); \
INIT_LIST_HEAD(&(_work)->entry); \
(_work)->func = (_func); \
} while (0)
@@ -398,7 +398,7 @@ __alloc_workqueue_key(const char *fmt, unsigned int flags, int max_active,
static struct lock_class_key __key; \
const char *__lock_name; \
\
- __lock_name = #fmt#args; \
+ __lock_name = "(wq_completion)"#fmt#args; \
\
__alloc_workqueue_key((fmt), (flags), (max_active), \
&__key, __lock_name, ##args); \
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 39831b2..160fdc6 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -2497,15 +2497,8 @@ static void insert_wq_barrier(struct pool_workqueue *pwq,
INIT_WORK_ONSTACK(&barr->work, wq_barrier_func);
__set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&barr->work));
- /*
- * Explicitly init the crosslock for wq_barrier::done, make its lock
- * key a subkey of the corresponding work. As a result we won't
- * build a dependency between wq_barrier::done and unrelated work.
- */
- lockdep_init_map_crosslock((struct lockdep_map *)&barr->done.map,
- "(complete)wq_barr::done",
- target->lockdep_map.key, 1);
- __init_completion(&barr->done);
+ init_completion_map(&barr->done, &target->lockdep_map);
+
barr->task = current;
/*
@@ -2611,16 +2604,13 @@ void flush_workqueue(struct workqueue_struct *wq)
struct wq_flusher this_flusher = {
.list = LIST_HEAD_INIT(this_flusher.list),
.flush_color = -1,
- .done = COMPLETION_INITIALIZER_ONSTACK(this_flusher.done),
+ .done = COMPLETION_INITIALIZER_ONSTACK_MAP(this_flusher.done, wq->lockdep_map),
};
int next_color;
if (WARN_ON(!wq_online))
return;
- lock_map_acquire(&wq->lockdep_map);
- lock_map_release(&wq->lockdep_map);
-
mutex_lock(&wq->mutex);
/*
@@ -2883,9 +2873,6 @@ bool flush_work(struct work_struct *work)
if (WARN_ON(!wq_online))
return false;
- lock_map_acquire(&work->lockdep_map);
- lock_map_release(&work->lockdep_map);
-
if (start_flush_work(work, &barr)) {
wait_for_completion(&barr.done);
destroy_work_on_stack(&barr.work);
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion()
2017-10-25 10:13 ` Ingo Molnar
@ 2017-10-25 18:20 ` Jens Axboe
2017-10-26 5:50 ` Ingo Molnar
0 siblings, 1 reply; 23+ messages in thread
From: Jens Axboe @ 2017-10-25 18:20 UTC (permalink / raw)
To: Ingo Molnar, Byungchul Park
Cc: peterz, johan, tglx, linux-kernel, linux-mm, tj, johannes.berg,
oleg, amir73il, david, darrick.wong, linux-xfs, linux-fsdevel,
linux-block, hch, idryomov, kernel-team
On 10/25/2017 03:13 AM, Ingo Molnar wrote:
>
> * Byungchul Park <byungchul.park@lge.com> wrote:
>
>> Darrick posted the following warning and Dave Chinner analyzed it:
>>
>>> ======================================================
>>> WARNING: possible circular locking dependency detected
>>> 4.14.0-rc1-fixes #1 Tainted: G W
>
>> Reported-by: Darrick J. Wong <darrick.wong@oracle.com>
>> Analyzed-by: Dave Chinner <david@fromorbit.com>
>> Signed-off-by: Byungchul Park <byungchul.park@lge.com>
>> ---
>> block/bio.c | 2 +-
>> block/genhd.c | 10 ++--------
>> include/linux/genhd.h | 22 ++++++++++++++++++++--
>> 3 files changed, 23 insertions(+), 11 deletions(-)
>
> Ok, this patch looks good to me now, I'll wait to get an Ack or Nak from Jens for
> these changes.
>
> Jens: this patch has some dependencies in prior lockdep changes, so I'd like to
> carry it in the locking tree for a v4.15 merge.
Looks fine to me, you can add my reviewed-by and carry it in your tree.
--
Jens Axboe
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion()
2017-10-25 18:20 ` Jens Axboe
@ 2017-10-26 5:50 ` Ingo Molnar
2017-10-26 5:58 ` Byungchul Park
0 siblings, 1 reply; 23+ messages in thread
From: Ingo Molnar @ 2017-10-26 5:50 UTC (permalink / raw)
To: Jens Axboe
Cc: Byungchul Park, peterz, johan, tglx, linux-kernel, linux-mm, tj,
johannes.berg, oleg, amir73il, david, darrick.wong, linux-xfs,
linux-fsdevel, linux-block, hch, idryomov, kernel-team
* Jens Axboe <axboe@kernel.dk> wrote:
> On 10/25/2017 03:13 AM, Ingo Molnar wrote:
> >
> > * Byungchul Park <byungchul.park@lge.com> wrote:
> >
> >> Darrick posted the following warning and Dave Chinner analyzed it:
> >>
> >>> ======================================================
> >>> WARNING: possible circular locking dependency detected
> >>> 4.14.0-rc1-fixes #1 Tainted: G W
> >
> >> Reported-by: Darrick J. Wong <darrick.wong@oracle.com>
> >> Analyzed-by: Dave Chinner <david@fromorbit.com>
> >> Signed-off-by: Byungchul Park <byungchul.park@lge.com>
> >> ---
> >> block/bio.c | 2 +-
> >> block/genhd.c | 10 ++--------
> >> include/linux/genhd.h | 22 ++++++++++++++++++++--
> >> 3 files changed, 23 insertions(+), 11 deletions(-)
> >
> > Ok, this patch looks good to me now, I'll wait to get an Ack or Nak from Jens for
> > these changes.
> >
> > Jens: this patch has some dependencies in prior lockdep changes, so I'd like to
> > carry it in the locking tree for a v4.15 merge.
>
> Looks fine to me, you can add my reviewed-by and carry it in your tree.
Thanks Jens!
Ingo
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion()
2017-10-26 5:50 ` Ingo Molnar
@ 2017-10-26 5:58 ` Byungchul Park
0 siblings, 0 replies; 23+ messages in thread
From: Byungchul Park @ 2017-10-26 5:58 UTC (permalink / raw)
To: Ingo Molnar
Cc: Jens Axboe, peterz, johan, tglx, linux-kernel, linux-mm, tj,
johannes.berg, oleg, amir73il, david, darrick.wong, linux-xfs,
linux-fsdevel, linux-block, hch, idryomov, kernel-team
On Thu, Oct 26, 2017 at 07:50:46AM +0200, Ingo Molnar wrote:
>
> * Jens Axboe <axboe@kernel.dk> wrote:
>
> > On 10/25/2017 03:13 AM, Ingo Molnar wrote:
> > >
> > > * Byungchul Park <byungchul.park@lge.com> wrote:
> > >
> > >> Darrick posted the following warning and Dave Chinner analyzed it:
> > >>
> > >>> ======================================================
> > >>> WARNING: possible circular locking dependency detected
> > >>> 4.14.0-rc1-fixes #1 Tainted: G W
> > >
> > >> Reported-by: Darrick J. Wong <darrick.wong@oracle.com>
> > >> Analyzed-by: Dave Chinner <david@fromorbit.com>
> > >> Signed-off-by: Byungchul Park <byungchul.park@lge.com>
> > >> ---
> > >> block/bio.c | 2 +-
> > >> block/genhd.c | 10 ++--------
> > >> include/linux/genhd.h | 22 ++++++++++++++++++++--
> > >> 3 files changed, 23 insertions(+), 11 deletions(-)
> > >
> > > Ok, this patch looks good to me now, I'll wait to get an Ack or Nak from Jens for
> > > these changes.
> > >
> > > Jens: this patch has some dependencies in prior lockdep changes, so I'd like to
> > > carry it in the locking tree for a v4.15 merge.
> >
> > Looks fine to me, you can add my reviewed-by and carry it in your tree.
>
> Thanks Jens!
Thanks all of you.
^ permalink raw reply [flat|nested] 23+ messages in thread
* [tip:locking/core] block, locking/lockdep: Assign a lock_class per gendisk used for wait_for_completion()
2017-10-25 8:56 ` [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion() Byungchul Park
2017-10-25 10:13 ` Ingo Molnar
@ 2017-10-26 9:31 ` tip-bot for Byungchul Park
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Byungchul Park @ 2017-10-26 9:31 UTC (permalink / raw)
To: linux-tip-commits
Cc: torvalds, linux-kernel, peterz, hpa, axboe, david, tglx, mingo,
darrick.wong, byungchul.park
Commit-ID: e319e1fbd9d42420ab6eec0bfd75eb9ad7ca63b1
Gitweb: https://git.kernel.org/tip/e319e1fbd9d42420ab6eec0bfd75eb9ad7ca63b1
Author: Byungchul Park <byungchul.park@lge.com>
AuthorDate: Wed, 25 Oct 2017 17:56:05 +0900
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Thu, 26 Oct 2017 07:54:17 +0200
block, locking/lockdep: Assign a lock_class per gendisk used for wait_for_completion()
Darrick posted the following warning and Dave Chinner analyzed it:
> ======================================================
> WARNING: possible circular locking dependency detected
> 4.14.0-rc1-fixes #1 Tainted: G W
> ------------------------------------------------------
> loop0/31693 is trying to acquire lock:
> (&(&ip->i_mmaplock)->mr_lock){++++}, at: [<ffffffffa00f1b0c>] xfs_ilock+0x23c/0x330 [xfs]
>
> but now in release context of a crosslock acquired at the following:
> ((complete)&ret.event){+.+.}, at: [<ffffffff81326c1f>] submit_bio_wait+0x7f/0xb0
>
> which lock already depends on the new lock.
>
> the existing dependency chain (in reverse order) is:
>
> -> #2 ((complete)&ret.event){+.+.}:
> lock_acquire+0xab/0x200
> wait_for_completion_io+0x4e/0x1a0
> submit_bio_wait+0x7f/0xb0
> blkdev_issue_zeroout+0x71/0xa0
> xfs_bmapi_convert_unwritten+0x11f/0x1d0 [xfs]
> xfs_bmapi_write+0x374/0x11f0 [xfs]
> xfs_iomap_write_direct+0x2ac/0x430 [xfs]
> xfs_file_iomap_begin+0x20d/0xd50 [xfs]
> iomap_apply+0x43/0xe0
> dax_iomap_rw+0x89/0xf0
> xfs_file_dax_write+0xcc/0x220 [xfs]
> xfs_file_write_iter+0xf0/0x130 [xfs]
> __vfs_write+0xd9/0x150
> vfs_write+0xc8/0x1c0
> SyS_write+0x45/0xa0
> entry_SYSCALL_64_fastpath+0x1f/0xbe
>
> -> #1 (&xfs_nondir_ilock_class){++++}:
> lock_acquire+0xab/0x200
> down_write_nested+0x4a/0xb0
> xfs_ilock+0x263/0x330 [xfs]
> xfs_setattr_size+0x152/0x370 [xfs]
> xfs_vn_setattr+0x6b/0x90 [xfs]
> notify_change+0x27d/0x3f0
> do_truncate+0x5b/0x90
> path_openat+0x237/0xa90
> do_filp_open+0x8a/0xf0
> do_sys_open+0x11c/0x1f0
> entry_SYSCALL_64_fastpath+0x1f/0xbe
>
> -> #0 (&(&ip->i_mmaplock)->mr_lock){++++}:
> up_write+0x1c/0x40
> xfs_iunlock+0x1d0/0x310 [xfs]
> xfs_file_fallocate+0x8a/0x310 [xfs]
> loop_queue_work+0xb7/0x8d0
> kthread_worker_fn+0xb9/0x1f0
>
> Chain exists of:
> &(&ip->i_mmaplock)->mr_lock --> &xfs_nondir_ilock_class --> (complete)&ret.event
>
> Possible unsafe locking scenario by crosslock:
>
> CPU0 CPU1
> ---- ----
> lock(&xfs_nondir_ilock_class);
> lock((complete)&ret.event);
> lock(&(&ip->i_mmaplock)->mr_lock);
> unlock((complete)&ret.event);
>
> *** DEADLOCK ***
The warning is a false positive, caused by the fact that all
wait_for_completion()s in submit_bio_wait() are waiting with the same
lock class.
However, some bios have nothing to do with others, for example in the case
of loop devices, there's no direct connection between the bios of an upper
device and the bios of a lower device(=loop device).
The safest way to assign different lock classes to different devices is
to do it for each gendisk. In other words, this patch assigns a
lockdep_map per gendisk and uses it when initializing completion in
submit_bio_wait().
Analyzed-by: Dave Chinner <david@fromorbit.com>
Reported-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Byungchul Park <byungchul.park@lge.com>
Reviewed-by: Jens Axboe <axboe@kernel.dk>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: amir73il@gmail.com
Cc: axboe@kernel.dk
Cc: david@fromorbit.com
Cc: hch@infradead.org
Cc: idryomov@gmail.com
Cc: johan@kernel.org
Cc: johannes.berg@intel.com
Cc: kernel-team@lge.com
Cc: linux-block@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-xfs@vger.kernel.org
Cc: oleg@redhat.com
Cc: tj@kernel.org
Link: http://lkml.kernel.org/r/1508921765-15396-10-git-send-email-byungchul.park@lge.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
block/bio.c | 2 +-
block/genhd.c | 10 ++--------
include/linux/genhd.h | 22 ++++++++++++++++++++--
3 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/block/bio.c b/block/bio.c
index 5e901bf..cc60213 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -935,7 +935,7 @@ static void submit_bio_wait_endio(struct bio *bio)
*/
int submit_bio_wait(struct bio *bio)
{
- DECLARE_COMPLETION_ONSTACK(done);
+ DECLARE_COMPLETION_ONSTACK_MAP(done, bio->bi_disk->lockdep_map);
bio->bi_private = &done;
bio->bi_end_io = submit_bio_wait_endio;
diff --git a/block/genhd.c b/block/genhd.c
index dd305c6..630c0da 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1354,13 +1354,7 @@ dev_t blk_lookup_devt(const char *name, int partno)
}
EXPORT_SYMBOL(blk_lookup_devt);
-struct gendisk *alloc_disk(int minors)
-{
- return alloc_disk_node(minors, NUMA_NO_NODE);
-}
-EXPORT_SYMBOL(alloc_disk);
-
-struct gendisk *alloc_disk_node(int minors, int node_id)
+struct gendisk *__alloc_disk_node(int minors, int node_id)
{
struct gendisk *disk;
struct disk_part_tbl *ptbl;
@@ -1411,7 +1405,7 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
}
return disk;
}
-EXPORT_SYMBOL(alloc_disk_node);
+EXPORT_SYMBOL(__alloc_disk_node);
struct kobject *get_disk(struct gendisk *disk)
{
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index ea652bf..19d1871 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -206,6 +206,7 @@ struct gendisk {
#endif /* CONFIG_BLK_DEV_INTEGRITY */
int node_id;
struct badblocks *bb;
+ struct lockdep_map lockdep_map;
};
static inline struct gendisk *part_to_disk(struct hd_struct *part)
@@ -590,8 +591,7 @@ extern void __delete_partition(struct percpu_ref *);
extern void delete_partition(struct gendisk *, int);
extern void printk_all_partitions(void);
-extern struct gendisk *alloc_disk_node(int minors, int node_id);
-extern struct gendisk *alloc_disk(int minors);
+extern struct gendisk *__alloc_disk_node(int minors, int node_id);
extern struct kobject *get_disk(struct gendisk *disk);
extern void put_disk(struct gendisk *disk);
extern void blk_register_region(dev_t devt, unsigned long range,
@@ -615,6 +615,24 @@ extern ssize_t part_fail_store(struct device *dev,
const char *buf, size_t count);
#endif /* CONFIG_FAIL_MAKE_REQUEST */
+#define alloc_disk_node(minors, node_id) \
+({ \
+ static struct lock_class_key __key; \
+ const char *__name; \
+ struct gendisk *__disk; \
+ \
+ __name = "(gendisk_completion)"#minors"("#node_id")"; \
+ \
+ __disk = __alloc_disk_node(minors, node_id); \
+ \
+ if (__disk) \
+ lockdep_init_map(&__disk->lockdep_map, __name, &__key, 0); \
+ \
+ __disk; \
+})
+
+#define alloc_disk(minors) alloc_disk_node(minors, NUMA_NO_NODE)
+
static inline int hd_ref_init(struct hd_struct *part)
{
if (percpu_ref_init(&part->ref, __delete_partition, 0,
^ permalink raw reply related [flat|nested] 23+ messages in thread
end of thread, other threads:[~2017-10-26 9:36 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-10-25 8:55 [PATCH v5 0/9] cross-release: Enhence performance and fix false positives Byungchul Park
2017-10-25 8:55 ` [PATCH v5 1/9] block: use DECLARE_COMPLETION_ONSTACK in submit_bio_wait Byungchul Park
2017-10-25 11:10 ` [tip:locking/core] block: Use DECLARE_COMPLETION_ONSTACK() in submit_bio_wait() tip-bot for Christoph Hellwig
2017-10-25 8:55 ` [PATCH v5 2/9] locking/lockdep: Provide empty lockdep_map structure for !CONFIG_LOCKDEP Byungchul Park
2017-10-25 11:11 ` [tip:locking/core] " tip-bot for Byungchul Park
2017-10-25 8:55 ` [PATCH v5 3/9] completion: Change the prefix of lock name for completion variable Byungchul Park
2017-10-25 11:11 ` [tip:locking/core] locking/lockdep, sched/completions: Change the prefix of lock name for completion variables tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 4/9] locking/lockdep: Add a boot parameter allowing unwind in cross-release and disable it by default Byungchul Park
2017-10-25 11:11 ` [tip:locking/core] " tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 5/9] locking/lockdep: Remove the BROKEN flag from CONFIG_LOCKDEP_CROSSRELEASE and CONFIG_LOCKDEP_COMPLETIONS Byungchul Park
2017-10-25 11:12 ` [tip:locking/core] " tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 6/9] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK Byungchul Park
2017-10-25 11:12 ` [tip:locking/core] locking/lockdep: Introduce CONFIG_BOOTPARAM_LOCKDEP_CROSSRELEASE_FULLSTACK=y tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 7/9] completion: Add support for initializing completion with lockdep_map Byungchul Park
2017-10-25 11:12 ` [tip:locking/core] sched/completions: Add support for initializing completions " tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 8/9] workqueue: Remove unnecessary acquisitions wrt workqueue flush Byungchul Park
2017-10-25 11:13 ` [tip:locking/core] workqueue: Remove now redundant lock acquisitions wrt. workqueue flushes tip-bot for Byungchul Park
2017-10-25 8:56 ` [PATCH v5 9/9] block: Assign a lock_class per gendisk used for wait_for_completion() Byungchul Park
2017-10-25 10:13 ` Ingo Molnar
2017-10-25 18:20 ` Jens Axboe
2017-10-26 5:50 ` Ingo Molnar
2017-10-26 5:58 ` Byungchul Park
2017-10-26 9:31 ` [tip:locking/core] block, locking/lockdep: " tip-bot for Byungchul Park
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox