Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933610Ab0LUEmU (ORCPT ); Mon, 20 Dec 2010 23:42:20 -0500 Received: from mail.windriver.com ([147.11.1.11]:42480 "EHLO mail.windriver.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933564Ab0LUEmT (ORCPT ); Mon, 20 Dec 2010 23:42:19 -0500 Date: Tue, 21 Dec 2010 12:40:50 +0800 From: Yong Zhang To: Tejun Heo Cc: Yong Zhang , Andy Walls , linux-kernel@vger.kernel.org, nicolas.mailhot@laposte.net, Jarod Wilson , Ingo Molnar , Mauro Carvalho Chehab , Hans Verkuil , Andrew Morton Subject: [V2 PATCH] kthread_work: Make lockdep happy Message-ID: <20101221044050.GA25718@windriver.com> Reply-To: Yong Zhang References: <1292762975.2403.29.camel@localhost> <4D0F8276.9070903@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <4D0F8276.9070903@kernel.org> User-Agent: Mutt/1.5.20 (2009-06-14) X-OriginalArrivalTime: 21 Dec 2010 04:40:52.0447 (UTC) FILETIME=[3F80D6F0:01CBA0C9] Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3645 Lines: 109 From: Yong Zhang Subject: [V2 PATCH] kthread_work: Make lockdep happy spinlock in kthread_worker and wait_queue_head in kthread_work both should be lockdep sensible. So change the interface to make it suiltable for CONFIG_LOCKDEP. Reported-by: Nicolas Signed-off-by: Yong Zhang Cc: Tejun Heo Cc: Andrew Morton Cc: Andy Walls --- Changes from V1: *According to Tejun, kthread_worker could be defined on stack, So introduce DEFINE_KTHREAD_WORKER_ONSTACK. *Change wrong setting to kthread_work->task. Thanks Adny for pointing it. *including some minor issue. BTW, only passed build. include/linux/kthread.h | 45 +++++++++++++++++++++++++++++++++++---------- kernel/kthread.c | 9 +++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 685ea65..f8b3320 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h @@ -81,16 +81,41 @@ struct kthread_work { #define DEFINE_KTHREAD_WORK(work, fn) \ struct kthread_work work = KTHREAD_WORK_INIT(work, fn) -static inline void init_kthread_worker(struct kthread_worker *worker) -{ - *worker = (struct kthread_worker)KTHREAD_WORKER_INIT(*worker); -} - -static inline void init_kthread_work(struct kthread_work *work, - kthread_work_func_t fn) -{ - *work = (struct kthread_work)KTHREAD_WORK_INIT(*work, fn); -} +/* + * kthread_worker.lock and kthread_work.done need + * special work if they are defined on stack with + * lockdep enabled. + */ +#ifdef CONFIG_LOCKDEP +# define KTHREAD_WORKER_INIT_ONSTACK(worker) \ + ({ init_kthread_worker(&worker); worker; }) +# define DEFINE_KTHREAD_WORKER_ONSTACK(worker) \ + struct kthread_worker worker = KTHREAD_WORKER_INIT_ONSTACK(worker) +# define KTHREAD_WORK_INIT_ONSTACK(work, fn) \ + ({ init_kthread_work((&work), fn); work; }) +# define DEFINE_KTHREAD_WORK_ONSTACK(work, fn) \ + struct kthread_work work = KTHREAD_WORK_INIT_ONSTACK(work, fn) +#else +# define DEFINE_KTHREAD_WORKER_ONSTACK(worker) DEFINE_KTHREAD_WORKER(worker) +# define DEFINE_KTHREAD_WORK_ONSTACK(work, fn) DEFINE_KTHREAD_WORK(work, fn) +#endif + +extern void __init_kthread_worker(struct kthread_worker *worker, + struct lock_class_key *key); + +#define init_kthread_worker(worker) \ + do { \ + static struct lock_class_key __key; \ + __init_kthread_worker((worker), &__key); \ + } while (0) + +#define init_kthread_work(work, fn) \ + do { \ + memset((work), 0, sizeof(struct kthread_work)); \ + INIT_LIST_HEAD(&(work)->node); \ + (work)->func = (fn); \ + init_waitqueue_head(&(work)->done); \ + } while (0) int kthread_worker_fn(void *worker_ptr); diff --git a/kernel/kthread.c b/kernel/kthread.c index 2dc3786..f760587 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c @@ -265,6 +265,15 @@ int kthreadd(void *unused) return 0; } +void __init_kthread_worker(struct kthread_worker *worker, + struct lock_class_key *key) +{ + spin_lock_init(&worker->lock); + lockdep_set_class(&worker->lock, key); + INIT_LIST_HEAD(&worker->work_list); + worker->task = NULL; +} + /** * kthread_worker_fn - kthread function to process kthread_worker * @worker_ptr: pointer to initialized kthread_worker -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/