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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 07F04C433FE for ; Wed, 4 May 2022 21:44:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378895AbiEDVsO (ORCPT ); Wed, 4 May 2022 17:48:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37314 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1378877AbiEDVsH (ORCPT ); Wed, 4 May 2022 17:48:07 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D9970532E7 for ; Wed, 4 May 2022 14:44:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=Content-Type:MIME-Version:Message-ID: Subject:Cc:To:From:Date:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:In-Reply-To:References; bh=nnLXKYzsn4Ff0H53e/iYWG4pt2fEuSs3Y0Owjo05quQ=; b=rAsWAKrg/BnsEj+sAFL9zDKNzj hycwa5qwZygumLrMwKD/S+OiNu7+Yz+Dbt4bx4+NKHGc0rOdAq/RFrexskpjkW5T9/7nsTBCwZfEM 9EvPXDvEPG0s4fDupLglTDTRiqXhukfN7f/+gDEzMNuL+roIbSVkKAHBxTBXOYCqb8yQzKulD+fF8 EDWCM4CfZ5ykkEQJOwGRWQ7He2cAmCpJJK4gUFET9kjHEGoH8Gv+gIETUY51zeuDloTrVh4ADB4VU 16/8ig2MuowRWAingduT4D+ZrOsle3Aa9WwOKxjWn9BR01RCcv3lKSIAZymkP4MRSTZpH2WIUa2l6 Hs1Q7/Pg==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1nmMn6-00GyNr-6H; Wed, 04 May 2022 21:44:12 +0000 Date: Wed, 4 May 2022 22:44:12 +0100 From: Matthew Wilcox To: Peter Zijlstra , Ingo Molnar , Will Deacon , Waiman Long Cc: "Paul E. McKenney" , Thomas Gleixner , "Liam R. Howlett" , linux-kernel@vger.kernel.org Subject: Wait for mutex to become unlocked Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Paul, Liam and I were talking about some code we intend to write soon and realised there's a missing function in the mutex & rwsem API. We're intending to use it for an rwsem, but I think it applies equally to mutexes. The customer has a low priority task which wants to read /proc/pid/smaps of a higher priority task. Today, everything is awful; smaps acquires mmap_sem read-only, is preempted, then the high-pri task calls mmap() and the down_write(mmap_sem) blocks on the low-pri task. Then all the other threads in the high-pri task block on the mmap_sem as they take page faults because we don't want writers to starve. The approach we're looking at is to allow RCU lookup of VMAs, and then take a per-VMA rwsem for read. Because we're under RCU protection, that looks a bit like this: rcu_read_lock(); vma = vma_lookup(); if (down_read_trylock(&vma->sem)) { rcu_read_unlock(); } else { rcu_read_unlock(); down_read(&mm->mmap_sem); vma = vma_lookup(); down_read(&vma->sem); up_read(&mm->mmap_sem); } (for clarity, I've skipped the !vma checks; don't take this too literally) So this is Good. For the vast majority of cases, we avoid taking the mmap read lock and the problem will appear much less often. But we can do Better with a new API. You see, for this case, we don't actually want to acquire the mmap_sem; we're happy to spin a bit, but there's no point in spinning waiting for the writer to finish when we can sleep. I'd like to write this code: again: rcu_read_lock(); vma = vma_lookup(); if (down_read_trylock(&vma->sem)) { rcu_read_unlock(); } else { rcu_read_unlock(); rwsem_wait_read(&mm->mmap_sem); goto again; } That is, rwsem_wait_read() puts the thread on the rwsem's wait queue, and wakes it up without giving it the lock. Now this thread will never be able to block any thread that tries to acquire mmap_sem for write. Similarly, it may make sense to add rwsem_wait_write() and mutex_wait(). Perhaps also mutex_wait_killable() and mutex_wait_interruptible() (the combinatoric explosion is a bit messy; I don't know that it makes sense to do the _nested, _io variants). Does any of this make sense?