Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp3487850pxv; Mon, 12 Jul 2021 19:16:57 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxohnPdbIY+XUwW9LZNNNnZ4JBjbUDT+kdJpR49si5sYV/WSyvEp1EjdB139RG3WThM5tl1 X-Received: by 2002:aa7:c3d0:: with SMTP id l16mr2363250edr.225.1626142617386; Mon, 12 Jul 2021 19:16:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626142617; cv=none; d=google.com; s=arc-20160816; b=MuARh3cpx/zmA9GF0YcTViq2wt43h+81NjqVl7B9c6OnkGYvXpyQQXv7wuzWGSrtmO 1NPHMFeMmHQgK9UlzES39xaT0XTbYCt0bLwadDTFdpKrt9ubI7043vUipHXyZ4gkqkIk z5Oer9VWIBS3Ej44ajnUD2wRmNEME9f1DjER5m46QihuP02JttLNEvn7piBSwXivrQHV C26xpvUhIis4opHn8WR28+5nsdyOe3vWVa6D8ozvLjIN/rCFv3vQDdiYuq3pZoYIhBEW C4+iWfElnJ4IJC28V/QFU03wetpoR7x6+AQ5rPE0s2EV0esbh1sY5uOqCz7d5V/FTA8l KR6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=xJavVTfNWhtpN9cK3gRrytjNmd7xz7skpAOWkhfRqSk=; b=kJQBCGTrFLVeqAjjmcXesjrRN47O19ML7dzWoym1rhexkMks8qfSYZbZ6EoeGOxUck Iu3Fo/TeOQZuIocwBMYZ/VpGzbaSSvUZO/Xjy9ppvb/e6tINoZI9hqKLlBkkHsUXjQvl VA/ZvI7HSHt86l4mbqgfWOOn0vaQeiv4kDD9h4I6h3v2sNj8Z1klRgzsKdL/wA+JAR65 p7MaNQN75A/YS3JPE9gaUQQT3xwP8JFmE1jhxIiZU+6v1cYyIlR29v5YHL1wl0vsQjeV Q9iionZmnn2j/9y6q5ekjcHNfqT3ArcS5RV7saRCQDI0iQA7CaYRTLcOhKWmRQPL7jqV 3nVQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@infradead.org header.s=casper.20170209 header.b=BWJ5IeYD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dg1si18073502edb.139.2021.07.12.19.16.32; Mon, 12 Jul 2021 19:16:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@infradead.org header.s=casper.20170209 header.b=BWJ5IeYD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229931AbhGMCSa (ORCPT + 99 others); Mon, 12 Jul 2021 22:18:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47656 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229521AbhGMCS3 (ORCPT ); Mon, 12 Jul 2021 22:18:29 -0400 Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:8b0:10b:1236::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D285AC0613DD; Mon, 12 Jul 2021 19:15:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=In-Reply-To:Content-Type:MIME-Version: References:Message-ID:Subject:Cc:To:From:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=xJavVTfNWhtpN9cK3gRrytjNmd7xz7skpAOWkhfRqSk=; b=BWJ5IeYDzBpfCxr6ONu4e9+vr0 WDw6K+XJXd3pWafSZzG9GLPx1+YCV1GSQsOaGRWoOGYqTboibclpE+PeWiSx67JixZrTlAYy+YP4T /xO+cURfcqiKEYY9Fy/dosw/mXDt5Cq5pKeJe/W+WEYJi5+pqT4vPK8GnzksEvdxODZJDev+Bcc0O 34J1BQvt3XMsGb2qC9t0SBuNeg3OfOEFK1jKwuRS9O+cqtJSCITFAdFGFUrKdkZNUu15eZsI9KN7k ZTGM0VLaX/OJCTzl0sF1SFwVl8hvkdYcqcqnYO6e6NA2ENH6IlgY/m83rJXaZ09IBXcyz3vuNqY5D djP2UfCw==; Received: from willy by casper.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1m37x0-000eHy-EK; Tue, 13 Jul 2021 02:15:16 +0000 Date: Tue, 13 Jul 2021 03:15:10 +0100 From: Matthew Wilcox To: Johannes Weiner Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, Christoph Hellwig , Jeff Layton , "Kirill A . Shutemov" , Vlastimil Babka , William Kucharski , David Howells , Linus Torvalds , Andrew Morton , Hugh Dickins , Peter Zijlstra Subject: Re: [PATCH v13 010/137] mm: Add folio flag manipulation functions Message-ID: References: <20210712030701.4000097-1-willy@infradead.org> <20210712030701.4000097-11-willy@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Jul 12, 2021 at 08:24:09PM -0400, Johannes Weiner wrote: > On Mon, Jul 12, 2021 at 04:04:54AM +0100, Matthew Wilcox (Oracle) wrote: > > +/* Whether there are one or multiple pages in a folio */ > > +static inline bool folio_single(struct folio *folio) > > +{ > > + return !folio_head(folio); > > +} > > Reading more converted code in the series, I keep tripping over the > new non-camelcased flag testers. Added PeterZ as he asked for it. https://lore.kernel.org/linux-mm/20210419135528.GC2531743@casper.infradead.org/ > It's not an issue when it's adjectives: folio_uptodate(), > folio_referenced(), folio_locked() etc. - those are obvious. But nouns > and words that overlap with struct member names can easily be confused > with non-bool accessors and lookups. Pop quiz: flag test or accessor? > > folio_private() > folio_lru() > folio_nid() > folio_head() > folio_mapping() > folio_slab() > folio_waiters() I know the answers to each of those, but your point is valid. So what's your preferred alternative? folio_is_lru(), folio_is_uptodate(), folio_is_slab(), etc? I've seen suggestions for folio_test_lru(), folio_test_uptodate(), and I don't much care for that alternative. > This requires a lot of double-taking on what is actually being > queried. Bool types, ! etc. don't help, since we test pointers for > NULL/non-NULL all the time. > > I see in a later patch you changed the existing page_lru() (which > returns an enum) to folio_lru_list() to avoid the obvious collision > with the PG_lru flag test. page_private() has the same problem but it > changed into folio_get_private() (no refcounting involved). There > doesn't seem to be a consistent, future-proof scheme to avoid this new > class of collisions between flag testing and member accessors. > > There is also an inconsistency between flag test and set that makes me > pause to think if they're actually testing and setting the same thing: > > if (folio_idle(folio)) > folio_clear_idle_flag(folio); > > Compare this to check_move_unevictable_pages(), where we do > > if (page_evictable(page)) > ClearPageUnevictable(page); > > where one queries a more complex, contextual userpage state and the > other updates the corresponding pageframe bit flag. > > The camelcase stuff we use for page flag testing is unusual for kernel > code. But the page API is also unusually rich and sprawling. What > would actually come close? task? inode? Having those multiple > namespaces to structure and organize the API has been quite helpful. > > On top of losing the flagops namespacing, this series also disappears > many _page() operations (which currently optically distinguish > themselves from page_() accessors) into the shared folio_ > namespace. This further increases the opportunities for collisions, > which force undesirable naming compromises and/or ambiguity. > > More double-taking when the verb can be read as a noun: lock_folio() > vs folio_lock(). > > Now, is anybody going to mistake folio_lock() for an accessor? Not > once they think about it. Can you figure out and remember what > folio_head() returns? Probably. What about all the examples above at > the same time? Personally, I'm starting to struggle. It certainly > eliminates syntactic help and pattern matching, and puts much more > weight on semantic analysis and remembering API definitions. Other people have given the opposite advice. For example, https://lore.kernel.org/linux-mm/YMmfQNjExNs3cuyq@kroah.com/ > What about functions like shrink_page_list() which are long sequences > of page queries and manipulations? Many lines would be folio_ > with no further cue whether you're looking at tests, accessors, or a > high-level state change that is being tested for success. There are > fewer visual anchors to orient yourself when you page up and down. It > quite literally turns some code into blah_(), blah_(), blah_(): > > if (!folio_active(folio) && !folio_unevictable(folio)) { > folio_del_from_lru_list(folio, lruvec); > folio_set_active_flag(folio); > folio_add_to_lru_list(folio, lruvec); > trace_mm_lru_activate(&folio->page); > } I actually like the way that looks (other than the trace_mm_lru_activate() which is pending a conversion from page to folio). But I have my head completely down in it, and I can't tell what works for someone who's fresh to it. I do know that it's hard to change from an API you're used to (and that's part of the cost of changing an API), and I don't know how to balance that against making a more discoverable API. > Think about the mental strain of reading and writing complicated > memory management code with such a degree of syntactic parsimony, let > alone the repetetive monotony. > > In those few lines of example code alone, readers will pause on things > that should be obvious, and miss grave errors that should stand out. > > Add compatible return types to similarly named functions and we'll > provoke subtle bugs that the compiler won't catch either. > > There are warts and inconsistencies in our naming patterns that could > use cleanups. But I think this compresses a vast API into one template > that isn't nearly expressive enough to adequately communicate and > manage the complexity of the underlying structure and its operations. I don't want to dismiss your concerns. I just don't agree with them. If there's a consensus on folio_verb() vs verb_folio(), I'm happy to go back through all these patches and do the rename.