From patchwork Fri Apr 21 22:12:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Doug Anderson X-Patchwork-Id: 13220743 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 D7660C77B7E for ; Fri, 21 Apr 2023 22:13:28 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 755946B0075; Fri, 21 Apr 2023 18:13:28 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 6DEF06B0078; Fri, 21 Apr 2023 18:13:28 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 532026B007B; Fri, 21 Apr 2023 18:13:28 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 3D09A6B0075 for ; Fri, 21 Apr 2023 18:13:28 -0400 (EDT) Received: from smtpin08.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 10D2A1606BE for ; Fri, 21 Apr 2023 22:13:28 +0000 (UTC) X-FDA: 80706800496.08.F7AFEA3 Received: from mail-pf1-f175.google.com (mail-pf1-f175.google.com [209.85.210.175]) by imf07.hostedemail.com (Postfix) with ESMTP id 42D3F40008 for ; Fri, 21 Apr 2023 22:13:26 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=G4PoB7oj; spf=pass (imf07.hostedemail.com: domain of dianders@chromium.org designates 209.85.210.175 as permitted sender) smtp.mailfrom=dianders@chromium.org; dmarc=pass (policy=none) header.from=chromium.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1682115206; 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-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=q5AkNpnnC51XtdBu29L1YvEWhYLiet10/hNPEtnlk4k=; b=dTrZg9i55fA6z9jfPAS2ZM66+rZPz5tK1p7as9scwEEg+6jiIqIBsK2bnjQibQE4zjZUFg N8aOqxbOWSNp5TWpc+dB5JAJcedu27FzDvqWQAErKEfwusk1Lx8La3YsIAnfw7UmLxDmG3 bESwyz1V4dntOXn7BJ1mGJd32RcH3tE= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=pass header.d=chromium.org header.s=google header.b=G4PoB7oj; spf=pass (imf07.hostedemail.com: domain of dianders@chromium.org designates 209.85.210.175 as permitted sender) smtp.mailfrom=dianders@chromium.org; dmarc=pass (policy=none) header.from=chromium.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1682115206; a=rsa-sha256; cv=none; b=Qv1VpwtHPGvOEOfME5xUxtiTS8uoZwvLHDezodc8hiQ9oIRO/eEggec+MoGwjf1gun4I4V pkdjWzKE5Ia+K0/hw7JX4qNxA5EJpLc8pONVVPUEPKBEnw8na+mbB2XiEZzr2lUsAtIvw5 lRIrUW+8fO/6VYS3Wz0J881JS+Yavqg= Received: by mail-pf1-f175.google.com with SMTP id d2e1a72fcca58-63b64a32fd2so3665876b3a.2 for ; Fri, 21 Apr 2023 15:13:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1682115205; x=1684707205; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=q5AkNpnnC51XtdBu29L1YvEWhYLiet10/hNPEtnlk4k=; b=G4PoB7ojaq05ZoUvu0bGhZVqKkk7zuFsPAQngKsh3YkvxtolTqu1sE5QemG7mwI9bC +lav55U9fdGkURLbrLnJpkwmFYqt+QPV1H3FtmqsyKCWezQ4MHw4sDrMDuq7BBrcauHj vF1OEuZHKgdoBCROSFAfcnRZzV8U5N65M2Rkk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682115205; x=1684707205; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=q5AkNpnnC51XtdBu29L1YvEWhYLiet10/hNPEtnlk4k=; b=EFhKfmqW/tijQN8uyCwvap2ZqEdpkFs+u0qstn4n1Qq5NP5RdrEl5QXyjYYMLYFUNP 8sIAbqCf333YosqIdX+BsmzkqYH3Gh+hHtnxUtnmxec7cEQoBCiLdYExm6h2IFRPbNng 9miLaRfW7iXkYoMg2f/rSCtdvRBk2VmIUsi/+Vlt16F3TIvlz+pqemAkeSUy7y8VwZ/9 RltZ+KbNo42p3toPcO/1umzvkMtFS/dbR426qy1pPhKQpar0Dbe7ZXj9NMMg3ZbAJO0h 2WRYZJTzaF6+1JpoVvhJH51nfilXjHGinmJJi0wJvq/Nprdgk1p7gliYZGVS9Gm2+Kuo n6kQ== X-Gm-Message-State: AAQBX9fLGFN6n0VPe5V6Lzr1nnkoELOzTu+UJzkfm1AinzSAFKTDmjkQ l2KOGbP0Fir67DiwK4yfQkvMcA== X-Google-Smtp-Source: AKy350Zf5b8NMr8PvbXnnwZSXrydNzrK4lJ4UsMs/fDtsJnXPPkwv+LxUNSlTubSDT1jS6eyThlL9A== X-Received: by 2002:a05:6a00:1393:b0:63f:15cc:9c1a with SMTP id t19-20020a056a00139300b0063f15cc9c1amr6134194pfg.1.1682115205182; Fri, 21 Apr 2023 15:13:25 -0700 (PDT) Received: from tictac2.mtv.corp.google.com ([2620:15c:9d:2:87cc:9018:e569:4a27]) by smtp.gmail.com with ESMTPSA id y72-20020a62644b000000b006372791d708sm3424715pfb.104.2023.04.21.15.13.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Apr 2023 15:13:24 -0700 (PDT) From: Douglas Anderson To: Andrew Morton , Mel Gorman , Vlastimil Babka , Ying , Alexander Viro , Christian Brauner Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, Yu Zhao , linux-fsdevel@vger.kernel.org, Matthew Wilcox , Douglas Anderson , Bart Van Assche , Ben Segall , Daniel Bristot de Oliveira , Dietmar Eggemann , Ingo Molnar , Jan Kara , Juri Lelli , Mel Gorman , Mikulas Patocka , Peter Zijlstra , "Ritesh Harjani (IBM)" , Steven Rostedt , Valentin Schneider , Vincent Guittot , Will Deacon , Zhang Yi Subject: [PATCH v2 2/4] buffer: Add lock_buffer_timeout() Date: Fri, 21 Apr 2023 15:12:46 -0700 Message-ID: <20230421151135.v2.2.Ie146eec4d41480ebeb15f0cfdfb3bc9095e4ebd9@changeid> X-Mailer: git-send-email 2.40.0.634.g4ca3ef3211-goog In-Reply-To: <20230421221249.1616168-1-dianders@chromium.org> References: <20230421221249.1616168-1-dianders@chromium.org> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 42D3F40008 X-Stat-Signature: p5btsaosxhhs3rmpe3diimcoqj9kwke1 X-HE-Tag: 1682115206-926695 X-HE-Meta: U2FsdGVkX19+AVCDyk0SuydCzOjEe42cIJr4nWMQGkr0q+PK0HVrQwt9auVVBde3DoNxKXnqMTWqUVRgHllQAhovGPJyVX4nduYN57FTLqNGSERNdoB1Nr/caTE11QdJJJKKbapn4k9geOEeJDsGPPjG+fNfrUvB/w7pC/qwqgvb0VG/CpMgIG4MYNiSz8VfYXe7hcYWNPTIJLDxOdwaLOHo2OMRMmLVB97QWyXtG+R0eiSdZKEkRgM0HcW3ECR6J6vOjniDO6p6Sk9FFiOmT/cW4NARKiOk5ScXOUWW/pQY1MiOfnqhlBR326gkFPvT7SL+IemLHzWYDkd+FPG/FPesxLX2CqY51Z0cuyK+Y8NfHOiw9DOXC6KXF+PwKuha4uCzqU6521fFjmHdmv6nu7dr2nFOOpLqZDwEorPSyURDtcFxEJawTR2KRJtCVyxvmw8/RRjuaDcZwswJ9bo8LixlddaTAUSWiik8A0CT1cseccMv3dzc3nBF0j/A9wCqaB5ME+EMYcmjwH9XhdQy/RQAPRwxOAQlq8P+9+vnsRnrwSCaQRzI0+JPulGIVpwOHY2sirq0kCN8DpKB3Z/xTqDOFF8NJRGnf0ZcaxiJTsSmIbe4w9X+fNlFuCSPKUUS6r+anNWL1F/zikEY7YIuteP/7GKRzdGC0xTJLqMnpBihseqWv3WXGhKksinqiGXkEkPTpiuOronzFgvJI0hScPQrianL5Kx/OK60Y11Q1Dr1iuKVFdUzLtNlYXsIO/ttt/jYSGnIfMoTrocDWSKDNv94KRZUYXOAxQlbME0cgO1TtqUwzGpd/gbFFNqhGbmC0+223wzc0RNZBuoVvJlAfaY1uyWfFu7oWBBTf3GxRl4xSXGdFF267GeWxV366ao17NH58da5CGXkS8vpTvK298+sSkxeNaHfZK/uai7oxPfSPr2ixGcZ6332sRZfYS2QVNlRlxJ0Gtkj3pLXigv pFU3rYg9 iNaOWxo2ij//2Rn0y6+nvmGFDLa6qxVcvs85jslZwwT2OlV1ru9wUAjvphSAQZ6K0vNQLsVD5xkjjXMFOjN03eDyFA5AvJl12rmuu0hfjL29s6mJikih1jzmYJo4PHThQj7Vd2F8iPzQ+Pp1JrQTfxp+8AKL9DFNw6FCc/zbqocK5mNQDI8F4YDFzKfi5ePtwfMYlB6x3rs5AEgZTOj1tBx9CZ/3dza++25bb/ZYsCmYs7FfsjVkC3i6KWMP3e2EBLSuzAcqYM97WWBwMtoitcsWcW8XDE39DIP94BcTx5FqVEIsVSaZBmzhb7NB94HrnkRYugFkEv5WTB7L81mQaNglpcr0GarF4dFFESFGqtuYaOD46qz1LreelIw0CHAqac49YCm4vPbVusX24WM93M1PJO4sEM8ZeK9EZMTDuyjufLoDWJN/N45ku99ZOcgGj+fHrao430xLXVNvutH8iIg+BTb291xt2ojJyx7PgMueS8vWeVY0HOYMl3i/vY1fTDdpHxO4n04nkfoI/lV38kpfV1A== 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: Add a variant of lock_buffer() 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 lock_buffer_timeout()" new for v2. fs/buffer.c | 7 +++++++ include/linux/buffer_head.h | 10 ++++++++++ include/linux/wait_bit.h | 24 ++++++++++++++++++++++++ kernel/sched/wait_bit.c | 14 ++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/fs/buffer.c b/fs/buffer.c index 9e1e2add541e..fcd19c270024 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -71,6 +71,13 @@ void __lock_buffer(struct buffer_head *bh) } EXPORT_SYMBOL(__lock_buffer); +int __lock_buffer_timeout(struct buffer_head *bh, unsigned long timeout) +{ + return wait_on_bit_lock_io_timeout(&bh->b_state, BH_Lock, + TASK_UNINTERRUPTIBLE, timeout); +} +EXPORT_SYMBOL(__lock_buffer_timeout); + void unlock_buffer(struct buffer_head *bh) { clear_bit_unlock(BH_Lock, &bh->b_state); diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 8f14dca5fed7..2bae464f89d5 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -237,6 +237,7 @@ struct buffer_head *alloc_buffer_head(gfp_t gfp_flags); void free_buffer_head(struct buffer_head * bh); void unlock_buffer(struct buffer_head *bh); void __lock_buffer(struct buffer_head *bh); +int __lock_buffer_timeout(struct buffer_head *bh, unsigned long timeout); int sync_dirty_buffer(struct buffer_head *bh); int __sync_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags); void write_dirty_buffer(struct buffer_head *bh, blk_opf_t op_flags); @@ -400,6 +401,15 @@ static inline void lock_buffer(struct buffer_head *bh) __lock_buffer(bh); } +static inline int lock_buffer_timeout(struct buffer_head *bh, + unsigned long timeout) +{ + might_sleep(); + if (!trylock_buffer(bh)) + return __lock_buffer_timeout(bh, timeout); + return 0; +} + static inline struct buffer_head *getblk_unmovable(struct block_device *bdev, sector_t block, unsigned size) diff --git a/include/linux/wait_bit.h b/include/linux/wait_bit.h index 7725b7579b78..33f0f60b1c8c 100644 --- a/include/linux/wait_bit.h +++ b/include/linux/wait_bit.h @@ -30,6 +30,7 @@ void wake_up_bit(void *word, int bit); int out_of_line_wait_on_bit(void *word, int, wait_bit_action_f *action, unsigned int mode); int out_of_line_wait_on_bit_timeout(void *word, int, wait_bit_action_f *action, unsigned int mode, unsigned long timeout); int out_of_line_wait_on_bit_lock(void *word, int, wait_bit_action_f *action, unsigned int mode); +int out_of_line_wait_on_bit_lock_timeout(void *word, int, wait_bit_action_f *action, unsigned int mode, unsigned long timeout); struct wait_queue_head *bit_waitqueue(void *word, int bit); extern void __init wait_bit_init(void); @@ -208,6 +209,29 @@ wait_on_bit_lock_io(unsigned long *word, int bit, unsigned mode) return out_of_line_wait_on_bit_lock(word, bit, bit_wait_io, mode); } +/** + * wait_on_bit_lock_io_timeout - wait_on_bit_lock_io() with a timeout + * @word: the word being waited on, a kernel virtual address + * @bit: the bit of the word being waited on + * @mode: the task state to sleep in + * @timeout: the timeout in jiffies; %MAX_SCHEDULE_TIMEOUT means wait forever + * + * Returns zero if the bit was (eventually) found to be clear and was + * set. Returns non-zero if a timeout happened or a signal was delivered to + * the process and the @mode allows that signal to wake the process. + */ +static inline int +wait_on_bit_lock_io_timeout(unsigned long *word, int bit, unsigned mode, + unsigned long timeout) +{ + might_sleep(); + if (!test_and_set_bit(bit, word)) + return 0; + return out_of_line_wait_on_bit_lock_timeout(word, bit, + bit_wait_io_timeout, + mode, timeout); +} + /** * wait_on_bit_lock_action - wait for a bit to be cleared, when wanting to set it * @word: the word being waited on, a kernel virtual address diff --git a/kernel/sched/wait_bit.c b/kernel/sched/wait_bit.c index 0b1cd985dc27..629acd1c6c79 100644 --- a/kernel/sched/wait_bit.c +++ b/kernel/sched/wait_bit.c @@ -118,6 +118,20 @@ int __sched out_of_line_wait_on_bit_lock(void *word, int bit, } EXPORT_SYMBOL(out_of_line_wait_on_bit_lock); +int __sched out_of_line_wait_on_bit_lock_timeout(void *word, int bit, + wait_bit_action_f *action, + unsigned mode, + unsigned long timeout) +{ + struct wait_queue_head *wq_head = bit_waitqueue(word, bit); + DEFINE_WAIT_BIT(wq_entry, word, bit); + + wq_entry.key.timeout = jiffies + timeout; + + return __wait_on_bit_lock(wq_head, &wq_entry, action, mode); +} +EXPORT_SYMBOL(out_of_line_wait_on_bit_lock_timeout); + void __wake_up_bit(struct wait_queue_head *wq_head, void *word, int bit) { struct wait_bit_key key = __WAIT_BIT_KEY_INITIALIZER(word, bit);