From patchwork Fri May 3 21:04:09 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Colin Cross X-Patchwork-Id: 2519431 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 48CDBDF2E5 for ; Fri, 3 May 2013 21:04:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1762489Ab3ECVEW (ORCPT ); Fri, 3 May 2013 17:04:22 -0400 Received: from mail-qc0-f202.google.com ([209.85.216.202]:60752 "EHLO mail-qc0-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1763249Ab3ECVES (ORCPT ); Fri, 3 May 2013 17:04:18 -0400 Received: by mail-qc0-f202.google.com with SMTP id n41so180574qco.1 for ; Fri, 03 May 2013 14:04:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state; bh=+8UvQZDIFUgeZbtH0bCRGvnHvcD2rkiOuZ/02OqDvJg=; b=CqyGyYYKtbFmS6UdIIPQUZW1qU8efGcgT/AZddDzveM4Lwq47jvOrI4Dayk5dOCbyw Ee73b8gdfRvDUi755xsBlQqEOCsfn5hjhrkvu5rb+wnUVIM+mO88YVZgGjZS40q3nCN6 RxQzDWe0+KwpQFvUg7lpa9nmpzx5ucnRtMLEFaowoSc9K5bcqghl2i5pA7r4nsNTT1X+ +2kHnagmjS8TWcimrHKT/gujh286zW8Ifb/xG46WQMKE6h53TXz/CblM7dtjNj8kJjaV riDlCaoDOMdmQHthmzjdLpzEvHQ/0mbgf6izBJXpzDHSJlQVEgUqPRtBh1GBG76UNfJA G4OQ== X-Received: by 10.236.78.103 with SMTP id f67mr9572975yhe.52.1367615057934; Fri, 03 May 2013 14:04:17 -0700 (PDT) Received: from corp2gmr1-1.hot.corp.google.com (corp2gmr1-1.hot.corp.google.com [172.24.189.92]) by gmr-mx.google.com with ESMTPS id s48si1200872yhe.6.2013.05.03.14.04.17 for (version=TLSv1.1 cipher=AES128-SHA bits=128/128); Fri, 03 May 2013 14:04:17 -0700 (PDT) Received: from walnut.mtv.corp.google.com (walnut.mtv.corp.google.com [172.18.105.48]) by corp2gmr1-1.hot.corp.google.com (Postfix) with ESMTP id A7C2531C0AC; Fri, 3 May 2013 14:04:17 -0700 (PDT) Received: by walnut.mtv.corp.google.com (Postfix, from userid 99897) id 412A816132B; Fri, 3 May 2013 14:04:17 -0700 (PDT) From: Colin Cross To: linux-kernel@vger.kernel.org Cc: Trond Myklebust , Len Brown , Pavel Machek , "Rafael J. Wysocki" , Peter Zijlstra , Ingo Molnar , "J. Bruce Fields" , "David S. Miller" , Andrew Morton , Mandeep Singh Baines , Paul Walmsley , Colin Cross , Al Viro , "Eric W. Biederman" , Oleg Nesterov , linux-nfs@vger.kernel.org, linux-pm@vger.kernel.org, netdev@vger.kernel.org, Linus Torvalds , Tejun Heo , Ben Chan Subject: [PATCH 1/2] freezer: add unsafe versions of freezable helpers Date: Fri, 3 May 2013 14:04:09 -0700 Message-Id: <1367615050-3894-1-git-send-email-ccross@android.com> X-Mailer: git-send-email 1.8.2.1 X-Gm-Message-State: ALoCoQnl4WZ/DnRjmCaBQqKw8mvKOhsrtCa7alDRjvns5XX7c7cVVtKhLHNvbgtYr4wK1TdoAo6Um0Yp4j9DUlYBLZpYmul2C35tzkPTNvTH5AcN4uHDCwagmM6PIfW++X8LpQVxvMryvaQ/DN0xuaNz9ccbjSLMGuKkPwcNAoF7lA5QqCAtYypR/4FEJDUCs9FxO5t8J/ji Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org NFS calls the freezable helpers with locks held, which is unsafe and caused lockdep warnings when 6aa9707 "lockdep: check that no locks held at freeze time" was applied (reverted in dbf520a). Add new *_unsafe versions of the helpers that will not run the lockdep test when 6aa9707 is reapplied, and call them from NFS. Signed-off-by: Colin Cross Acked-by: Pavel Machek Acked-by: Tejun Heo --- fs/nfs/inode.c | 2 +- fs/nfs/nfs3proc.c | 2 +- fs/nfs/nfs4proc.c | 4 ++-- include/linux/freezer.h | 42 +++++++++++++++++++++++++++++++++++++++++- net/sunrpc/sched.c | 2 +- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 1f94167..53cbee5 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -79,7 +79,7 @@ int nfs_wait_bit_killable(void *word) { if (fatal_signal_pending(current)) return -ERESTARTSYS; - freezable_schedule(); + freezable_schedule_unsafe(); return 0; } EXPORT_SYMBOL_GPL(nfs_wait_bit_killable); diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index 43ea96c..ce90eb4 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c @@ -33,7 +33,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) res = rpc_call_sync(clnt, msg, flags); if (res != -EJUKEBOX) break; - freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME); + freezable_schedule_timeout_killable_unsafe(NFS_JUKEBOX_RETRY_TIME); res = -ERESTARTSYS; } while (!fatal_signal_pending(current)); return res; diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 0ad025e..a236077 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -266,7 +266,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) *timeout = NFS4_POLL_RETRY_MIN; if (*timeout > NFS4_POLL_RETRY_MAX) *timeout = NFS4_POLL_RETRY_MAX; - freezable_schedule_timeout_killable(*timeout); + freezable_schedule_timeout_killable_unsafe(*timeout); if (fatal_signal_pending(current)) res = -ERESTARTSYS; *timeout <<= 1; @@ -4309,7 +4309,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4 static unsigned long nfs4_set_lock_task_retry(unsigned long timeout) { - freezable_schedule_timeout_killable(timeout); + freezable_schedule_timeout_killable_unsafe(timeout); timeout <<= 1; if (timeout > NFS4_LOCK_MAXTIMEOUT) return NFS4_LOCK_MAXTIMEOUT; diff --git a/include/linux/freezer.h b/include/linux/freezer.h index e70df40..5b31e21c 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -46,7 +46,11 @@ extern int freeze_kernel_threads(void); extern void thaw_processes(void); extern void thaw_kernel_threads(void); -static inline bool try_to_freeze(void) +/* + * DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION + * If try_to_freeze causes a lockdep warning it means the caller may deadlock + */ +static inline bool try_to_freeze_unsafe(void) { might_sleep(); if (likely(!freezing(current))) @@ -54,6 +58,11 @@ static inline bool try_to_freeze(void) return __refrigerator(false); } +static inline bool try_to_freeze(void) +{ + return try_to_freeze_unsafe(); +} + extern bool freeze_task(struct task_struct *p); extern bool set_freezable(void); @@ -115,6 +124,14 @@ static inline void freezer_count(void) try_to_freeze(); } +/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */ +static inline void freezer_count_unsafe(void) +{ + current->flags &= ~PF_FREEZER_SKIP; + smp_mb(); + try_to_freeze_unsafe(); +} + /** * freezer_should_skip - whether to skip a task when determining frozen * state is reached @@ -152,6 +169,14 @@ static inline bool freezer_should_skip(struct task_struct *p) freezer_count(); \ }) +/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */ +#define freezable_schedule_unsafe() \ +({ \ + freezer_do_not_count(); \ + schedule(); \ + freezer_count_unsafe(); \ +}) + /* Like schedule_timeout_killable(), but should not block the freezer. */ #define freezable_schedule_timeout_killable(timeout) \ ({ \ @@ -162,6 +187,16 @@ static inline bool freezer_should_skip(struct task_struct *p) __retval; \ }) +/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */ +#define freezable_schedule_timeout_killable_unsafe(timeout) \ +({ \ + long __retval; \ + freezer_do_not_count(); \ + __retval = schedule_timeout_killable(timeout); \ + freezer_count_unsafe(); \ + __retval; \ +}) + /* * Freezer-friendly wrappers around wait_event_interruptible(), * wait_event_killable() and wait_event_interruptible_timeout(), originally @@ -225,9 +260,14 @@ static inline void set_freezable(void) {} #define freezable_schedule() schedule() +#define freezable_schedule_unsafe() schedule() + #define freezable_schedule_timeout_killable(timeout) \ schedule_timeout_killable(timeout) +#define freezable_schedule_timeout_killable_unsafe(timeout) \ + schedule_timeout_killable(timeout) + #define wait_event_freezable(wq, condition) \ wait_event_interruptible(wq, condition) diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index f8529fc..8dcfadc 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -254,7 +254,7 @@ static int rpc_wait_bit_killable(void *word) { if (fatal_signal_pending(current)) return -ERESTARTSYS; - freezable_schedule(); + freezable_schedule_unsafe(); return 0; }