From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73C564343E0 for ; Fri, 10 Jul 2026 13:23:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.176 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783689835; cv=none; b=fa9z1SVkckq5N3QqK4DVXnqrCvL/H247QZcFnhR/jJhNlmjYdsBgwubc6yvUPe8cYHM0prY3iUJBn8NvITB1iA7jV+9T6U8nxGkm+a/amdSxyTIgcJKHSUhAfZ83azgU0OH4bvoXi3yTxgg2WD3YAG6i4s2mVfTCFE3qw/UFE6c= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783689835; c=relaxed/simple; bh=xfG9Yh6PdxwCZ5amhCuAqaFey7nfqtmMZOG3tAoItOg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WyAPbVkg52WdwDwE6jAj921rDtnwM7a5+ReyokwJkexjt+Qi5V2N4Em0FYlkvi4VAngjE/Ot0Xc5tmMBAhfyX4kJKDHQyv2WOhosLnxSWpCrqng07zZPDsws6egAhrCBlurFWuQD0tx2JdbFSS/FqgiSgOjKdn+SLhze1uSS+IY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=f7iaJFTa; arc=none smtp.client-ip=209.85.214.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="f7iaJFTa" Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-2cca0c5799eso7634065ad.0 for ; Fri, 10 Jul 2026 06:23:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1783689833; x=1784294633; darn=vger.kernel.org; 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:content-type; bh=LhRaXJfW0MEUnElMB0BBQ14vfwzvxCxOVpgUd+6T/XY=; b=f7iaJFTa7ua19T/tvI/pSamQdIsm5NoSuaibx6cSN+6bCaplxAY1ZfxQpGkua3FzU9 tP0TYOsUT7DutNG6MihKf1PXOuvuiedi7pCLR0oXRWPP41A/zPdbviddTdg7rfpIPImV Y5H6ihJYXmsZty2R+OXVSjkD7+YIgYLFVRff7D49wpcCo2caCaa4IW5ea/8ZiEZVpVfn kLH/K8yyZXooJKSHpUF0UIbDBm6GrOTPLDn5Bk9FAkKD/CDJMlApd+NmgM+ZpdA1Mkd6 lEq+DMy03FPF2vFNjRJvL8z3B89NTbMU2ncTptSH1DOgdFzferuyC/51QT5/97ZMJWCy GbPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783689833; x=1784294633; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=LhRaXJfW0MEUnElMB0BBQ14vfwzvxCxOVpgUd+6T/XY=; b=rBqz/jNahz8MutZ36CyvaVOiP+CCUR12zk3r5l7zQTkn0R60P33JCYANWpDtqbY8E1 j7/z5+m2MwT53YAPYqMrB9VN4EtNuHgaO+LJLBPeyN5humNWR/A/cauNL3G/UkzGxTzQ bFsM3qcibG/oCh9OdGVobUbAL3MhKzcBKLLA2HKMFg/seHlPeWq+auG97T4Uc4tH8xdn FoipDgeysiIT3n7zUqrQynbIu9i+D6dFRKjS7LMv3zQ/nE0GUvPdY7pK6XgP/8YNF05r i2Cj4mS2Pt6JYH6uB7MitX+Szb0qju7qwlXMHeYHR4jXRvmdy32eEalbiJLkgu6MI6uG fxYA== X-Forwarded-Encrypted: i=1; AHgh+RoeocHhlow/45dV6lQhdqDAGTDrs8c7CRC70zyn1Z8Wb82o9F4CtbiTfnAYNHHNXiYrRkzC3/OM5dV34Z0=@vger.kernel.org X-Gm-Message-State: AOJu0Ywi3/NyqV13yubMCnDTvkA5N+6rYWCrbmamXoEiasjToQrDnYzu d++ykr7zHnBVeZ3lKKYdbz6DtvXu1Hq4rYWdD6sOgRb1mgCP5BEd6XA4 X-Gm-Gg: AfdE7cltRj7APypXE9cfl2sx6rzzZxU4Nl6n1RLAfqY9SCoKFlMYc2JQg8nh/+gPiPc Q5hqty32WCUgGNiaMcyQFiYqMAp8OdFFUNcDollSktdyWL1ath3MNBGcEA2WZyAikKlSoHnqWYl k4V0We8KabZ/QCIQHhiRZeGlsdHqdjgpYGXAxCHY1X7gLa876bs8IR0JpAw2F9Y8VTfQyKukisL pxoSVQLkr6/nro97fo3tymN1Zhl+iKd2dBux30LFGCNjmOiP+dOk4WRZf/v+mg8Rght9hxRAXSP a5T7CfWVV1H1Hz2F1g/+SvCtGTvwdFMGI2jM5A7fC17DWccwLkEjdeE7p0frQEL/0q2cPb+65pQ q+JxTM5QsYx6w/Efk0gHStfB40JNCs56ziUp7abdKMskHpORDjiZSaouojOCJX59+jqRr6w8+Gv U6I6bevHg+d6PzjYO3PnDr5angBmRs7MIQa9ulmkjHkhq7aobG3NSj9zpbHW11mwB+PbzdFVdGi g+VHJs= X-Received: by 2002:a05:6a21:e083:b0:3b3:486f:f2d1 with SMTP id adf61e73a8af0-3c0bceb6df6mr13539932637.3.1783689832543; Fri, 10 Jul 2026 06:23:52 -0700 (PDT) Received: from research02.. ([2601:1c1:8700:f5b:fe34:97ff:fea3:c147]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-ca5b3b251eesm4903776a12.31.2026.07.10.06.23.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 10 Jul 2026 06:23:52 -0700 (PDT) From: Hiroshi Nishida To: Song Liu , Yu Kuai Cc: Li Nan , Xiao Ni , linux-raid@vger.kernel.org, linux-kernel@vger.kernel.org, Hiroshi Nishida Subject: [PATCH 5/6] md/raid5: scale the default stripe cache size with system memory Date: Fri, 10 Jul 2026 06:23:45 -0700 Message-ID: <20260710132346.7295-6-nishidafmly@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260710132346.7295-1-nishidafmly@gmail.com> References: <20260710132346.7295-1-nishidafmly@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit setup_conf() starts every array with min_nr_stripes = NR_STRIPES (256), about 12MB of stripe cache on a 12-disk array. That fixed default was chosen for small systems and is never revisited: a server with hundreds of GB of RAM backing a wide array still creates its arrays with the same 256 stripes, and only benefits from more after an administrator writes stripe_cache_size by hand. Auto-size the initial count from memory when the new stripe_cache_size_default module parameter is 0 (the default): keep the historical NR_STRIPES up to RAID5_CACHE_DEFAULT_BASE_GB (8GB) of RAM, then grow the count using about 1/512 of the RAM above that baseline, capped at RAID5_CACHE_DEFAULT_MAX (4096). A system with 8GB or less is therefore unchanged -- same count, same footprint -- while larger ones scale up smoothly (no jump at the baseline) to a bounded maximum. A non-zero stripe_cache_size_default sets a fixed initial size for administrators who want one; existing arrays are unaffected, and a reshape still forces at least its window's worth of stripes. Signed-off-by: Hiroshi Nishida --- drivers/md/raid5.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 5f0825c5effe..8e1c2eba4241 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -83,6 +83,11 @@ module_param(max_stripe_batch, uint, 0644); MODULE_PARM_DESC(max_stripe_batch, "Number of stripes a worker thread handles per device_lock acquisition, 1-32 (default 8). Larger values amortise the lock over more stripes on busy multi-threaded arrays at some latency cost. Read when an array is created"); +static unsigned int stripe_cache_size_default; +module_param(stripe_cache_size_default, uint, 0644); +MODULE_PARM_DESC(stripe_cache_size_default, + "Initial stripe_cache_size for newly created arrays. 0 (the default) auto-sizes it from system memory: the historical 256 on small hosts, scaling up with RAM to a capped maximum on larger ones. A non-zero value sets a fixed initial size. Existing arrays are unaffected"); + static bool devices_handle_discard_safely = false; module_param(devices_handle_discard_safely, bool, 0644); MODULE_PARM_DESC(devices_handle_discard_safely, @@ -7568,6 +7573,17 @@ static unsigned long raid5_cache_count(struct shrinker *shrink, return max_stripes - min_stripes; } +/* + * Auto-sizing of the initial stripe cache (stripe_cache_size_default == 0): + * stay at the historical NR_STRIPES up to RAID5_CACHE_DEFAULT_BASE_GB of RAM, + * then grow the count using about 1/512 of the RAM above that base, capped at + * RAID5_CACHE_DEFAULT_MAX. So a system at or below the base is unchanged and + * keeps the historical footprint, while larger ones scale. + */ +#define RAID5_CACHE_DEFAULT_BASE_GB 8 /* unchanged at or below this much RAM */ +#define RAID5_CACHE_DEFAULT_RAM_SHIFT 9 /* above it: ~1/512 of the extra RAM */ +#define RAID5_CACHE_DEFAULT_MAX 4096 + static struct r5conf *setup_conf(struct mddev *mddev) { struct r5conf *conf; @@ -7801,15 +7817,37 @@ static struct r5conf *setup_conf(struct mddev *mddev) conf->prev_algo = conf->algorithm; } - conf->min_nr_stripes = NR_STRIPES; + /* + * Choose the initial stripe cache size. stripe_cache_size_default + * selects it: 0 (the default) auto-sizes from memory -- the historical + * NR_STRIPES up to RAID5_CACHE_DEFAULT_BASE_GB of RAM, then scaling up + * to at most RAID5_CACHE_DEFAULT_MAX -- and a non-zero value sets it + * directly. A reshape still forces at least enough stripes for its + * window, below. + */ + if (stripe_cache_size_default) { + conf->min_nr_stripes = clamp_t(unsigned long, + stripe_cache_size_default, 16, INT_MAX); + } else { + unsigned long per_stripe = sizeof(struct stripe_head) + + max_disks * (sizeof(struct bio) + PAGE_SIZE); + unsigned long ram = totalram_pages() << PAGE_SHIFT; + unsigned long base = (unsigned long)RAID5_CACHE_DEFAULT_BASE_GB << 30; + unsigned long extra = ram > base ? + ((ram - base) >> RAID5_CACHE_DEFAULT_RAM_SHIFT) / per_stripe : 0; + + conf->min_nr_stripes = clamp_t(unsigned long, NR_STRIPES + extra, + NR_STRIPES, RAID5_CACHE_DEFAULT_MAX); + } if (mddev->reshape_position != MaxSector) { int stripes = max_t(int, ((mddev->chunk_sectors << 9) / RAID5_STRIPE_SIZE(conf)) * 4, ((mddev->new_chunk_sectors << 9) / RAID5_STRIPE_SIZE(conf)) * 4); - conf->min_nr_stripes = max(NR_STRIPES, stripes); - if (conf->min_nr_stripes != NR_STRIPES) + if (stripes > conf->min_nr_stripes) { + conf->min_nr_stripes = stripes; pr_info("md/raid:%s: force stripe size %d for reshape\n", mdname(mddev), conf->min_nr_stripes); + } } memory = conf->min_nr_stripes * (sizeof(struct stripe_head) + max_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024; -- 2.43.0