Received: by 10.223.164.202 with SMTP id h10csp4699022wrb; Wed, 29 Nov 2017 10:21:42 -0800 (PST) X-Google-Smtp-Source: AGs4zMaaOAc30COMnzlIun9jrH1aVYDraY3LiuNe5zodTykmZOsuPyAxKBNCIdVPx1BdDSk5JSxV X-Received: by 10.84.235.129 with SMTP id p1mr3653263plk.288.1511979702631; Wed, 29 Nov 2017 10:21:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511979702; cv=none; d=google.com; s=arc-20160816; b=i2Zrp2B5ayPD7e5G1bGG4j+dcdxHnZ5qwWF/Ovvr1zxVj+CE4jCFYKLPzbShivf+KY W2kLsWzSWxyeo/K/X8RtrdYlCEuU7UZN/Pix/HdefHj+K1eStVeNk7bM09e3a1Oh3oFg TMqDm1WWBciR6VVEbEtKhKBvKGg/zuMwGxC34PMP0KdBHlM6v1LrFIN4kzo+nfTBfGo0 uCjyevF2xlkTaE1IOdnsZtLvDVKAzKATLpcgjE7AI2bMqF0pLpjF6uvY8RK0RxpOqydL I7FnmcSyfMfBhSuCbNexVUTrdFk5LCxk6UQakpJgEvizyIukipPf7B0LHdKupHlWgQeo qb1g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=jQkBUNn/NKpD0VIDn4Prew87wHgnHSVy1CiTLtUnVvM=; b=OhsZKwwl9Q/uNHhn/8+R3moztx7kQSl5P5ILfG7mkSNxpVJ2SegqJZIi8zs1SdoA0A LRkJ61Kd536CK1dgouFVHJdwKHBln6da2Q7JsLjI4SV2np4wracxSqNGfJ0sFgVF410T 4pnf9qhe+PoxRfXIPLWPkyIjYqdRUjpx4TURPnbuMR9JepcqI26I/Z2O/GqPa4Ec7vn5 p4L+2WUBKz+AVUut3tMBlVqGc8K2mlLBNeQRxrbjkui13OnQRdxfWn79mcO7ckZ5DzUT hIQlTKrtPxO+VMDEvCylF1wyzGKDHHgnicW0/FQ1cTzW76UIijRUXO/TIKOHMmv45pdq XHRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=cHs29DJI; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1si1593992pgr.812.2017.11.29.10.21.32; Wed, 29 Nov 2017 10:21:42 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@ffwll.ch header.s=google header.b=cHs29DJI; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933454AbdK2Pme (ORCPT + 69 others); Wed, 29 Nov 2017 10:42:34 -0500 Received: from mail-wm0-f66.google.com ([74.125.82.66]:43201 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933158AbdK2PmO (ORCPT ); Wed, 29 Nov 2017 10:42:14 -0500 Received: by mail-wm0-f66.google.com with SMTP id i71so7185452wmf.2 for ; Wed, 29 Nov 2017 07:42:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=jQkBUNn/NKpD0VIDn4Prew87wHgnHSVy1CiTLtUnVvM=; b=cHs29DJIDMYnGlZ290Zan9egYe4AZzUZ5HbSs/zXuS1n0tLUsc1ah2qT86r6z4XeoE 0ovqkb7Kkgd2ab25ApCiLxPLGIJCbSzeQpxUKKemIH3Xxx2RMde6bkayTPsR0+mMy4FK M2STeevsuHkE6abgD7Ob4G9+dbFM824IA81gQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=jQkBUNn/NKpD0VIDn4Prew87wHgnHSVy1CiTLtUnVvM=; b=QMop/YdXVTPFZA6Fxr4DgmfgGnG0kopMpL1ZFqBMPaYDwaqYcSUx3CUxEii0kH7zEC Y5oBBYiKbOwhIxAw2H1bkerzRUfUVDUHzSzrTOPJuRzORSeEdkHclESxRoyBaUrr402g KbkzHdeN0TSIfOG8Ex0uBPzSktBDCBaJKeZLEQXQYUwoMRR4A9R/fiM4VDcgghDFz32z QDj9vF5ZhnXfPnun/Vek8oCzXMIXsG7idhAg4gLTzMMyNlJ9nINhOYh7/oQ3aZ8r3C0i C0/UR9GZIyXFqZFCEXQcJB3+pME86zIrt52ga/I8e8vhuBd7QtjBhPvWgSUwuy5R9OHN 9GBA== X-Gm-Message-State: AJaThX7RmM7ad/qWWkzZpQLGjpeEGkiAuAClk4MBkSLZWvxaXhuBDWpx kxdhgKcbXFJXEtm62BBkmUFSu8E1 X-Received: by 10.80.146.11 with SMTP id i11mr8678575eda.198.1511970133137; Wed, 29 Nov 2017 07:42:13 -0800 (PST) Received: from phenom.ffwll.local ([2a02:168:5635:0:39d2:f87e:2033:9f6]) by smtp.gmail.com with ESMTPSA id o64sm1747655edb.14.2017.11.29.07.42.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Nov 2017 07:42:12 -0800 (PST) From: Daniel Vetter To: LKML , Peter Zijlstra , Ingo Molnar , Thomas Gleixner Cc: Intel Graphics Development , Tejun Heo , Kees Cook , Daniel Vetter , Tvrtko Ursulin , Marta Lofstedt , Daniel Vetter Subject: [PATCH 1/2] lockdep: finer-grained completion key for kthread Date: Wed, 29 Nov 2017 16:41:44 +0100 Message-Id: <20171129154145.26755-2-daniel.vetter@ffwll.ch> X-Mailer: git-send-email 2.15.0 In-Reply-To: <20171129154145.26755-1-daniel.vetter@ffwll.ch> References: <20171129154145.26755-1-daniel.vetter@ffwll.ch> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. v2: - make it compile - use the right map (Tvrtko) v3: lockdep insist on a static key, so the cheap way didn't work. Wire 2 keys through all the callers. I didn't extend this up to alloc_workqueue because the lockdep_invariant_state() call should separate the work functions from the workqueue kthread logic and prevent cross-release state from leaking between unrelated work queues that happen to reuse the same kthreads. v4: CI found more compile fail :-/ Cc: Tvrtko Ursulin Cc: Marta Lofstedt References: https://bugs.freedesktop.org/show_bug.cgi?id=103950 Signed-off-by: Daniel Vetter --- include/linux/kthread.h | 48 ++++++++++++++++++++++++++++----- kernel/kthread.c | 70 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 90 insertions(+), 28 deletions(-) diff --git a/include/linux/kthread.h b/include/linux/kthread.h index c1961761311d..7a9463f0be5c 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -6,10 +6,12 @@ #include #include -__printf(4, 5) -struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), +__printf(6, 7) +struct task_struct *_kthread_create_on_node(int (*threadfn)(void *data), void *data, int node, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, const char namefmt[], ...); /** @@ -25,12 +27,27 @@ struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), */ #define kthread_create(threadfn, data, namefmt, arg...) \ kthread_create_on_node(threadfn, data, NUMA_NO_NODE, namefmt, ##arg) +#define kthread_create_on_node(threadfn, data, node, namefmt, arg...) \ +({ \ + static struct lock_class_key __exited_key, __parked_key; \ + _kthread_create_on_node(threadfn, data, node, &__exited_key, \ + &__parked_key, namefmt, ##arg); \ +}) -struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), +struct task_struct *_kthread_create_on_cpu(int (*threadfn)(void *data), void *data, unsigned int cpu, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, const char *namefmt); +#define kthread_create_on_cpu(threadfn, data, cpu, namefmt) \ +({ \ + static struct lock_class_key __exited_key, __parked_key; \ + _kthread_create_on_cpu(threadfn, data, cpu, &__exited_key,\ + &__parked_key, namefmt); \ +}) + /** * kthread_run - create and wake a thread. @@ -171,13 +188,30 @@ extern void __kthread_init_worker(struct kthread_worker *worker, int kthread_worker_fn(void *worker_ptr); -__printf(2, 3) +__printf(4, 5) struct kthread_worker * -kthread_create_worker(unsigned int flags, const char namefmt[], ...); +_kthread_create_worker(unsigned int flags, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, + const char namefmt[], ...); +#define kthread_create_worker(flags, namefmt...) \ +({ \ + static struct lock_class_key __exited_key, __parked_key; \ + _kthread_create_worker(flags, &__exited_key, &__parked_key, \ + ##namefmt); \ +}) -__printf(3, 4) struct kthread_worker * -kthread_create_worker_on_cpu(int cpu, unsigned int flags, +__printf(5, 6) struct kthread_worker * +_kthread_create_worker_on_cpu(int cpu, unsigned int flags, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, const char namefmt[], ...); +#define kthread_create_worker_on_cpu(cpu, flags, namefmt...) \ +({ \ + static struct lock_class_key __exited_key, __parked_key; \ + _kthread_create_worker_on_cpu(cpu, flags, &__exited_key, &__parked_key,\ + ##namefmt); \ +}) bool kthread_queue_work(struct kthread_worker *worker, struct kthread_work *work); diff --git a/kernel/kthread.c b/kernel/kthread.c index cd50e99202b0..9022806818fc 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -32,6 +32,7 @@ struct kthread_create_info int (*threadfn)(void *data); void *data; int node; + struct lock_class_key *exited_key, *parked_key; /* Result passed back to kthread_create() from kthreadd. */ struct task_struct *result; @@ -221,8 +222,17 @@ static int kthread(void *_create) } self->data = data; - init_completion(&self->exited); - init_completion(&self->parked); + /* these two completions are shared with all kthread, which is bonghist + * imo */ + lockdep_init_map_crosslock(&self->exited.map.map, + "(kthread completion)->exited", + create->exited_key, 0); + init_completion_map(&self->exited, &self->exited.map.map); + lockdep_init_map_crosslock(&self->parked.map.map, + "(kthread completion)->parked", + create->parked_key, 0); + init_completion_map(&self->parked, &self->exited.map.map); + current->vfork_done = &self->exited; /* OK, tell user we're spawned, wait for stop or wakeup */ @@ -272,9 +282,11 @@ static void create_kthread(struct kthread_create_info *create) } } -static __printf(4, 0) +static __printf(6, 0) struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data), void *data, int node, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, const char namefmt[], va_list args) { @@ -289,6 +301,8 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data), create->data = data; create->node = node; create->done = &done; + create->exited_key = exited_key; + create->parked_key = parked_key; spin_lock(&kthread_create_lock); list_add_tail(&create->list, &kthread_create_list); @@ -353,21 +367,24 @@ struct task_struct *__kthread_create_on_node(int (*threadfn)(void *data), * * Returns a task_struct or ERR_PTR(-ENOMEM) or ERR_PTR(-EINTR). */ -struct task_struct *kthread_create_on_node(int (*threadfn)(void *data), - void *data, int node, - const char namefmt[], - ...) +struct task_struct *_kthread_create_on_node(int (*threadfn)(void *data), + void *data, int node, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, + const char namefmt[], + ...) { struct task_struct *task; va_list args; va_start(args, namefmt); - task = __kthread_create_on_node(threadfn, data, node, namefmt, args); + task = __kthread_create_on_node(threadfn, data, node, + exited_key, parked_key, namefmt, args); va_end(args); return task; } -EXPORT_SYMBOL(kthread_create_on_node); +EXPORT_SYMBOL(_kthread_create_on_node); static void __kthread_bind_mask(struct task_struct *p, const struct cpumask *mask, long state) { @@ -421,14 +438,16 @@ EXPORT_SYMBOL(kthread_bind); * Description: This helper function creates and names a kernel thread * The thread will be woken and put into park mode. */ -struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data), +struct task_struct *_kthread_create_on_cpu(int (*threadfn)(void *data), void *data, unsigned int cpu, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, const char *namefmt) { struct task_struct *p; - p = kthread_create_on_node(threadfn, data, cpu_to_node(cpu), namefmt, - cpu); + p = _kthread_create_on_node(threadfn, data, cpu_to_node(cpu), + exited_key, parked_key, namefmt, cpu); if (IS_ERR(p)) return p; kthread_bind(p, cpu); @@ -649,8 +668,10 @@ int kthread_worker_fn(void *worker_ptr) } EXPORT_SYMBOL_GPL(kthread_worker_fn); -static __printf(3, 0) struct kthread_worker * +static __printf(5, 0) struct kthread_worker * __kthread_create_worker(int cpu, unsigned int flags, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, const char namefmt[], va_list args) { struct kthread_worker *worker; @@ -666,8 +687,8 @@ __kthread_create_worker(int cpu, unsigned int flags, if (cpu >= 0) node = cpu_to_node(cpu); - task = __kthread_create_on_node(kthread_worker_fn, worker, - node, namefmt, args); + task = __kthread_create_on_node(kthread_worker_fn, worker, node, + exited_key, parked_key, namefmt, args); if (IS_ERR(task)) goto fail_task; @@ -694,18 +715,22 @@ __kthread_create_worker(int cpu, unsigned int flags, * when the worker was SIGKILLed. */ struct kthread_worker * -kthread_create_worker(unsigned int flags, const char namefmt[], ...) +_kthread_create_worker(unsigned int flags, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, + const char namefmt[], ...) { struct kthread_worker *worker; va_list args; va_start(args, namefmt); - worker = __kthread_create_worker(-1, flags, namefmt, args); + worker = __kthread_create_worker(-1, flags, exited_key, parked_key, + namefmt, args); va_end(args); return worker; } -EXPORT_SYMBOL(kthread_create_worker); +EXPORT_SYMBOL(_kthread_create_worker); /** * kthread_create_worker_on_cpu - create a kthread worker and bind it @@ -725,19 +750,22 @@ EXPORT_SYMBOL(kthread_create_worker); * when the worker was SIGKILLed. */ struct kthread_worker * -kthread_create_worker_on_cpu(int cpu, unsigned int flags, +_kthread_create_worker_on_cpu(int cpu, unsigned int flags, + struct lock_class_key *exited_key, + struct lock_class_key *parked_key, const char namefmt[], ...) { struct kthread_worker *worker; va_list args; va_start(args, namefmt); - worker = __kthread_create_worker(cpu, flags, namefmt, args); + worker = __kthread_create_worker(cpu, flags, exited_key, parked_key, + namefmt, args); va_end(args); return worker; } -EXPORT_SYMBOL(kthread_create_worker_on_cpu); +EXPORT_SYMBOL(_kthread_create_worker_on_cpu); /* * Returns true when the work could not be queued at the moment. -- 2.15.0 From 1585625727300846932@xxx Fri Dec 01 23:22:11 +0000 2017 X-GM-THRID: 1585625727300846932 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread