From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id F358CC77B76 for ; Sun, 23 Apr 2023 07:51:18 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 5C3206B0072; Sun, 23 Apr 2023 03:51:18 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 54B886B0074; Sun, 23 Apr 2023 03:51:18 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 3EC476B0075; Sun, 23 Apr 2023 03:51:18 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 2C46E6B0072 for ; Sun, 23 Apr 2023 03:51:18 -0400 (EDT) Received: from smtpin19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id E47431401E0 for ; Sun, 23 Apr 2023 07:51:17 +0000 (UTC) X-FDA: 80711885394.19.8327861 Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by imf18.hostedemail.com (Postfix) with ESMTP id 61DE51C0006 for ; Sun, 23 Apr 2023 07:51:15 +0000 (UTC) Authentication-Results: imf18.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=nldGAKk+; spf=pass (imf18.hostedemail.com: domain of ying.huang@intel.com designates 192.55.52.136 as permitted sender) smtp.mailfrom=ying.huang@intel.com; dmarc=pass (policy=none) header.from=intel.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1682236276; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=6c+f/ZRRasmIqeOzPtW0Y2PC2t7oXyova9jWkIN0HaE=; b=yw9UmS/yxNzKbkpGcecmlNrVdx7ma+z6hV7Lvi0yuEo+jRHFcMnukOMnZOXuNTlzIE+1Ee 6XrRWuyAaTO+bqhEbR6JYa7NX1isBCWCbCfG68+zfBhOaAwEI62DsE2GilAPFV+kt0F2z8 T0dJyb9/CK50tHd1wmg42IKPLDfDYzQ= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1682236276; a=rsa-sha256; cv=none; b=cZiejurieiRiLKpt6iV4Bd1ypoe6xfDgoR8JGkr1vmTWkV8ueoVPBhGSYCJgJhHlYq3ke6 HlpoHKFfO+CkrGBUNY83kumDc1HJHiioFvSMqLN0N19ilL6O2Ow3GfmYC0cJ/8AGifi077 PWlS2KQjIhGnAMgL056ORfh4YhIc7as= ARC-Authentication-Results: i=1; imf18.hostedemail.com; dkim=pass header.d=intel.com header.s=Intel header.b=nldGAKk+; spf=pass (imf18.hostedemail.com: domain of ying.huang@intel.com designates 192.55.52.136 as permitted sender) smtp.mailfrom=ying.huang@intel.com; dmarc=pass (policy=none) header.from=intel.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1682236275; x=1713772275; h=from:to:cc:subject:references:date:in-reply-to: message-id:mime-version; bh=hLqzuB/dsyGdPuw8pDlg/eKJWZevKf5YyeT9JmqhmFM=; b=nldGAKk+FNm3Ld9GtnJIAB+HHpRg8a/DVqbgcAnLPozpRt2sJlAgPCAo gG62kb96/NDOlpO9bCpXb6R7jgvfk13euOquZR0T0WLnbG8ormwb+Jynr S1LjIv/uEDZBtjI1ewdC2lVjg/Hi29LyOpn57CEWvXfqhSuIL74HdgPEq PDTALFzMORSnYI5qi/PyBjOynVLsAs6IXEyx0bqR4FOWRaQzIwekbQoXA JTo3DGc/H3G7lQ9uLbi+sWhtxGysaAMFJceqqOisg4DKdUR9QMQaBI5oS 9K5PaWXElYo6e1UHk2Cf7VMlURhE/CETC6ken91jxxy4NCXupcHI9deII g==; X-IronPort-AV: E=McAfee;i="6600,9927,10688"; a="325857892" X-IronPort-AV: E=Sophos;i="5.99,220,1677571200"; d="scan'208";a="325857892" Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Apr 2023 00:51:13 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10688"; a="867132673" X-IronPort-AV: E=Sophos;i="5.99,220,1677571200"; d="scan'208";a="867132673" Received: from yhuang6-desk2.sh.intel.com (HELO yhuang6-desk2.ccr.corp.intel.com) ([10.238.208.55]) by orsmga005-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Apr 2023 00:51:10 -0700 From: "Huang, Ying" To: Douglas Anderson Cc: Andrew Morton , Mel Gorman , Vlastimil Babka , Alexander Viro , Christian Brauner , linux-kernel@vger.kernel.org, linux-mm@kvack.org, Yu Zhao , linux-fsdevel@vger.kernel.org, Matthew Wilcox Subject: Re: [PATCH v2 1/4] mm/filemap: Add folio_lock_timeout() References: <20230421221249.1616168-1-dianders@chromium.org> <20230421151135.v2.1.I2b71e11264c5c214bc59744b9e13e4c353bc5714@changeid> Date: Sun, 23 Apr 2023 15:50:01 +0800 In-Reply-To: <20230421151135.v2.1.I2b71e11264c5c214bc59744b9e13e4c353bc5714@changeid> (Douglas Anderson's message of "Fri, 21 Apr 2023 15:12:45 -0700") Message-ID: <87leijkpg6.fsf@yhuang6-desk2.ccr.corp.intel.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=ascii X-Rspam-User: X-Rspamd-Queue-Id: 61DE51C0006 X-Rspamd-Server: rspam09 X-Stat-Signature: hugy9zofzgof9n4xfdstyop96g31ongf X-HE-Tag: 1682236275-178863 X-HE-Meta: U2FsdGVkX1/D0Q5Mw1lOWvvs0qwRIKhiWRw7xyh1Ljz+QfbdpB3F7tHNbCjE+BzACMi6UUih27gMsLdmrXJP0ft5xM5omvZSohfT11lLx6+zxKc5GFItgGN8870+DAMjP7pWt5ilD2gSGzClJHO8g6t+U5AizE3xpaQhJhqK9HvAamH8vjvkFiUXGEynUVejqLdThIRl7JFgqSLNFGLgvd5p2uJvf8WaeBALZa06Aop4YkcRBjN8ojEPsFtFaSMXeGIajK0EA9215NWTHDo1GBHL2LHPUHF+N1FmOcHRowDOxYheaCsUjKvoSgirUN1QG/d3tIQqUGzoJy8ZtUFa1WgrOYvb5oldkDgqh+wyoU54aDGL2XE00cG07/DdvlAK3y01v33WTPRxXghfAnDfOFrnWUZb2NnyLyDOlLKZxdZ53hmh9WOW2eptbVDCaQEpvzogpNX83yUklaJGyB+qjunYygNAX8MmA/FCuxeRlFdTa64/2RGlYY/33PR0N/JvR3k9lmMWApepbczf75JhrzM2CzMhpgXoTaof6NwnE6U9+sAe63itjAp7dO0sOirq5Qz8s+wRAWG9UxB3uJOCk4IIR9XFMnS4vCrk8JslHOPmt4PmWacx/KkQeoVMPnNwIb9J3fELCgUuO/8z/Kro/DlO4/V2nIKzyCM/fJ/bxFfxx5hYgfRowHO1cHb1ptguxc9cmJbG/KRDID40Y0aneaY4VjALWb1H1mAxhzY/+0FQCzvVA2TaPDmHTbiNzOYl184hmaUDRbwhAPpUprXVqCEU5AXa/155fn6gu2j8HKwMbwgYSPDIr/g/JfdTbaEFEnt/Wd66PjPuo/IulPUbDKWowv8z6QfovZEep72ekseJjeoqdEo8W11BD3YZL2sx1cjwCDyKFBwHqu5aUGXTOh4k5BLt8ALSCNrD5uAqp6ou1vja4/QBUdVqOV9bzUfSL5XzI1mUXH7pv0S6a8e CAIMx2XA 5yv9tFVfl171HeJ/uyX+QbF+MX0kGbS0PJNPml3cS+VA/gdoizNypmWFzX6+xqphMiML+Tcoay3yHNh1WeNxxxVW87R3dUHsmt53RB7CQi24idGDhP98XK7gbOHyv0phvIuiyNnWaWlZ5Io0gQmdg8csjztd+8u+JisUYNQ/qAwzvRGRksk2VbVpRUDj9CywI9RVzH9vZk1bW0oTnSsSRzLwlDWEcv/g2GNOXnZg2ub577onB9K16AOUvdntLxtnytsbN X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Douglas Anderson writes: > Add a variant of folio_lock() that can timeout. This is useful to > avoid unbounded waits for the page lock in kcompactd. > > Signed-off-by: Douglas Anderson > --- > > Changes in v2: > - "Add folio_lock_timeout()" new for v2. > > include/linux/pagemap.h | 16 ++++++++++++++ > mm/filemap.c | 47 +++++++++++++++++++++++++++++------------ > 2 files changed, 50 insertions(+), 13 deletions(-) > > diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h > index 0acb8e1fb7af..0f3ef9f79300 100644 > --- a/include/linux/pagemap.h > +++ b/include/linux/pagemap.h > @@ -892,6 +892,7 @@ static inline bool wake_page_match(struct wait_page_queue *wait_page, > } > > void __folio_lock(struct folio *folio); > +int __folio_lock_timeout(struct folio *folio, long timeout); > int __folio_lock_killable(struct folio *folio); > bool __folio_lock_or_retry(struct folio *folio, struct mm_struct *mm, > unsigned int flags); > @@ -952,6 +953,21 @@ static inline void folio_lock(struct folio *folio) > __folio_lock(folio); > } > > +/** > + * folio_lock_timeout() - Lock this folio, with a timeout. > + * @folio: The folio to lock. > + * @timeout: The timeout in jiffies; %MAX_SCHEDULE_TIMEOUT means wait forever. > + * > + * Return: 0 upon success; -ETIMEDOUT upon failure. IIUC, the funtion may return -EINTR too. Otherwise looks good to me. Thanks! Best Regards, Huang, Ying > + */ > +static inline int folio_lock_timeout(struct folio *folio, long timeout) > +{ > + might_sleep(); > + if (!folio_trylock(folio)) > + return __folio_lock_timeout(folio, timeout); > + return 0; > +} > + > /** > * lock_page() - Lock the folio containing this page. > * @page: The page to lock. > diff --git a/mm/filemap.c b/mm/filemap.c > index 2723104cc06a..c6056ec41284 100644 > --- a/mm/filemap.c > +++ b/mm/filemap.c > @@ -1220,7 +1220,7 @@ static inline bool folio_trylock_flag(struct folio *folio, int bit_nr, > int sysctl_page_lock_unfairness = 5; > > static inline int folio_wait_bit_common(struct folio *folio, int bit_nr, > - int state, enum behavior behavior) > + int state, enum behavior behavior, long timeout) > { > wait_queue_head_t *q = folio_waitqueue(folio); > int unfairness = sysctl_page_lock_unfairness; > @@ -1229,6 +1229,7 @@ static inline int folio_wait_bit_common(struct folio *folio, int bit_nr, > bool thrashing = false; > unsigned long pflags; > bool in_thrashing; > + int err; > > if (bit_nr == PG_locked && > !folio_test_uptodate(folio) && folio_test_workingset(folio)) { > @@ -1295,10 +1296,13 @@ static inline int folio_wait_bit_common(struct folio *folio, int bit_nr, > /* Loop until we've been woken or interrupted */ > flags = smp_load_acquire(&wait->flags); > if (!(flags & WQ_FLAG_WOKEN)) { > + if (!timeout) > + break; > + > if (signal_pending_state(state, current)) > break; > > - io_schedule(); > + timeout = io_schedule_timeout(timeout); > continue; > } > > @@ -1324,10 +1328,10 @@ static inline int folio_wait_bit_common(struct folio *folio, int bit_nr, > } > > /* > - * If a signal happened, this 'finish_wait()' may remove the last > - * waiter from the wait-queues, but the folio waiters bit will remain > - * set. That's ok. The next wakeup will take care of it, and trying > - * to do it here would be difficult and prone to races. > + * If a signal/timeout happened, this 'finish_wait()' may remove the > + * last waiter from the wait-queues, but the folio waiters bit will > + * remain set. That's ok. The next wakeup will take care of it, and > + * trying to do it here would be difficult and prone to races. > */ > finish_wait(q, wait); > > @@ -1336,6 +1340,13 @@ static inline int folio_wait_bit_common(struct folio *folio, int bit_nr, > psi_memstall_leave(&pflags); > } > > + /* > + * If we don't meet the success criteria below then we've got an error > + * of some sort. Differentiate between the two error cases. If there's > + * no time left it must have been a timeout. > + */ > + err = !timeout ? -ETIMEDOUT : -EINTR; > + > /* > * NOTE! The wait->flags weren't stable until we've done the > * 'finish_wait()', and we could have exited the loop above due > @@ -1350,9 +1361,9 @@ static inline int folio_wait_bit_common(struct folio *folio, int bit_nr, > * waiter, but an exclusive one requires WQ_FLAG_DONE. > */ > if (behavior == EXCLUSIVE) > - return wait->flags & WQ_FLAG_DONE ? 0 : -EINTR; > + return wait->flags & WQ_FLAG_DONE ? 0 : err; > > - return wait->flags & WQ_FLAG_WOKEN ? 0 : -EINTR; > + return wait->flags & WQ_FLAG_WOKEN ? 0 : err; > } > > #ifdef CONFIG_MIGRATION > @@ -1442,13 +1453,15 @@ void migration_entry_wait_on_locked(swp_entry_t entry, pte_t *ptep, > > void folio_wait_bit(struct folio *folio, int bit_nr) > { > - folio_wait_bit_common(folio, bit_nr, TASK_UNINTERRUPTIBLE, SHARED); > + folio_wait_bit_common(folio, bit_nr, TASK_UNINTERRUPTIBLE, SHARED, > + MAX_SCHEDULE_TIMEOUT); > } > EXPORT_SYMBOL(folio_wait_bit); > > int folio_wait_bit_killable(struct folio *folio, int bit_nr) > { > - return folio_wait_bit_common(folio, bit_nr, TASK_KILLABLE, SHARED); > + return folio_wait_bit_common(folio, bit_nr, TASK_KILLABLE, SHARED, > + MAX_SCHEDULE_TIMEOUT); > } > EXPORT_SYMBOL(folio_wait_bit_killable); > > @@ -1467,7 +1480,8 @@ EXPORT_SYMBOL(folio_wait_bit_killable); > */ > static int folio_put_wait_locked(struct folio *folio, int state) > { > - return folio_wait_bit_common(folio, PG_locked, state, DROP); > + return folio_wait_bit_common(folio, PG_locked, state, DROP, > + MAX_SCHEDULE_TIMEOUT); > } > > /** > @@ -1662,17 +1676,24 @@ EXPORT_SYMBOL_GPL(page_endio); > void __folio_lock(struct folio *folio) > { > folio_wait_bit_common(folio, PG_locked, TASK_UNINTERRUPTIBLE, > - EXCLUSIVE); > + EXCLUSIVE, MAX_SCHEDULE_TIMEOUT); > } > EXPORT_SYMBOL(__folio_lock); > > int __folio_lock_killable(struct folio *folio) > { > return folio_wait_bit_common(folio, PG_locked, TASK_KILLABLE, > - EXCLUSIVE); > + EXCLUSIVE, MAX_SCHEDULE_TIMEOUT); > } > EXPORT_SYMBOL_GPL(__folio_lock_killable); > > +int __folio_lock_timeout(struct folio *folio, long timeout) > +{ > + return folio_wait_bit_common(folio, PG_locked, TASK_KILLABLE, > + EXCLUSIVE, timeout); > +} > +EXPORT_SYMBOL_GPL(__folio_lock_timeout); > + > static int __folio_lock_async(struct folio *folio, struct wait_page_queue *wait) > { > struct wait_queue_head *q = folio_waitqueue(folio);