@@ -44,6 +44,10 @@ struct kthread {
unsigned long flags;
unsigned int cpu;
void *data;
+#ifdef CONFIG_LOCKDEP_COMPLETIONS
+ struct lock_class_key parked_key;
+ struct lock_class_key exited_key;
+#endif
struct completion parked;
struct completion exited;
#ifdef CONFIG_BLK_CGROUP
@@ -221,8 +225,17 @@ static int kthread(void *_create)
}
self->data = data;
+ /* these two completions are shared with all kthread, which is bonghist
+ * imo */
+ lockdep_init_map_crosslock(&self->exited->map,
+ "(kthread completion)->exited",
+ &self->exited_key, 0);
init_completion(&self->exited);
+ lockdep_init_map_crosslock(&self->parked->map,
+ "(kthread completion)->parked",
+ &self->parked_key, 0);
init_completion(&self->parked);
+
current->vfork_done = &self->exited;
/* OK, tell user we're spawned, wait for stop or wakeup */
Ideally we'd create the key through a macro at the real callers and pass it all the way down. This would give us better coverage for cases where a bunch of kthreads are created for the same thing. But this gets the job done meanwhile and unblocks our CI. Refining later on is always possible. Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> --- kernel/kthread.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)