Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp3423385pxv; Mon, 12 Jul 2021 17:25:18 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyOcSUugq9M6M684NXrj1AtT0KusMKyeYk6rfjYk6S9x6KCp1uSlmgjyjxkg/W63q34yY7J X-Received: by 2002:a05:6e02:669:: with SMTP id l9mr1047901ilt.244.1626135918704; Mon, 12 Jul 2021 17:25:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626135918; cv=none; d=google.com; s=arc-20160816; b=V+k4q8wUDPieiM4MNWti9oJgkfy5n4r6eaTnlWSVHkzqiz2hnpHIOS60hvBFniYZb/ ho9b2b9LaEjLlz6HoOFYxBF+xOPh9DCqPk9MTb8UG9vKuh6OXuPEqs0hMymlAbgqXb4m MqRhCIrFotrDXzrQcdaabtRFzOYbmSTUZ57axad9OjkdRzimAaH9pxZhBX4EUu7xtSok dDBn1U3AORNlteHmsmPrxRBezcBKSFYiExGckA0IWD4qo2kAezMb5+DnSejR0MBkBlA+ HbHvaY0o+6pIM3CYMnVpipwRfqUFFtRqZWE3aBSArthXnYNk396C0iZwyprsG/VKuOBW 6yxA== 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=yB5qAIs9Fc7CEvMMJ8HjSEc+CJeHsMb3Z3r28kd1YEE=; b=pNO0Ul9Jml2ITjUnmEuuSBg6fPIPf2IapSWbQ6t7ZExRYJKYuAQs556VfQhapp1pTp 3dGWMWi/BfIorGoIz42LfKH+tDuCkD+yWJ65U/iJTRw+rvfYaboq2Px+CTkCG+9AR/Ee volpZ7aYJ/x+aFCgMELsPD0Hg8x3Ufmnl4+EkdLP/4tabL4ShcgWv3+8rOuwBDiijYAe IygxpuwsSFRlwi1ZUAQnOKHKP/L2cOccKbSGskXS2DiHt3NUoSrKtLhCpZFdYuCET7M7 xJgM0wgc+PBYB9R3lV0cJpeOUSiLOfzmMoU9ZCVsSRBf5nmaT779uFaKfaaq6+YVkri8 AmiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@cmpxchg-org.20150623.gappssmtp.com header.s=20150623 header.b="01/+1Pey"; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=cmpxchg.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g3si18853913ilc.117.2021.07.12.17.25.05; Mon, 12 Jul 2021 17:25:18 -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=@cmpxchg-org.20150623.gappssmtp.com header.s=20150623 header.b="01/+1Pey"; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=cmpxchg.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233479AbhGMA1B (ORCPT + 99 others); Mon, 12 Jul 2021 20:27:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51258 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233486AbhGMA1B (ORCPT ); Mon, 12 Jul 2021 20:27:01 -0400 Received: from mail-qk1-x72e.google.com (mail-qk1-x72e.google.com [IPv6:2607:f8b0:4864:20::72e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 65FAFC0613DD for ; Mon, 12 Jul 2021 17:24:12 -0700 (PDT) Received: by mail-qk1-x72e.google.com with SMTP id r125so12297119qkf.1 for ; Mon, 12 Jul 2021 17:24:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cmpxchg-org.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=yB5qAIs9Fc7CEvMMJ8HjSEc+CJeHsMb3Z3r28kd1YEE=; b=01/+1PeyYqpCfkWSPiQzQ1/4ZzPCpTK75chfxFtWF7xgFFxO8o4Rb6MeI8H1ivl+R1 1ebZc2s7qCJgIHtRRFKwbcgLSUa4zIa4Kn6y6NMGTV1QlR87DV9iAeYNqMq5bDoBrrmC XSi53W67knvsyOnZ1i+6YWyZWQNWcAk+m6zx/QRcYOJTWpZRpKDsnGM0zk4Tqb3GXrN3 beKx5CGDrwhitiApD8OyX43Jrc3VFvy31lLfrNz0N5XDSD7AxLj9gFkWp+qDmeu0p9Yb o+evI0jqah2VbXE5Lt/o15HtAEE+yZjiMaIPwdVonhgkYelnStKJwaS/TWNSzoI3xkZq sQ3g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=yB5qAIs9Fc7CEvMMJ8HjSEc+CJeHsMb3Z3r28kd1YEE=; b=nn8I1p5RbL1Mz0HYAUrzM/KwEizSSgV+JPtV5Qk6Zz7pRejEXKZrGU4coojxOZrKxo jeb7OEUiXHog38dPjSCdD3kuOssSll2Cq1X1YLdLuP8Re5Sh07vajKpnnOqmcAKAL+5b tdiLuMgBO0VWp+0w22+Hl/R+TWQ0UiT2JtOWbxKzXgjQ9UEw7ZQVrTZ4D5cnXTGehECJ afPeaDyMlLIR5oTy2NTR3aTaBQc7WYPV5QYx8xS0Fe/F323uwEGmecBCd0AmhEoHfrM2 m2rWImhBoq60HwwX8cCcaXlp1XP2EpMMHdSYwp50EsSHu+gHyl/2XYQjFW0M8WYS4yQl dRsw== X-Gm-Message-State: AOAM532TwPTf8fJqkj7ErlxmnXC+XpjVFUAlXDdInv5E3LosfVlOkpBe VIbNlFSFMfqnvTfRVyzp51GYtA44q5yAow== X-Received: by 2002:ae9:dd06:: with SMTP id r6mr1467355qkf.74.1626135851341; Mon, 12 Jul 2021 17:24:11 -0700 (PDT) Received: from localhost ([2620:10d:c091:480::1:a40c]) by smtp.gmail.com with ESMTPSA id x20sm7394463qkp.15.2021.07.12.17.24.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Jul 2021 17:24:10 -0700 (PDT) Date: Mon, 12 Jul 2021 20:24:09 -0400 From: Johannes Weiner To: "Matthew Wilcox (Oracle)" 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 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: <20210712030701.4000097-11-willy@infradead.org> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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. 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() 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. 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); } 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.