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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D52AC3ABC9 for ; Fri, 9 May 2025 17:39:50 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 80E3D6B00C5; Fri, 9 May 2025 13:39:48 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 7BD256B00C6; Fri, 9 May 2025 13:39:48 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 6AC8C6B00C7; Fri, 9 May 2025 13:39:48 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 4DA1F6B00C5 for ; Fri, 9 May 2025 13:39:48 -0400 (EDT) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 43F04BB424 for ; Fri, 9 May 2025 17:39:49 +0000 (UTC) X-FDA: 83424082098.26.A31A9EC Received: from m16.mail.163.com (m16.mail.163.com [220.197.31.4]) by imf26.hostedemail.com (Postfix) with ESMTP id 97E6F140002 for ; Fri, 9 May 2025 17:39:46 +0000 (UTC) Authentication-Results: imf26.hostedemail.com; dkim=pass header.d=163.com header.s=s110527 header.b=LNJqiJRQ; dmarc=pass (policy=none) header.from=163.com; spf=pass (imf26.hostedemail.com: domain of 00107082@163.com designates 220.197.31.4 as permitted sender) smtp.mailfrom=00107082@163.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1746812387; a=rsa-sha256; cv=none; b=piO8qHBPnqfvyEMURcO5aErrOdZUdIQTV6lZpTKog0f/o7PKQEq5br53Oi41Z3YzIsfSxL 67acbTtC1ONnr+EjBZwk1cqA8lQXgmLV2xykylEmjYo1SyF5HUsi/KNuimb2eXQQaYTLBq a7suFMB9XnVIc6OwyI+kVD2MWnY+7jE= ARC-Authentication-Results: i=1; imf26.hostedemail.com; dkim=pass header.d=163.com header.s=s110527 header.b=LNJqiJRQ; dmarc=pass (policy=none) header.from=163.com; spf=pass (imf26.hostedemail.com: domain of 00107082@163.com designates 220.197.31.4 as permitted sender) smtp.mailfrom=00107082@163.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1746812387; 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=07i3jvklR0vx9OSADeziqkp40nZ/Zft1yJ0zQrQjUFM=; b=arCvhpwZK5/k5hi/WO7YfAclcAUwjGygZOBadywVljJBx0hYpqaF5/ISS2//zEA71eGW3F zQmdkS3dWHg/H5Tm7fydNpHueO1yB233VIhZNUt7yMoZBnli5rj0VEA0KWQKEfo/5V/io7 8SGJZpm4QSj/cGVGIyNvf3/y8WNcqUc= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=07 i3jvklR0vx9OSADeziqkp40nZ/Zft1yJ0zQrQjUFM=; b=LNJqiJRQZH3S2sw4JD 4thGkWRXrwU8woLFBVOBkhRxZ+RJxkXyzo5f5NYL6iX9JKNBSb8rJq792inZyFun GQUOzpqzhfY/KWq6UQ7lNtDsqWlekjSCcgEodSkGZK7OLHxaPHGKgq6dHzzlaH6E XlCRPuQgL/H050gREmN3lc6Tw= Received: from localhost.localdomain (unknown []) by gzsmtp5 (Coremail) with SMTP id QCgvCgDHg9HSPR5oUrKHAA--.12846S4; Sat, 10 May 2025 01:39:37 +0800 (CST) From: David Wang <00107082@163.com> To: surenb@google.com, kent.overstreet@linux.dev, akpm@linux-foundation.org Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, David Wang <00107082@163.com> Subject: [PATCH v2 2/2] alloc_tag: keep codetag iterator active between read() calls Date: Sat, 10 May 2025 01:39:29 +0800 Message-Id: <20250509173929.42508-1-00107082@163.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250507175500.204569-1-00107082@163.com> References: <20250507175500.204569-1-00107082@163.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:QCgvCgDHg9HSPR5oUrKHAA--.12846S4 X-Coremail-Antispam: 1Uf129KBjvJXoWxGFWUWw1UXF18ZrWDXF47Jwb_yoWruF17pa 13ua4YkF4rAr1UCF4rJr4IqFW3t3W8ta18XF42qrWFvFn0vrs8uF98Jryj9Fy3AFy8Ka1a va90k34UJr9IvaDanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x0p__-BDUUUUU= X-Originating-IP: [111.35.191.17] X-CM-SenderInfo: qqqrilqqysqiywtou0bp/xtbB0gRIqmgePWgV5gAAsk X-Rspamd-Queue-Id: 97E6F140002 X-Rspam-User: X-Rspamd-Server: rspam07 X-Stat-Signature: mi6bm4e738ao61pdc4upfixs1ijz13zw X-HE-Tag: 1746812386-264503 X-HE-Meta: U2FsdGVkX1/xNM2WNlpDk+kAKtJRqS4j0Ti16FnRvAJN54BdIpC+BKJzgIYrL5DXm9DVTG1b7QQNTVyh4AAPf7h1zKahJm1CyG5MwBYz2/3yePujUjmynjhy3adfV9ePgRzvNguRvXV2z68N3JqZEfKGp+r6sFNPbpEA3HJsFGme8iYhDjxLhPmPbTbxgT8QysASVVTCsmdeSbyPBqpi3l+ERSvn0gn/Fg9xbN/DJRHVD+Hb2eRl/f1zEAvGLdJxn5gCBxku+PGIQI5lNcrKlbG+8YrQeBwp7PnDjHPGbg894TONT5k719Rc2gznJMHJ8OEJAXkFBWrHmuyx2b24uj0NeXHfPioMpgQUELTn0Dpf8WuIU8lDmRwZJj+XaGP93jGq5P9CkskuBM0XBszr0r69NqCKQhb/z3x6Q3QdBhiYB3Y2YmjYmZD5LVHAIj3Jj7lPvEvb0bkUJuxhkmnnlTRgLrtQK8xy8ufIczfs57mUkHPQXILBNL3ZiM+4WZVrZPB5Y2LOrTLkLS/zsuoYolSHLCysK/K1vJtZVszjg0hNYtIWhwTABune4lKrF/iwkAVdL+Mjs7OuSLUmi003FbXypQH1RfhJFgHGKu+n9TqRc4Hcvv1O/d4+UCiaNNTup38i0UILNPeDPDc8UTq9BE7LC1fJ95+EhSJQpIQrZuTLved0ahG1P88HjGvtMkIw4Cil0nFEr/c5gMiH4Vf3xI4mhstqCRKypfnUYyCWqhICdTcApDxZ3b/sJrUJOO9rvw7404dsUZRbycDsyuJWl/yUX5xm8Ea1AMq+8658QaOLh7+1S1Ex9Zs0aLduLO4Wqa2keGILuKml5SPS+Y03H/gVDoAl3eNnJo2KN2cshIE6a4VzI+8atX0OstGY1IQhP3EbFKJ3Btc/dO1IbhzM9/L4yq7u3LWf6A38eLIOin3qMoZVpyQowrH7nZ/vkvhDux9H1ItT2h6pWXMw/P2 uV6SdJ8L 5UCuuJP+ghq2BM56krAVGyHODV/NUo3XNXxNy907TN1q0UxsGHE6QHzm4vFPVQkHFnSTRgsD0/RrixsBSzQiU7u/B6ushC9IR0Uq7lsp51KKUI1h30pMQ8IkLYOGC2Co+mv5sCYIsBnje58PDI5cHNvUpfmXofMA6TQr/KrZPJKy5uCJmLdizDDric8Ar3V/hakzpA3E17+SVBJH8udqx7I73pcoM1oXXW8IF5lWN4Gy2IobnmfRokq1k73EA4DDeAeY/kRUZls7Sc2i1PuIFC6kZPAHDMhn4qjhJE0H9z9/PGIJeoUg0rBcQq0SHPdfHc0cbgtKLmuZoY+svuPFZHgK+NbPpz8WxYUIjSF8LHHFNXonQN7ohuRvm8lpPkG1zQB+ubKuILig+6c++M/UzlVnCsoHdIq7ur1Ze9yFQLM967bw= 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: List-Subscribe: List-Unsubscribe: When reading /proc/allocinfo, for each read syscall, seq_file would invoke start/stop callbacks. In start callback, a memory is alloced to store iterator and the iterator would start from beginning to walk linearly to current read position. seq_file read() takes at most 4096 bytes, even if read with a larger user space buffer, meaning read out all of /proc/allocinfo, tens of read syscalls are needed. For example, a 306036 bytes allocinfo files need 76 reads: $ sudo cat /proc/allocinfo | wc 3964 16678 306036 $ sudo strace -T -e read cat /proc/allocinfo ... read(3, " 4096 1 arch/x86/k"..., 131072) = 4063 <0.000062> ... read(3, " 0 0 sound/core"..., 131072) = 4021 <0.000150> ... For those n=3964 lines, each read takes about m=3964/76=52 lines, since iterator restart from beginning for each read(), it would move forward m steps on 1st read 2*m steps on 2nd read 3*m steps on 3rd read ... n steps on last read As read() along, those linear seek steps make read() calls slower and slower. Adding those up, codetag iterator moves about O(n*n/m) steps, making data structure traversal take significant part of the whole reading. Profiling when stress reading /proc/allocinfo confirms it: vfs_read(99.959% 1677299/1677995) proc_reg_read_iter(99.856% 1674881/1677299) seq_read_iter(99.959% 1674191/1674881) allocinfo_start(75.664% 1266755/1674191) codetag_next_ct(79.217% 1003487/1266755) <--- srso_return_thunk(1.264% 16011/1266755) __kmalloc_cache_noprof(0.102% 1296/1266755) ... allocinfo_show(21.287% 356378/1674191) allocinfo_next(1.530% 25621/1674191) codetag_next_ct() takes major part. A private data alloced at open() time can be used to carry iterator alive across read() calls, and avoid the memory allocation and iterator reset for each read(). This way, only O(1) memory allocation and O(n) steps iterating, and `time` shows performance improvement from ~7ms to ~4ms. Profiling with the change: vfs_read(99.865% 1581073/1583214) proc_reg_read_iter(99.485% 1572934/1581073) seq_read_iter(99.846% 1570519/1572934) allocinfo_show(87.428% 1373074/1570519) seq_buf_printf(83.695% 1149196/1373074) seq_buf_putc(1.917% 26321/1373074) _find_next_bit(1.531% 21023/1373074) ... codetag_to_text(0.490% 6727/1373074) ... allocinfo_next(6.275% 98543/1570519) ... allocinfo_start(0.369% 5790/1570519) ... Now seq_buf_printf() takes major part. Signed-off-by: David Wang <00107082@163.com> --- lib/alloc_tag.c | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/lib/alloc_tag.c b/lib/alloc_tag.c index 25ecc1334b67..fdd5887769a6 100644 --- a/lib/alloc_tag.c +++ b/lib/alloc_tag.c @@ -45,21 +45,16 @@ struct allocinfo_private { static void *allocinfo_start(struct seq_file *m, loff_t *pos) { struct allocinfo_private *priv; - struct codetag *ct; loff_t node = *pos; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); - m->private = priv; - if (!priv) - return NULL; - - priv->print_header = (node == 0); + priv = (struct allocinfo_private *)m->private; codetag_lock_module_list(alloc_tag_cttype, true); - priv->iter = codetag_get_ct_iter(alloc_tag_cttype); - while ((ct = codetag_next_ct(&priv->iter)) != NULL && node) - node--; - - return ct ? priv : NULL; + if (node == 0) { + priv->print_header = true; + priv->iter = codetag_get_ct_iter(alloc_tag_cttype); + codetag_next_ct(&priv->iter); + } + return priv->iter.ct ? priv : NULL; } static void *allocinfo_next(struct seq_file *m, void *arg, loff_t *pos) @@ -76,12 +71,7 @@ static void *allocinfo_next(struct seq_file *m, void *arg, loff_t *pos) static void allocinfo_stop(struct seq_file *m, void *arg) { - struct allocinfo_private *priv = (struct allocinfo_private *)m->private; - - if (priv) { - codetag_lock_module_list(alloc_tag_cttype, false); - kfree(priv); - } + codetag_lock_module_list(alloc_tag_cttype, false); } static void print_allocinfo_header(struct seq_buf *buf) @@ -249,7 +239,8 @@ static void __init procfs_init(void) if (!mem_profiling_support) return; - if (!proc_create_seq(ALLOCINFO_FILE_NAME, 0400, NULL, &allocinfo_seq_op)) { + if (!proc_create_seq_private(ALLOCINFO_FILE_NAME, 0400, NULL, &allocinfo_seq_op, + sizeof(struct allocinfo_private), NULL)) { pr_err("Failed to create %s file\n", ALLOCINFO_FILE_NAME); shutdown_mem_profiling(false); } -- 2.39.2