From patchwork Sat Nov 16 17:59:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pasha Tatashin X-Patchwork-Id: 13877670 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 1A20AD68BE7 for ; Sat, 16 Nov 2024 17:59:32 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 161DD9C001B; Sat, 16 Nov 2024 12:59:31 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 10D019C0018; Sat, 16 Nov 2024 12:59:31 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id E539A9C001B; Sat, 16 Nov 2024 12:59:30 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id C54449C0018 for ; Sat, 16 Nov 2024 12:59:30 -0500 (EST) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 6992A121CFF for ; Sat, 16 Nov 2024 17:59:30 +0000 (UTC) X-FDA: 82792718988.21.09DE5E2 Received: from mail-qk1-f171.google.com (mail-qk1-f171.google.com [209.85.222.171]) by imf17.hostedemail.com (Postfix) with ESMTP id A856140002 for ; Sat, 16 Nov 2024 17:58:52 +0000 (UTC) Authentication-Results: imf17.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=RtYCXKvy; dmarc=pass (policy=none) header.from=soleen.com; spf=pass (imf17.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.171 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1731779903; a=rsa-sha256; cv=none; b=uvA3pUExmdY7k7Cm5GQetsLGUtbMn15s3/sfaBJp78p6oSukR9z4xmYDsebQPVNwQBRzJJ 8j0yzoTaMyQP2nykR5HpGCADMcQnLHap++FM8FV+qz9z8bK59oB8DbP/1G0s+sxbAwKTyV LMHZFUT1nCsiFWyAvFk9CURUO7kOg2E= ARC-Authentication-Results: i=1; imf17.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=RtYCXKvy; dmarc=pass (policy=none) header.from=soleen.com; spf=pass (imf17.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.171 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1731779903; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=q+AdtzJV8StRb0yy8pEXghurQ0eEZGVtS6O69RbdSyA=; b=H/PTs4C61ZWhsiS/FNHNxUdyo5xsHJp6ajlXAKw0DyX3G20V4HnE++h/StkbXXLi8+iGHV oTZ7dkw9+D7nRGEopFOKhMFjvZ/hq2ZG2zGg0lwbxEa/pptjMethICaQQ21QBCfnjE/P7B uKvsPjGs6XmrLH5QFXNEO6nFy7s5Apg= Received: by mail-qk1-f171.google.com with SMTP id af79cd13be357-7b13fe8f4d0so120526585a.0 for ; Sat, 16 Nov 2024 09:59:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen-com.20230601.gappssmtp.com; s=20230601; t=1731779968; x=1732384768; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=q+AdtzJV8StRb0yy8pEXghurQ0eEZGVtS6O69RbdSyA=; b=RtYCXKvy6hqvGdL2oOeYhBCfRc6jIHhWtAFn7VIEz251vHxMRfiG9YG5O5K/CTYavi sy3syvQi48E6HO+KoaM0rFRalhgZWXvxaMeb6UeDkDCPqX+pzswVJUuhKqnDhkoyh7r2 UtCSSt7Le5+MnqeTupCmRFir+VAj2wRPipBzH+BjWUdRx0aJ4NQLkbfkDkZC9BYWOt4i 4ensBR/bDhpCDN5O2J5P1spV4tm6eIygUCnItevcZTEVuik7fWSbEJc/CQ84j8bHSksN GjvhaFAqSpXdpyEbMeIkimvCGm52o/KaQtVH8ymafWulcjrjiyU9pgsY79lU9gR0+/dw NqMg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731779968; x=1732384768; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=q+AdtzJV8StRb0yy8pEXghurQ0eEZGVtS6O69RbdSyA=; b=JMwGb7sHQSfJjIVVA/Cf3Wqso25bJ/ILj6selzNjMVMgsvdr/ZpqEXOA8Br5vg9f60 pTftDan6CegzNxNyOZGCM7WhPDXiLJROZXK1nLuhfEPqPgXt0U4OW5YMTPBGjtvZpkRH SzykMJ2AcKHsohVTmt5ibW8MBTMVYdsafWN+u+HlPglS0U4W0X0a78+OpmXMZu9+/be8 bFUH6cRjnr861PNjXjwhgOBLWMW6/pGOB6j+SDREBGcAEdO6+39DuuVEkijcR7nCjQGv NpfFsFqzoKN+FJTX+TIpv/T0BW9hgjYI6eR7T4+XeGXVckU5CEepO8TtBaC53DgJlR4G vKIQ== X-Forwarded-Encrypted: i=1; AJvYcCUcszBQSKR2svoZjvdPOvbrXpXPpmCxrHSASvPo+CLSu6cUiv7V68ueBOPJlbkTg9HVF3ipGUC9rg==@kvack.org X-Gm-Message-State: AOJu0Yw+DheFjxvgtlD2HRvB8xXR5JyusMBMyF9bELCZLB7Zx/nT/gI1 c/zEgrL+6iKMiV6bq8AHqV8F8xNoTNcEHwWP+X+EybN4kllad9OIqkz1UhUrzP8= X-Google-Smtp-Source: AGHT+IHID5UaFDu345/iXR65Tjm/g4UasFabizEe9rsgDtnAMppuhhS2EDxuUbmo+8naXZvVw6Ss7Q== X-Received: by 2002:a05:620a:468d:b0:7b1:5504:2772 with SMTP id af79cd13be357-7b362378df6mr1035738885a.55.1731779967540; Sat, 16 Nov 2024 09:59:27 -0800 (PST) Received: from soleen.c.googlers.com.com (51.57.86.34.bc.googleusercontent.com. [34.86.57.51]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7b35ca309d6sm280530085a.94.2024.11.16.09.59.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 Nov 2024 09:59:26 -0800 (PST) From: Pasha Tatashin To: pasha.tatashin@soleen.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, cgroups@vger.kernel.org, linux-kselftest@vger.kernel.org, akpm@linux-foundation.org, corbet@lwn.net, derek.kiernan@amd.com, dragan.cvetic@amd.com, arnd@arndb.de, gregkh@linuxfoundation.org, viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz, tj@kernel.org, hannes@cmpxchg.org, mhocko@kernel.org, roman.gushchin@linux.dev, shakeel.butt@linux.dev, muchun.song@linux.dev, Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, vbabka@suse.cz, jannh@google.com, shuah@kernel.org, vegard.nossum@oracle.com, vattunuru@marvell.com, schalla@marvell.com, david@redhat.com, willy@infradead.org, osalvador@suse.de, usama.anjum@collabora.com, andrii@kernel.org, ryan.roberts@arm.com, peterx@redhat.com, oleg@redhat.com, tandersen@netflix.com, rientjes@google.com, gthelen@google.com Subject: [RFCv1 1/6] mm: Make get_vma_name() function public Date: Sat, 16 Nov 2024 17:59:17 +0000 Message-ID: <20241116175922.3265872-2-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.47.0.338.g60cca15819-goog In-Reply-To: <20241116175922.3265872-1-pasha.tatashin@soleen.com> References: <20241116175922.3265872-1-pasha.tatashin@soleen.com> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Queue-Id: A856140002 X-Rspamd-Server: rspam01 X-Stat-Signature: 749866uy11mahcugstirakxttuirz733 X-HE-Tag: 1731779932-331541 X-HE-Meta: U2FsdGVkX19sDQSTkYLIt0Z7bqOe208knlyuPxeVipNvvglNyT9qDXEXtknnbM+qtXkIDtTOkv/8yomvtkFXxLJvHCszjtvcjIEfIjl6D8dgXPoVSFROVF8uEz+kpXazlLRlDqpPLttti9hfp4yOZJdDR91XMBTHE/lJxQtKlddsVecDGSstTtBxfme45SJnXEH4vA+HLqc8tDaXgsALAr0fR1w3nyrrCmavhHIW6owt9OvcD0qpQtyIF/6/J21YC0RqU264aGQdEAsaftamTRaB5HraKRZR6MHM8oni/nAJKz1ytkPhJw5JfgFydMthMorjamjsK3FYPnOLtijoRJCsT64XlyibuTanCyLBr4kYsFxmZRNGvT4WvlCs1Wg+h4wIeww+HW2BULFYDlSnkGxk+iziZiZF6h4aYgrIlq1+GIo2kg+ccmyob8icsLD4y5y7pv9OK9vDulnddvDDENFlE7Z70kq36yoENxn9/5bX2yxxhCjDQujKuBtJhFkk8S88nNx/lTokVtaenCbSdyQcbUqIfYJtH7nOt/aQRvUBARwys9SmIsEldHiS9H5b43fSRMyjapt/UfipbvLLyuv6NA1yiH/4TRP5+bbc+YNtp/cvnhlnroslvRMG3EvZEpXDC7dBHLsFVMVTHaVrbiPlQ+IuZlECjiqijm60mHKvlNuUuyNxJyBbuSI0jjtCi4RE8zjKm9LncFCVkXlBFfViJaah3DREUglfzuzIT0HSKfI4CWNRuDvsj3Vy1UlOuuZX6a/3GieGIm4Qy708zslTHorzek22JZrkwUOvcmOp94QIJszeQ4tzHxsTKNV0WLJfguBmg3EOGUz4eF6IJ+zYpnF4+SgZR2KxEdzVY66wvfBjsasg8AX7qdGWYg7l1a6CKNVr8fR2G7vB6MtG/oNb794Q49vRMhEjpJsQ905gp//N9FYaIwesk8tDLO/pg92IYuoArFLWUAnDQ2f BlJKU/PK e702eT9NSr2nSQd+nd+cuC/RoSEHvcxi9ZoyINaX1iBwPA3TGZ6otuhF4hiy3ceTexnyYgaGL39LlZESEyGxMc+UVwuUNofSC0aYJ8HOSZXtiVJjrOEBgEqNO7vUelx0ax6n4aAqtzGRhj1DbjVEoSjUgtvHn0gxjw6Tp3nAjDu0c2eAScwCOTdEDLD+xLgbqLkVCyQertKnjYRoN/V+NzgPb3lA9V6xDsmP7OxjU1qxoNvTEBP3RIvSFtlPNjpSU02jMIoB56cP614Sy956Mm9+K/oTjApGYI18yowkaCvtk/3TxJ1c1ixdsLP5KasZEwru6NATOmKnEFH8/XI/m/A2GMT2FO+qNXH1Iq/fF1hXWZOyxsjW54hwTlDr2ZqP+bD8K4d6kz9lQyWjnpSYafXxQEQcDjCEuYXq2LWe1ldB8US/NjvtQYsQZ3w== 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: Page Detective will be using get_vma_name() that is currently used by fs/proc to show names of VMAs in /proc//smaps for example. Move this function to mm/vma.c, and make it accessible by modules. Signed-off-by: Pasha Tatashin --- fs/proc/task_mmu.c | 61 ---------------------------------------------- include/linux/fs.h | 3 +++ mm/vma.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 61 deletions(-) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index e52bd96137a6..b28c42b7a591 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -240,67 +240,6 @@ static int do_maps_open(struct inode *inode, struct file *file, sizeof(struct proc_maps_private)); } -static void get_vma_name(struct vm_area_struct *vma, - const struct path **path, - const char **name, - const char **name_fmt) -{ - struct anon_vma_name *anon_name = vma->vm_mm ? anon_vma_name(vma) : NULL; - - *name = NULL; - *path = NULL; - *name_fmt = NULL; - - /* - * Print the dentry name for named mappings, and a - * special [heap] marker for the heap: - */ - if (vma->vm_file) { - /* - * If user named this anon shared memory via - * prctl(PR_SET_VMA ..., use the provided name. - */ - if (anon_name) { - *name_fmt = "[anon_shmem:%s]"; - *name = anon_name->name; - } else { - *path = file_user_path(vma->vm_file); - } - return; - } - - if (vma->vm_ops && vma->vm_ops->name) { - *name = vma->vm_ops->name(vma); - if (*name) - return; - } - - *name = arch_vma_name(vma); - if (*name) - return; - - if (!vma->vm_mm) { - *name = "[vdso]"; - return; - } - - if (vma_is_initial_heap(vma)) { - *name = "[heap]"; - return; - } - - if (vma_is_initial_stack(vma)) { - *name = "[stack]"; - return; - } - - if (anon_name) { - *name_fmt = "[anon:%s]"; - *name = anon_name->name; - return; - } -} - static void show_vma_header_prefix(struct seq_file *m, unsigned long start, unsigned long end, vm_flags_t flags, unsigned long long pgoff, diff --git a/include/linux/fs.h b/include/linux/fs.h index 3559446279c1..a25b72397af5 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3474,6 +3474,9 @@ void setattr_copy(struct mnt_idmap *, struct inode *inode, extern int file_update_time(struct file *file); +void get_vma_name(struct vm_area_struct *vma, const struct path **path, + const char **name, const char **name_fmt); + static inline bool vma_is_dax(const struct vm_area_struct *vma) { return vma->vm_file && IS_DAX(vma->vm_file->f_mapping->host); diff --git a/mm/vma.c b/mm/vma.c index 7621384d64cf..1bd589fbc3c7 100644 --- a/mm/vma.c +++ b/mm/vma.c @@ -2069,3 +2069,63 @@ void mm_drop_all_locks(struct mm_struct *mm) mutex_unlock(&mm_all_locks_mutex); } + +void get_vma_name(struct vm_area_struct *vma, const struct path **path, + const char **name, const char **name_fmt) +{ + struct anon_vma_name *anon_name = vma->vm_mm ? anon_vma_name(vma) : NULL; + + *name = NULL; + *path = NULL; + *name_fmt = NULL; + + /* + * Print the dentry name for named mappings, and a + * special [heap] marker for the heap: + */ + if (vma->vm_file) { + /* + * If user named this anon shared memory via + * prctl(PR_SET_VMA ..., use the provided name. + */ + if (anon_name) { + *name_fmt = "[anon_shmem:%s]"; + *name = anon_name->name; + } else { + *path = file_user_path(vma->vm_file); + } + return; + } + + if (vma->vm_ops && vma->vm_ops->name) { + *name = vma->vm_ops->name(vma); + if (*name) + return; + } + + *name = arch_vma_name(vma); + if (*name) + return; + + if (!vma->vm_mm) { + *name = "[vdso]"; + return; + } + + if (vma_is_initial_heap(vma)) { + *name = "[heap]"; + return; + } + + if (vma_is_initial_stack(vma)) { + *name = "[stack]"; + return; + } + + if (anon_name) { + *name_fmt = "[anon:%s]"; + *name = anon_name->name; + return; + } +} +EXPORT_SYMBOL_GPL(get_vma_name); From patchwork Sat Nov 16 17:59:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pasha Tatashin X-Patchwork-Id: 13877671 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 28C49D68BF5 for ; Sat, 16 Nov 2024 17:59:35 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 555739C001C; Sat, 16 Nov 2024 12:59:32 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 4B5789C0018; Sat, 16 Nov 2024 12:59:32 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 30AE89C001C; Sat, 16 Nov 2024 12:59:32 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 0A6CD9C0018 for ; Sat, 16 Nov 2024 12:59:32 -0500 (EST) Received: from smtpin03.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 76690C1D44 for ; Sat, 16 Nov 2024 17:59:31 +0000 (UTC) X-FDA: 82792718148.03.E9A1B57 Received: from mail-qt1-f180.google.com (mail-qt1-f180.google.com [209.85.160.180]) by imf07.hostedemail.com (Postfix) with ESMTP id A49FF40004 for ; Sat, 16 Nov 2024 17:58:23 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=Unqas3E1; spf=pass (imf07.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.160.180 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1731779771; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=8NgfUO+bQWj6bU8BgCVOh0fIa47vMCexDt60Dq7gXNk=; b=BnBuTsfag3+2zJkx2gpMPvII1yqxX0mndPE5k0hNj5YewTS3OpBl1tFRLofPWcKOLk0Q81 pUG7l+IJzzINjDCn1duatXkOhq38rGMd62x6j5xgB/4NGZtaRhqv4kzvohLFn/8+e279eo OKrD8OxjGaLsp0nSifku/fcphhH8Nq0= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=Unqas3E1; spf=pass (imf07.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.160.180 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1731779771; a=rsa-sha256; cv=none; b=3VM43mEHPNz6a+nB5V/cAmJL5Vj7wcYGehz/QjvK7PDlUjnJ2VDy7+1E2UO/PT7OFfycMZ qpJJNZ6QQa2s++BnBB9172sRwegKz4cVBj/6XZlUnOIOW7QhC+OxX9P3bDGZstXfq5h1dW NcmT0u0QoET+469pJJcLQ5+mVkWy2wI= Received: by mail-qt1-f180.google.com with SMTP id d75a77b69052e-4609d8874b1so14182181cf.3 for ; Sat, 16 Nov 2024 09:59:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen-com.20230601.gappssmtp.com; s=20230601; t=1731779969; x=1732384769; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=8NgfUO+bQWj6bU8BgCVOh0fIa47vMCexDt60Dq7gXNk=; b=Unqas3E1J/vRBIyjKXAh1zDzbgIkWgZ66j/lGs5W5rxo82qi3v4LJZfrlPi6gOf9wC VewLbehuKEj2b4dS4RQ3U9J8eF8USFEcINrpZq99GNeXqNjwYlWkqDh2ttGSSABDxey+ VLciG4y/6dZtjjq8VCFgB9Y/lvrZaCIQtCbBneCaO91AMG0G/i06uXRl2Z2qynyDnn8Z xMLL6WN7B3yr01PqIBREvmw3IWmk+CHxGIQHQsaXFwwGaJBok/weCsmYq1+TnbEp4TDa 3H0IPAEmxhP8+TuGRLeSnu1RVH+ohJ1fqhQFoDn4RwSBaend+K0fBdebKA5iu9aAjQxh SPMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731779969; x=1732384769; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8NgfUO+bQWj6bU8BgCVOh0fIa47vMCexDt60Dq7gXNk=; b=N08+GU77pvOOsMLdvw5w/NYhfeYAhULDV+fwSkiArCfHzR1CrCUujBIBXGbQMy0SkZ dI9nUBCYkL3+MeaXQDAg/Xp0bButHczDx8JmICzmLajOM1YAXC0j40nU9ZEftg5UPKwB SwDhrkKpJYyEq+hYMkW6RyUcodPGy7OeZWrde1AYIpGPD40OTbWYKXoCrcW3aUGLcLCz loIFHkwc73TO/lXE2Ee2ZINnZamzUGQm3KNhKx5n/AwaHREjyP87s4pY6h0tv13Zw94J eHAH+m+XSvfGlagqI6v0gCLAQ+D17OtWTMrVT4JRTZXBnIj3ASThTUjlSDBPQWcNczy0 gXoA== X-Forwarded-Encrypted: i=1; AJvYcCVuC6i9LtUgzF+tS4OdQsWMkVvuRT0XMcovjfjjFMonKvRL9Q3huU3dUNg8xsVsZXSajEavAdqjHQ==@kvack.org X-Gm-Message-State: AOJu0YwVcfLlEGBKKFFuUk+UR0ddAFIyhPXGbkMnaDEQ9Ukk7WMwvG+l juCKrQPrvNkrpxWWZllPiALxNSEDV70U8CiADLivt0kICEPnGXtbdjDgENDtAn0= X-Google-Smtp-Source: AGHT+IEMOLNEsp5sqgIkt52tiSL0kf4hziLkF3l6oWPXAHVLzfNvt2ajo6yR1l9MnxJe6dgs1UWO0g== X-Received: by 2002:a05:6214:5d0a:b0:6cb:e6b2:4a84 with SMTP id 6a1803df08f44-6d3fb7cc924mr77641716d6.14.1731779968837; Sat, 16 Nov 2024 09:59:28 -0800 (PST) Received: from soleen.c.googlers.com.com (51.57.86.34.bc.googleusercontent.com. [34.86.57.51]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7b35ca309d6sm280530085a.94.2024.11.16.09.59.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 Nov 2024 09:59:28 -0800 (PST) From: Pasha Tatashin To: pasha.tatashin@soleen.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, cgroups@vger.kernel.org, linux-kselftest@vger.kernel.org, akpm@linux-foundation.org, corbet@lwn.net, derek.kiernan@amd.com, dragan.cvetic@amd.com, arnd@arndb.de, gregkh@linuxfoundation.org, viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz, tj@kernel.org, hannes@cmpxchg.org, mhocko@kernel.org, roman.gushchin@linux.dev, shakeel.butt@linux.dev, muchun.song@linux.dev, Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, vbabka@suse.cz, jannh@google.com, shuah@kernel.org, vegard.nossum@oracle.com, vattunuru@marvell.com, schalla@marvell.com, david@redhat.com, willy@infradead.org, osalvador@suse.de, usama.anjum@collabora.com, andrii@kernel.org, ryan.roberts@arm.com, peterx@redhat.com, oleg@redhat.com, tandersen@netflix.com, rientjes@google.com, gthelen@google.com Subject: [RFCv1 2/6] pagewalk: Add a page table walker for init_mm page table Date: Sat, 16 Nov 2024 17:59:18 +0000 Message-ID: <20241116175922.3265872-3-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.47.0.338.g60cca15819-goog In-Reply-To: <20241116175922.3265872-1-pasha.tatashin@soleen.com> References: <20241116175922.3265872-1-pasha.tatashin@soleen.com> MIME-Version: 1.0 X-Rspamd-Server: rspam07 X-Rspamd-Queue-Id: A49FF40004 X-Stat-Signature: xtu5ptiti3qe6r567jx4jw3pffwkjwsb X-Rspam-User: X-HE-Tag: 1731779903-710199 X-HE-Meta: U2FsdGVkX1+f3qtrDllT7xnYxRNcxjPDZLGsvi/Pi2XVFAw1Y7sZoRxakwu6dK0kncOUZqP5WUtaWRDwiBAHQBaUMZ5TESTdXptK+ai9gv7NKOiLPO4rguwf6fLKOI2ySbg8tbo9vDZicqfR8A5DJtA84VpomjJMEdgM4qvwrxDflfhAqNOQ4IX14Aa5I/A6wVD4Y1ej+Mq9tBPzOdlgRWtyDPs1H+O3S4lvNOz3K1P1UrCIbw8MNVW6lvDSDXfsY9ztVLfuS6K1VJTA4LKQOzPAZ/GQewVERq5/z/j82BQGwf0gocWOOHJO2qGUdgSxh9R9mgKyvVAuvWm9liriZjxePnKhNo/Rs8bNlItJhcJ8mUDgp9NOdYbPwGafHYRsZ8aQiL5HWoWnHOSfcEBOhgP35ZAMVtF6T5CKS9cAyIUwa9GLz0M5Jj0VFclLUqY9pd8oOchcjhWBsGeDh8vCanfmNuK0ZX77MdA8hB6xhJU+jn5Hfl6QZDEgbGQZcu+Uf6V23gJNh4kgx1qjaXScZGqsoct0tJeyrCUoDMq09mjtZO9yTa/YsJBVM8ZIN0idJB8+c6dLItmXX6POsWT4ijDCxyBhTGkP+/RBL4TJzMgd1Zg0NK79tl+fRv5rpSDNGl/U8n4SdaxVQZxm+Wf2YyxSF1A3GSBGMhj0M0++VPJfSpk2Ud7w7ktA8rM7MGPzXtSGmNKPxs3vbQzu1S6nHTBHfNIzoURgtQXq9ntwSSpSoQ9N7Qu8hjmJI+o1QQy+2Gz9YDnKLDq8mwYL1l+T0orbtFE12aMRsE8cyuo2UMCS/8MaIwGUJPgiRApvkQi1V3KdPco9i2iDktKgkUSAACLseDcpl2uSLBaxSpIXt5ZDMTVs59Gm9/VSuNUjXMuSzmLz+kJtxYbYMBQK4rFtjWywtIdlpCbeIySGcxkxSCoduVHKVH9tbnjww4B14XQCtzdZRubPmbJsaN5OTJz wt7datOJ /G8X9gmO2PzqwOxgnUNFpqTe7Aa/Q91bvdnNhSF5tB20MaaCFMxaLi34rJdr29KoFT23JHWEIElwWLQ7HOvyCGtpUFXnHb/XAT+wFoLwvKvwEgubyThoM7LkY904/CqlrmbHW1RxExq55L/iG2QrBeVL8uI1JNffMo1Mz7ATMwBs/dTYthzVNCfXiwHA1mf3IqV/3WOcb8PX/23HH+fhiz0KzfchpouqXudXD6scCrFu3xTEcL8s9IITyPWeUsWqXUxyWmv4WPTJe/QQKgNtPJoArcQbb5tMP9TY1Ng42WkWNVbBmvNNps1mv94B2+iTmUTo49HFg4d66kqsodmlhCXSW3BA8Sf7Yttr9N2LDMySMp6ZD8P5SDNeTxE8HWDuszSukpsZQemARO2jbJBLUwHwStVBzIJYzQLvg8ADjhhUjU7yMXcQWIUm1PQ== 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: Page Detective will use it to walk the kernel page table. Make this function accessible from modules, and also while here make walk_page_range() accessible from modules, so Page Detective could use it to walk user page tables. Signed-off-by: Pasha Tatashin --- include/linux/pagewalk.h | 2 ++ mm/pagewalk.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/linux/pagewalk.h b/include/linux/pagewalk.h index f5eb5a32aeed..ff25374470f0 100644 --- a/include/linux/pagewalk.h +++ b/include/linux/pagewalk.h @@ -124,6 +124,8 @@ int walk_page_range_novma(struct mm_struct *mm, unsigned long start, int walk_page_range_vma(struct vm_area_struct *vma, unsigned long start, unsigned long end, const struct mm_walk_ops *ops, void *private); +int walk_page_range_kernel(unsigned long start, unsigned long end, + const struct mm_walk_ops *ops, void *private); int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops, void *private); int walk_page_mapping(struct address_space *mapping, pgoff_t first_index, diff --git a/mm/pagewalk.c b/mm/pagewalk.c index 5f9f01532e67..050790aeb15f 100644 --- a/mm/pagewalk.c +++ b/mm/pagewalk.c @@ -478,6 +478,7 @@ int walk_page_range(struct mm_struct *mm, unsigned long start, } while (start = next, start < end); return err; } +EXPORT_SYMBOL_GPL(walk_page_range); /** * walk_page_range_novma - walk a range of pagetables not backed by a vma @@ -541,6 +542,37 @@ int walk_page_range_novma(struct mm_struct *mm, unsigned long start, return walk_pgd_range(start, end, &walk); } +/** + * walk_page_range_kernel - walk a range of pagetables of kernel/init_mm + * @start: start address of the virtual address range + * @end: end address of the virtual address range + * @ops: operation to call during the walk + * @private: private data for callbacks' usage + * + * Similar to walk_page_range_novma() but specifically walks init_mm.pgd table. + * + * Note: This function takes two looks: get_online_mems(), and mmap_read, this + * is to prevent kernel page tables from being freed while walking. + */ +int walk_page_range_kernel(unsigned long start, unsigned long end, + const struct mm_walk_ops *ops, void *private) +{ + get_online_mems(); + if (mmap_read_lock_killable(&init_mm)) { + put_online_mems(); + return -EAGAIN; + } + + walk_page_range_novma(&init_mm, start, end, ops, + init_mm.pgd, private); + + mmap_read_unlock(&init_mm); + put_online_mems(); + + return 0; +} +EXPORT_SYMBOL_GPL(walk_page_range_kernel); + int walk_page_range_vma(struct vm_area_struct *vma, unsigned long start, unsigned long end, const struct mm_walk_ops *ops, void *private) From patchwork Sat Nov 16 17:59:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pasha Tatashin X-Patchwork-Id: 13877672 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 B1D13D68BE7 for ; Sat, 16 Nov 2024 17:59:37 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 469B59C001D; Sat, 16 Nov 2024 12:59:33 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 4023E9C0018; Sat, 16 Nov 2024 12:59:33 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 2474A9C001D; Sat, 16 Nov 2024 12:59:33 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id F32699C0018 for ; Sat, 16 Nov 2024 12:59:32 -0500 (EST) Received: from smtpin01.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 9FE1081C82 for ; Sat, 16 Nov 2024 17:59:32 +0000 (UTC) X-FDA: 82792718190.01.388ECEA Received: from mail-qk1-f182.google.com (mail-qk1-f182.google.com [209.85.222.182]) by imf01.hostedemail.com (Postfix) with ESMTP id 77BBE40005 for ; Sat, 16 Nov 2024 17:58:54 +0000 (UTC) Authentication-Results: imf01.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=icf1sKLK; spf=pass (imf01.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.182 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1731779772; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=O+zqV+yymXPy0a+WK0KlfZbpXJ50Be1gsnAxvt14Xcw=; b=3uUnZe/tEEj5RujUTscbsBao6pwdwsPi1a3TgT3ro50QMHv8AHZY/G96McZKfTUfmpn8Jb +F+muFaK7CpmJWwRcdmodtzKuhDCkQF6xpvZgvGiDSoZzsuRm2NEciPLbbEyUZjTq9397k xUy5zMGGUAyrsgX75xVBtCkQ/sjjJ8Q= ARC-Authentication-Results: i=1; imf01.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=icf1sKLK; spf=pass (imf01.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.182 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1731779772; a=rsa-sha256; cv=none; b=kVjMDQCi354Xf+k8E3HwiAwmfwHNe0Yglzgkd3uxF0bLweqNe2BnEvyU261rY5QhhgXR9p gBQk8EWRWIBtqjwmKGvyrmFU98DVKuln9Db06JpQBGWPPJ+G+h8JVd4DDGH9xz7siIZlTb D5li0CWc6wCSg0tBZFKCWioi2nYT7Ms= Received: by mail-qk1-f182.google.com with SMTP id af79cd13be357-7b1511697a5so173883785a.2 for ; Sat, 16 Nov 2024 09:59:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen-com.20230601.gappssmtp.com; s=20230601; t=1731779970; x=1732384770; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=O+zqV+yymXPy0a+WK0KlfZbpXJ50Be1gsnAxvt14Xcw=; b=icf1sKLKaa/waM3rFI+Vn6swiT4B2N1HvuhiobqmqiIzSncrxORPR2hEf8OEBoNCE+ RR1jhSsVeJt01fKxOU91c7dpaznHu4G8K/1AninbOPQrIW/n0G6tkLzo5LA7XITgmbSj hLyHPeeJ9cosmVjud20EU8kzgZHLdAO2OKQMHJ+BPLMBGtTRhgSXwtvod4SJKU29qXDj Yra7YMttqqSbWPIlVqn4tserWLWg8yBWSYZMhVB8azEf3e79IaXUzFb6iiS6j9HA3hm8 goqj3XKDg2lOEohTCfdzOsVmqeaWN3mbm7xfWfFYsLsg0CRSSqV2Dewtub5drnoelQgc 9/xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731779970; x=1732384770; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=O+zqV+yymXPy0a+WK0KlfZbpXJ50Be1gsnAxvt14Xcw=; b=QA22XVE1yUwfRPCRng9LFhf2rzp5STVvA9kkFSzZaz9AtHh9r2kcg2tEivkHMP8obA hqXpf30+am52gyve51nwQZnVSiihbtC1qyvlFvVb3+iwNxYRNojkYLq8o4g/42PSPwCF noHnP8veZvVWw5zyAAFjK7pYPzSxHPTFk02DOAukuZLmdJJ0WvlZ3asFkepcXxPln8m8 u9Hp7hUREHItdQ9c9Y3VkjtzP5R5Dr7YCgOoA4BbzjoQT0OjuT49Mr4MWBJWS9ZP16cT XpIYGjEhHtYKq0DguYnDQ9xFHgw0Ax1PMbtmw3uyFJ/j7excaIt+Ih6+raoFyGxIT9AE GB0g== X-Forwarded-Encrypted: i=1; AJvYcCW5tSXklYeTlxZbVftjZs/iejfkO8SO39lf2jlXrw94ITRyuthTtZP1Yl1MwJWmc0KcpXrKgNUNdg==@kvack.org X-Gm-Message-State: AOJu0Yy9qkYrUJtuGb+gsoU5QO+kWnl9TEqidBXAIMJvQv9AhYNDMgLS FzMmnc2N0a51MbLz0zfgHjZ94/0UCKRWdcNRFv/ByCRDkbWzhCjjUK1KjcXx2VA= X-Google-Smtp-Source: AGHT+IFM6KBibOKfJYXQZBFVrr3w+/SZOQZsHgHNA1kQveXXhFr8pkzrxC/81+yPU1STXi1ZMpKadw== X-Received: by 2002:a05:620a:4507:b0:7b1:4762:65 with SMTP id af79cd13be357-7b3622b4a6bmr766363285a.20.1731779970003; Sat, 16 Nov 2024 09:59:30 -0800 (PST) Received: from soleen.c.googlers.com.com (51.57.86.34.bc.googleusercontent.com. [34.86.57.51]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7b35ca309d6sm280530085a.94.2024.11.16.09.59.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 Nov 2024 09:59:29 -0800 (PST) From: Pasha Tatashin To: pasha.tatashin@soleen.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, cgroups@vger.kernel.org, linux-kselftest@vger.kernel.org, akpm@linux-foundation.org, corbet@lwn.net, derek.kiernan@amd.com, dragan.cvetic@amd.com, arnd@arndb.de, gregkh@linuxfoundation.org, viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz, tj@kernel.org, hannes@cmpxchg.org, mhocko@kernel.org, roman.gushchin@linux.dev, shakeel.butt@linux.dev, muchun.song@linux.dev, Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, vbabka@suse.cz, jannh@google.com, shuah@kernel.org, vegard.nossum@oracle.com, vattunuru@marvell.com, schalla@marvell.com, david@redhat.com, willy@infradead.org, osalvador@suse.de, usama.anjum@collabora.com, andrii@kernel.org, ryan.roberts@arm.com, peterx@redhat.com, oleg@redhat.com, tandersen@netflix.com, rientjes@google.com, gthelen@google.com Subject: [RFCv1 3/6] mm: Add a dump_page variant that accept log level argument Date: Sat, 16 Nov 2024 17:59:19 +0000 Message-ID: <20241116175922.3265872-4-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.47.0.338.g60cca15819-goog In-Reply-To: <20241116175922.3265872-1-pasha.tatashin@soleen.com> References: <20241116175922.3265872-1-pasha.tatashin@soleen.com> MIME-Version: 1.0 X-Rspamd-Server: rspam07 X-Rspamd-Queue-Id: 77BBE40005 X-Stat-Signature: b3jhb1ptacwf463pjn7dcortfuiu8ypa X-Rspam-User: X-HE-Tag: 1731779934-317128 X-HE-Meta: U2FsdGVkX18zl294Mv2R49XEECNFefl5o002zknpaLLMu9HVa6R3z5zysYUeueVcg2J01KBOf+fMpyeYmMF4MpW1fohJQWIgcC/lAI4GY+DxIBDAhhP3UdMbXG7UKr+drVGqsOpXYLW41EuQ6rDrjU/YOvSeMLQA/UbgWz3LbZDnwf57YxW+xzvT6XvLYvUkGdEkeRsaDok6wKBH11tMtTE0jpmkdDxlnkwsIoEo0n1a8uFLi6za/IwBc+08Wkxr8fOnqj1eYvp/xJiceTjOHtewptnnjd0rJRKL8flOS+QaMj1JHQH1bPSMc/9TwQmr/19xgN3CJPmRXHNp2WtfUCUKprYYx1L58q4CvVpFiQRfK4Hyio6HIUEBVF62uXjoY//2rtDM073cHxp40JX3v0Eoebf/8gu26KYql2SigXtYyCGy/mTuOWOzC6yuO0j4AvmxctaKegz6D8Sa++QIIsCvKKuMP66djMCe/3Epr0n3aq0K5ew0rhhEZKtZS/Ph37+E+LyfF98Hnt7zsMyFEMkC1Th24lWo//FRIuTychJaohXwuN8gqIHbqFQ2R7exPCvaG0jqdR5Ceb5ichIvEntbi+ivWLG+U/eaR3zbq6bTkryw0lCTlnjv7TesJrwuwF51/iI3J+UK/3w0wuMMkhCRcWopUIxAhy4E4bI6jXgCrl+axHI9/wfSf0gFiUCBFc8WR78ePIgtTeCqAXVKU+KN94QNUPzigC8d4QW+peTiCzLGEPQ6kOLU6CRz5gcFovDLsfmS9xkhrvpat6yVkVGd9jSe6dwq44KP0uOpVHzNpy0JOjS6iy/wiYGRN4u5gX3rOy1Gc0rW4qTpYk+fugaPD0JsT88WAUn28vmki3ouRjaOIQn0eFA5wboJO1Y2A0VM6nwwSf7PG2EAfvc3FipaaoleCHXhW/YtfiZBNTi7WH2s2G7VAuzDbDmjZ0o3qzEgcblNiaHxj6nb4Zz 3ht0VOdX iEZxVBRDi25qQ+iYS37RI5EH7ylgS3jp6QPnrbeEK3l8FewewtQbwbnPlD8vm0eEFNyawpu2gjoDRur06GIrL761ojgOulsHInUpS+CjYNIGu+BeasxhtkPrv01JfEKPnF3VxKMVGb9/Q0MXO0PUjE+n/ijd/+A21tP1pPIwmMiDFroslo38OYYi72Ge0ECEEmal6/pkPNXwPYWvG6kIwDk3KQ00jWwZqHr/Jb3EIc7u8Tg6xvfPQg1IKL/AB16o96m9+cfX0FONMgSNJCIVe3+uHT4J3+3IgoDyXLuoyBCJhdfUtobC9IHzf8hHuYVzvJzBxf70IF+5bTisJlcI8DVWGXFrJUUs59RLSyvzU6eHTrk558MLt8zh0SP9saYQgbuc0N+IbuzDgbaNeCEBqa7x+44eZAw1tbdGNXTjDI8if2msg80qAJPvdnJkzfS9xcvt9 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: Page Detective uses info level, while dump_page() uses warn level. Add a new function dump_page_lvl() that accepts log level argument to be able to dump pages at specific level. Also, this enables adding a modules specific prefix to output of this function. Signed-off-by: Pasha Tatashin --- fs/inode.c | 18 +++++++------- include/linux/fs.h | 2 +- include/linux/mmdebug.h | 1 + mm/debug.c | 53 ++++++++++++++++++++++------------------- 4 files changed, 39 insertions(+), 35 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 8dabb224f941..1114319d82b2 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -603,7 +603,7 @@ void __remove_inode_hash(struct inode *inode) } EXPORT_SYMBOL(__remove_inode_hash); -void dump_mapping(const struct address_space *mapping) +void dump_mapping(const char *loglvl, const struct address_space *mapping) { struct inode *host; const struct address_space_operations *a_ops; @@ -619,31 +619,31 @@ void dump_mapping(const struct address_space *mapping) */ if (get_kernel_nofault(host, &mapping->host) || get_kernel_nofault(a_ops, &mapping->a_ops)) { - pr_warn("invalid mapping:%px\n", mapping); + printk("%sinvalid mapping:%px\n", loglvl, mapping); return; } if (!host) { - pr_warn("aops:%ps\n", a_ops); + printk("%saops:%ps\n", loglvl, a_ops); return; } if (get_kernel_nofault(dentry_first, &host->i_dentry.first) || get_kernel_nofault(ino, &host->i_ino)) { - pr_warn("aops:%ps invalid inode:%px\n", a_ops, host); + printk("%saops:%ps invalid inode:%px\n", loglvl, a_ops, host); return; } if (!dentry_first) { - pr_warn("aops:%ps ino:%lx\n", a_ops, ino); + printk("%saops:%ps ino:%lx\n", loglvl, a_ops, ino); return; } dentry_ptr = container_of(dentry_first, struct dentry, d_u.d_alias); if (get_kernel_nofault(dentry, dentry_ptr) || !dentry.d_parent || !dentry.d_name.name) { - pr_warn("aops:%ps ino:%lx invalid dentry:%px\n", - a_ops, ino, dentry_ptr); + printk("%saops:%ps ino:%lx invalid dentry:%px\n", + loglvl, a_ops, ino, dentry_ptr); return; } @@ -653,8 +653,8 @@ void dump_mapping(const struct address_space *mapping) * Even if strncpy_from_kernel_nofault() succeeded, * the fname could be unreliable */ - pr_warn("aops:%ps ino:%lx dentry name(?):\"%s\"\n", - a_ops, ino, fname); + printk("%saops:%ps ino:%lx dentry name(?):\"%s\"\n", + loglvl, a_ops, ino, fname); } void clear_inode(struct inode *inode) diff --git a/include/linux/fs.h b/include/linux/fs.h index a25b72397af5..fa2b04bed9d6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3137,7 +3137,7 @@ extern void unlock_new_inode(struct inode *); extern void discard_new_inode(struct inode *); extern unsigned int get_next_ino(void); extern void evict_inodes(struct super_block *sb); -void dump_mapping(const struct address_space *); +void dump_mapping(const char *loglvl, const struct address_space *); /* * Userspace may rely on the inode number being non-zero. For example, glibc diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h index 39a7714605a7..69849d457f4c 100644 --- a/include/linux/mmdebug.h +++ b/include/linux/mmdebug.h @@ -11,6 +11,7 @@ struct mm_struct; struct vma_iterator; void dump_page(const struct page *page, const char *reason); +void dump_page_lvl(const char *loglvl, const struct page *page); void dump_vma(const struct vm_area_struct *vma); void dump_mm(const struct mm_struct *mm); void vma_iter_dump_tree(const struct vma_iterator *vmi); diff --git a/mm/debug.c b/mm/debug.c index aa57d3ffd4ed..0df242c77c7c 100644 --- a/mm/debug.c +++ b/mm/debug.c @@ -67,36 +67,38 @@ static const char *page_type_name(unsigned int page_type) return page_type_names[i]; } -static void __dump_folio(struct folio *folio, struct page *page, - unsigned long pfn, unsigned long idx) +static void __dump_folio(const char *loglvl, struct folio *folio, + struct page *page, unsigned long pfn, + unsigned long idx) { struct address_space *mapping = folio_mapping(folio); int mapcount = atomic_read(&page->_mapcount); char *type = ""; mapcount = page_mapcount_is_type(mapcount) ? 0 : mapcount + 1; - pr_warn("page: refcount:%d mapcount:%d mapping:%p index:%#lx pfn:%#lx\n", - folio_ref_count(folio), mapcount, mapping, - folio->index + idx, pfn); + printk("%spage: refcount:%d mapcount:%d mapping:%p index:%#lx pfn:%#lx\n", + loglvl, folio_ref_count(folio), mapcount, mapping, + folio->index + idx, pfn); if (folio_test_large(folio)) { - pr_warn("head: order:%u mapcount:%d entire_mapcount:%d nr_pages_mapped:%d pincount:%d\n", - folio_order(folio), - folio_mapcount(folio), - folio_entire_mapcount(folio), - folio_nr_pages_mapped(folio), - atomic_read(&folio->_pincount)); + printk("%shead: order:%u mapcount:%d entire_mapcount:%d nr_pages_mapped:%d pincount:%d\n", + loglvl, + folio_order(folio), + folio_mapcount(folio), + folio_entire_mapcount(folio), + folio_nr_pages_mapped(folio), + atomic_read(&folio->_pincount)); } #ifdef CONFIG_MEMCG if (folio->memcg_data) - pr_warn("memcg:%lx\n", folio->memcg_data); + printk("%smemcg:%lx\n", loglvl, folio->memcg_data); #endif if (folio_test_ksm(folio)) type = "ksm "; else if (folio_test_anon(folio)) type = "anon "; else if (mapping) - dump_mapping(mapping); + dump_mapping(loglvl, mapping); BUILD_BUG_ON(ARRAY_SIZE(pageflag_names) != __NR_PAGEFLAGS + 1); /* @@ -105,22 +107,22 @@ static void __dump_folio(struct folio *folio, struct page *page, * state for debugging, it should be fine to accept a bit of * inaccuracy here due to racing. */ - pr_warn("%sflags: %pGp%s\n", type, &folio->flags, - is_migrate_cma_folio(folio, pfn) ? " CMA" : ""); + printk("%s%sflags: %pGp%s\n", loglvl, type, &folio->flags, + is_migrate_cma_folio(folio, pfn) ? " CMA" : ""); if (page_has_type(&folio->page)) pr_warn("page_type: %x(%s)\n", folio->page.page_type >> 24, page_type_name(folio->page.page_type)); - print_hex_dump(KERN_WARNING, "raw: ", DUMP_PREFIX_NONE, 32, - sizeof(unsigned long), page, - sizeof(struct page), false); + print_hex_dump(loglvl, "raw: ", DUMP_PREFIX_NONE, 32, + sizeof(unsigned long), page, + sizeof(struct page), false); if (folio_test_large(folio)) - print_hex_dump(KERN_WARNING, "head: ", DUMP_PREFIX_NONE, 32, - sizeof(unsigned long), folio, - 2 * sizeof(struct page), false); + print_hex_dump(loglvl, "head: ", DUMP_PREFIX_NONE, 32, + sizeof(unsigned long), folio, + 2 * sizeof(struct page), false); } -static void __dump_page(const struct page *page) +void dump_page_lvl(const char *loglvl, const struct page *page) { struct folio *foliop, folio; struct page precise; @@ -149,22 +151,23 @@ static void __dump_page(const struct page *page) if (idx > nr_pages) { if (loops-- > 0) goto again; - pr_warn("page does not match folio\n"); + printk("%spage does not match folio\n", loglvl); precise.compound_head &= ~1UL; foliop = (struct folio *)&precise; idx = 0; } dump: - __dump_folio(foliop, &precise, pfn, idx); + __dump_folio(loglvl, foliop, &precise, pfn, idx); } +EXPORT_SYMBOL_GPL(dump_page_lvl); void dump_page(const struct page *page, const char *reason) { if (PagePoisoned(page)) pr_warn("page:%p is uninitialized and poisoned", page); else - __dump_page(page); + dump_page_lvl(KERN_WARNING, page); if (reason) pr_warn("page dumped because: %s\n", reason); dump_page_owner(page); From patchwork Sat Nov 16 17:59:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pasha Tatashin X-Patchwork-Id: 13877673 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 C002ED68BE7 for ; Sat, 16 Nov 2024 17:59:40 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id E8B2C9C001E; Sat, 16 Nov 2024 12:59:34 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id E092F9C0018; Sat, 16 Nov 2024 12:59:34 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id ADD739C001E; Sat, 16 Nov 2024 12:59:34 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 7D97D9C0018 for ; Sat, 16 Nov 2024 12:59:34 -0500 (EST) Received: from smtpin24.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 061D91C7F1E for ; Sat, 16 Nov 2024 17:59:34 +0000 (UTC) X-FDA: 82792719282.24.D292EAB Received: from mail-qk1-f177.google.com (mail-qk1-f177.google.com [209.85.222.177]) by imf11.hostedemail.com (Postfix) with ESMTP id 113C740002 for ; Sat, 16 Nov 2024 17:58:33 +0000 (UTC) Authentication-Results: imf11.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=rKQYPyVE; spf=pass (imf11.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.177 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1731779794; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=KpdAZ7NZ1Nr9pnhg/ywtF8JBC0mNTuaieti10H6ChLE=; b=lExhvCenXChBss1R9ks3qrT6B1idz1FX/r2uQdXuFNxNTxqoOnaqQbbOrAjItSTScaR4wo VWDL1z5Psa8CPe+uMabY5R+MjWoN6pi2oTRD+QFJaGFVGMWq+wuHeexaPmOOiDOt2hg4tp LnPf+i6avc180TZw0ahxerAylE8iI0s= ARC-Authentication-Results: i=1; imf11.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=rKQYPyVE; spf=pass (imf11.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.177 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1731779794; a=rsa-sha256; cv=none; b=ZKKSiAFjRNoWcrkAzLuBiw+rCDnTYSsckTbk1j5p9T37r+AJJMX+Q/KNspWhXjr2G9Cu6t HYSx3QxuTPNPhqiAd4Y9AYkBbN82TqfUD5PoHoz3TzXCQgenAMpyVrzNs7eBzwBmd4orET GYmaBC2JOt5LbqwTWpujE0t+oKGgfjk= Received: by mail-qk1-f177.google.com with SMTP id af79cd13be357-7b1601e853eso50255185a.2 for ; Sat, 16 Nov 2024 09:59:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen-com.20230601.gappssmtp.com; s=20230601; t=1731779971; x=1732384771; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=KpdAZ7NZ1Nr9pnhg/ywtF8JBC0mNTuaieti10H6ChLE=; b=rKQYPyVEloRbvmOgdqnlm68Zj19JeATs27K1XbGqax+9eXXzhCd7/BFo/mb2bRxEi4 JOIP7podHkSqQ2lkfIk53aH2PcCAFHdlGxxaDeHy4zcGJxZHeLrbP5KnBKJa7F6hbb90 oDLe9jfPJMKKTvIU3Gtui0yeITv/EazVkiQbjswVhMwTtoY7fNTJM7Pwc+oXwBsvlVaX 91ZR0mBm1gzkWIbGn7ivHAiHAVKWFwF5GUvpYjqBZdE1tcKWYT8bOVIA1M3urQY9JPcU Th8a3LFdMXqxE4pZ+gJkklXN1Ki5hcRR9/vxVAguUKpVkrRJUODXeqlMUl9f9DTYsNl7 I+Vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731779971; x=1732384771; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KpdAZ7NZ1Nr9pnhg/ywtF8JBC0mNTuaieti10H6ChLE=; b=lPmxzKAe2duHp606+N9QJi5J3zWRewh8YhIRQSnWh6wWLHzqB4/U9otxu+GGCj0zMI CrapXtmjF70TZO5rAkYgG8bOfAbq8g3qSIHSxPHhkbSf0i7Xc2ekV8JLQwtTkw2rfZU4 snZl3s8PdkiOPflHH5i6iPLCVqX194T416OEWc+pRwjE31PWeHry5AM53QnPRhRNB0/Y IMz9adW8MXW8VNYO02VLbqX0gtcDaODw057kHs5o17EEGAaXgy9Ycb33iRKMpdtujJoa nqYY64IjjTLOEg/65LgNdkmkVWkz9GT0AOK0M/1+djGo5xTc4wWgbsgaFdkzeQC+o/g1 fmlw== X-Forwarded-Encrypted: i=1; AJvYcCXVpuIS6ohzgu/LtVnILIGIaAD/6o19OUxW5DIgCEpE7wjEX7z0wXIKAN2yORzleS2NIM1jysruMw==@kvack.org X-Gm-Message-State: AOJu0YyyqPTedpRGPJ2/L1RGNg8sk4LDBTC8zBvRQEJRwPY8f9cJr9gN HY93cHSLzUk3j4+DfIa0YMkZ/2boi55oHGKz1gEKWG8LVT+YhacTBVbpAAFljQYhqV//qZXl2h8 r6HQ= X-Google-Smtp-Source: AGHT+IGEnnX3bsIVd4XhVJcy27AUXs1yLJInjTM3KRKozEzVKVF/2+dtQNAKFZY9A0G4bhtuK3H56Q== X-Received: by 2002:a05:620a:2902:b0:7a9:8679:993 with SMTP id af79cd13be357-7b36229521amr1016883385a.13.1731779971199; Sat, 16 Nov 2024 09:59:31 -0800 (PST) Received: from soleen.c.googlers.com.com (51.57.86.34.bc.googleusercontent.com. [34.86.57.51]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7b35ca309d6sm280530085a.94.2024.11.16.09.59.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 Nov 2024 09:59:30 -0800 (PST) From: Pasha Tatashin To: pasha.tatashin@soleen.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, cgroups@vger.kernel.org, linux-kselftest@vger.kernel.org, akpm@linux-foundation.org, corbet@lwn.net, derek.kiernan@amd.com, dragan.cvetic@amd.com, arnd@arndb.de, gregkh@linuxfoundation.org, viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz, tj@kernel.org, hannes@cmpxchg.org, mhocko@kernel.org, roman.gushchin@linux.dev, shakeel.butt@linux.dev, muchun.song@linux.dev, Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, vbabka@suse.cz, jannh@google.com, shuah@kernel.org, vegard.nossum@oracle.com, vattunuru@marvell.com, schalla@marvell.com, david@redhat.com, willy@infradead.org, osalvador@suse.de, usama.anjum@collabora.com, andrii@kernel.org, ryan.roberts@arm.com, peterx@redhat.com, oleg@redhat.com, tandersen@netflix.com, rientjes@google.com, gthelen@google.com Subject: [RFCv1 4/6] misc/page_detective: Introduce Page Detective Date: Sat, 16 Nov 2024 17:59:20 +0000 Message-ID: <20241116175922.3265872-5-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.47.0.338.g60cca15819-goog In-Reply-To: <20241116175922.3265872-1-pasha.tatashin@soleen.com> References: <20241116175922.3265872-1-pasha.tatashin@soleen.com> MIME-Version: 1.0 X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 113C740002 X-Stat-Signature: srszecj485ern57jt3anw817zopg5b53 X-Rspam-User: X-HE-Tag: 1731779913-742763 X-HE-Meta: U2FsdGVkX1+2EqxcwEm3Pyogw2U8HGoiKzszssFnWObURZpbCJWP/RnZSjVz1U05g5t5pg59GMCGth/kAAuyq1PCisSAstzVvNJEPxvKeFOizGCCSjkCXiKiKI6xHkk2SePb9pv43ZevYj2/wNRMgrEnApJErIhSereM+o1uWnlfQ0BgwBKH1pmRkY9fd3B/jo0ud+ZEBaHJEwqPYWlhNbZEmQknT25zMcE2/5TEHJiOufgnnGSDp75mKhzHLrBmdKOasToETRNMRkKd+CaWAdb3A/ckWomsbVC8XNwXZ3Qfh1ftkIWRMRUwCwL4GyTAgc/KVpfdP/88vSILKfG6uJdEPE4MAVfjSjt3DppTBkBCGFXKDFZYs6+oN0uJEinTBXaNyObyCh5IiZU+P2763d6mxqCjdJrfmucDeptMYdILQUWE0FZLPoGlvkzWM6EDkTy38TXQbeMzdFY+A6FnHidWpBBC2SAzIom2d9aEQDj9JXFTFwqAxrunCd55/zfDLrnFYnMBxSU44928KYuCQWPIN1/6u16cVMx9FIdHffCdBPo1rrT0Y1W64truNCo9za4eaFEmB+ZIgG87EGdB2gFdpjAJZBHl0LXKF6NWbKyZkNuCch9fx7ybfLtDzBmbY2yTR6pQ/gx5LjNp7/spGKRha1+vKZHePiq9/g7DxM1+26CXB0EWQz6REH5s+Q/lvdN0qMkoCvEQG/iAdmUWa9tzJLXALkXXJF1bMRPTzjvYABfXikaTBsiJ7o6mViMSJwZdPzTIN/+NiPyMjDmpkqdU3mptHpKjbGdniir26dqF1aGkDsImYPsVG5bdE1mScUVXBW1ihU92FNl8jf5/nqh+sXHAlymaJTOGGI0IPUN9KRcckLzxazU4cB5b4YpzZ6a0JfjuMC9XxprjhxyXdlLvjwEtcMDJG7okc4MTu0Yp7wBuDA1sApfmMwnZYjvvg6ajNtQLTHXVd6u7ES6 6Yt9VWQm YyvlWhnRRMpZWczS1X00oV/W2Vsd4A3o/+/Cw+f3HxTsRWiIcdK3AybrXL5fTPPU+03u+0mDg5KULj+ocuIcmqiskdo2czAseCfJ5ix9kjNxE6CTz1Wj8li1iesKlK02JV2WUWLobJibRprDD+/mseqcfO4i5SvMUhgAcF95ubjTyDwR0vqWTJK8B4Swa/Lf0Pt2KgPYLYVMlVwVvMZu9rEFlkP4UZs9s6U+WpNuNGBfncijajH5K82lgJqIqmh3D+STv8a6Znz2TFe46jrkCjll0RbVqnLmVijjn5Ozqr5FI8i4uP1LhWkbfedksN067G74sfgioX083gwGJznN0a9MOChbLes+3HtzJLfbZjPS5qpidHHkP3IyUMetmoAYiCZDzz0DMg1noZQYbVqNn1T5Avr6Zm5TCnaEYIF68x9WuyCR3dLJoEPFUpaidguW+/kyZOmIgHXUmaZYALXjznB/BXPUGCF/srWetYyi7+VxBnDoz4DcXgvSSmGtWBhhJTymMxdaeBoZtE+I= 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: Page Detective is a kernel debugging tool that provides detailed information about the usage and mapping of physical memory pages. It operates through the Linux debugfs interface, providing access to both virtual and physical address inquiries. The output, presented via kernel log messages (accessible with dmesg), will help administrators and developers understand how specific pages are utilized by the system. This tool can be used to investigate various memory-related issues, such as checksum failures during live migration, filesystem journal failures, general segfaults, or other corruptions. Signed-off-by: Pasha Tatashin --- Documentation/misc-devices/index.rst | 1 + Documentation/misc-devices/page_detective.rst | 78 ++ MAINTAINERS | 7 + drivers/misc/Kconfig | 11 + drivers/misc/Makefile | 1 + drivers/misc/page_detective.c | 808 ++++++++++++++++++ 6 files changed, 906 insertions(+) create mode 100644 Documentation/misc-devices/page_detective.rst create mode 100644 drivers/misc/page_detective.c diff --git a/Documentation/misc-devices/index.rst b/Documentation/misc-devices/index.rst index 8c5b226d8313..d64723f20804 100644 --- a/Documentation/misc-devices/index.rst +++ b/Documentation/misc-devices/index.rst @@ -23,6 +23,7 @@ fit into other categories. max6875 mrvl_cn10k_dpi oxsemi-tornado + page_detective pci-endpoint-test spear-pcie-gadget tps6594-pfsm diff --git a/Documentation/misc-devices/page_detective.rst b/Documentation/misc-devices/page_detective.rst new file mode 100644 index 000000000000..06f666d5b3a9 --- /dev/null +++ b/Documentation/misc-devices/page_detective.rst @@ -0,0 +1,78 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +============== +Page Detective +============== + +Author: +Pasha Tatashin + +Overview +-------- + +Page Detective is a kernel debugging tool designed to provide in-depth +information about the usage and mapping of physical memory pages within the +Linux kernel. By leveraging the debugfs interface, it enables administrators +and developers to investigate the status and allocation of memory pages. + +This tool is valuable for diagnosing memory-related issues such as checksum +errors during live migration, filesystem journal failures, segmentation faults, +and other forms of corruption. + +Functionality +------------- + +Page Detective operates by accepting input through its debugfs interface files +located in ``/sys/kernel/debug/page_detective`` directory: + + * virt: Takes input in the format . It resolves the + provided virtual address within the specified process's address space and + outputs comprehensive information about the corresponding physical page's + mapping and usage. + + * phys: Takes a raw physical address as input. It directly investigates the + usage of the specified physical page and outputs relevant information. + +The output generated by Page Detective is delivered through kernel log messages +(accessible using dmesg). + +Usage +----- + +- Enable Page Detective: Ensure the CONFIG_PAGE_DETECTIVE kernel configuration + option is enabled. + +- Access debugfs: Mount the debugfs filesystem (if not already mounted): + ``mount -t debugfs nodev /sys/kernel/debug`` + +- Interact with Page Detective through one of two interfaces: + ``echo " " > /sys/kernel/debug/page_detective/virt`` + ``echo "" > /sys/kernel/debug/page_detective/phys`` + +- The file page detective interface is accessible only to users with + CAP_SYS_ADMIN. + +Example +------- + +``` +# echo 0x1078fb000 > /sys/kernel/debug/page_detective/phys +Page Detective: Investigating physical[105bafc50] pfn[105baf] +Page Detective: metadata for Small Page pfn[105baf] folio[ffffea000416ebc0] order [0] +Page Detective: page: refcount:1 mapcount:1 mapping:0000000000000000 index:0x7fffffffb pfn:0x105baf +Page Detective: memcg:ffff888106189000 +Page Detective: anon flags: 0x200000000020828(uptodate|lru|owner_2|swapbacked|node=0|zone=2) +Page Detective: raw: 0200000000020828 ffffea000416ec08 ffffea000416e7c8 ffff888106382bc9 +Page Detective: raw: 00000007fffffffb 0000000000000000 0000000100000000 ffff888106189000 +Page Detective: memcg: [/system.slice/system-serial\x2dgetty.slice/serial-getty@ttyS0.service ] [/system.slice/system-serial\x2dgetty.slice ] [/system.slice ] [/ ] +Page Detective: The page is direct mapped addr[ffff888105baf000] pmd entry[8000000105a001e3] +Page Detective: The page is not mapped into kernel vmalloc area +Page Detective: The page mapped into kernel page table: 1 times +Page Detective: Scanned kernel page table in [0.003353799s] +Page Detective: The page contains some data +Page Detective: mapped by PID[377] cmd[page_detective_] mm[ffff888101778000] pgd[ffff888100894000] at addr[7ffea333b000] pte[8000000105baf067] +Page Detective: vma[ffff888101701aa0] start[7ffea331e000] end[7ffea333f000] flags[0000000000100173] name: [stack] +Page Detective: Scanned [16] user page tables in [0.000297744s] +Page Detective: The page mapped into user page tables: 1 times +Page Detective: Finished investigation of physical[105bafc50] +``` diff --git a/MAINTAINERS b/MAINTAINERS index 21fdaa19229a..654d4650670d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17450,6 +17450,13 @@ F: mm/page-writeback.c F: mm/readahead.c F: mm/truncate.c +PAGE DETECTIVE +M: Pasha Tatashin +L: linux-kernel@vger.kernel.org +S: Maintained +F: Documentation/misc-devices/page_detective.rst +F: drivers/misc/page_detective.c + PAGE POOL M: Jesper Dangaard Brouer M: Ilias Apalodimas diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 3fe7e2a9bd29..2965c3c7cdef 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -492,6 +492,17 @@ config MISC_RTSX tristate default MISC_RTSX_PCI || MISC_RTSX_USB +config PAGE_DETECTIVE + depends on PAGE_TABLE_CHECK + depends on MEMCG + bool "Page Detective" + help + A debugging tool designed to provide detailed information about the + usage and mapping of physical memory pages. This tool operates through + the Linux debugfs interface, providing access to both virtual and + physical address inquiries. The output is presented via kernel log + messages. + config HISI_HIKEY_USB tristate "USB GPIO Hub on HiSilicon Hikey 960/970 Platform" depends on (OF && GPIOLIB) || COMPILE_TEST diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index a9f94525e181..411f17fcde6b 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o obj-$(CONFIG_OCXL) += ocxl/ obj-$(CONFIG_BCM_VK) += bcm-vk/ obj-y += cardreader/ +obj-$(CONFIG_PAGE_DETECTIVE) += page_detective.o obj-$(CONFIG_PVPANIC) += pvpanic/ obj-$(CONFIG_UACCE) += uacce/ obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o diff --git a/drivers/misc/page_detective.c b/drivers/misc/page_detective.c new file mode 100644 index 000000000000..300064d83dd3 --- /dev/null +++ b/drivers/misc/page_detective.c @@ -0,0 +1,808 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright (c) 2024, Google LLC. + * Pasha Tatashin + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef pr_fmt +#define pr_fmt(fmt) "Page Detective: " fmt + +/* + * Walk 4T of VA space at a time, in order to periodically release the mmap + * lock + */ +#define PD_WALK_MAX_RANGE BIT(42) + +/* Synchronizes writes to virt and phys files */ +static DEFINE_MUTEX(page_detective_mutex); +static struct dentry *page_detective_debugfs_dir; + +static void page_detective_memcg(struct folio *folio) +{ + struct mem_cgroup *memcg; + + if (!folio_try_get(folio)) + return; + + memcg = get_mem_cgroup_from_folio(folio); + if (memcg) { + pr_info("memcg:"); + do { + pr_cont(" ["); + pr_cont_cgroup_path(memcg->css.cgroup); + pr_cont(" ]"); + } while ((memcg = parent_mem_cgroup(memcg))); + mem_cgroup_put(memcg); + pr_cont("\n"); + } + folio_put(folio); +} + +static void page_detective_metadata(unsigned long pfn) +{ + struct folio *folio = pfn_folio(pfn); + bool hugetlb, trans; + unsigned int order; + + if (!folio) { + pr_info("metadata for pfn[%lx] not found\n", pfn); + return; + } + + trans = folio_test_large(folio) && folio_test_large_rmappable(folio); + hugetlb = folio_test_hugetlb(folio); + order = folio_order(folio); + + pr_info("metadata for %s pfn[%lx] folio[%px] order [%u]\n", + (trans) ? "Transparent Huge Page" : (hugetlb) ? "HugeTLB" : + "Small Page", pfn, folio, order); + dump_page_lvl(KERN_INFO pr_fmt(""), &folio->page); + page_detective_memcg(folio); +} + +struct pd_private_kernel { + unsigned long pfn; + unsigned long direct_map_addr; + bool direct_map; + unsigned long vmalloc_maps; + long maps; +}; + +#define ENTRY_NAME(entry_page_size) ({ \ + unsigned long __entry_page_size = (entry_page_size); \ + \ + (__entry_page_size == PUD_SIZE) ? "pud" : \ + (__entry_page_size == PMD_SIZE) ? "pmd" : "pte"; \ +}) + +static void pd_print_entry_kernel(struct pd_private_kernel *pr, + unsigned long pfn_current, + unsigned long addr, + unsigned long entry_page_size, + unsigned long entry) +{ + unsigned long pfn = pr->pfn; + + if (pfn_current <= pfn && + pfn < (pfn_current + (entry_page_size >> PAGE_SHIFT))) { + bool v, d; + + addr += ((pfn << PAGE_SHIFT) & (entry_page_size - 1)); + v = (addr >= VMALLOC_START && addr < VMALLOC_END); + d = (pr->direct_map_addr == addr); + + if (v) { + pr_info("The page is mapped in vmalloc addr[%lx] %s entry[%lx]\n", + addr, ENTRY_NAME(entry_page_size), entry); + pr->vmalloc_maps++; + } else if (d) { + pr_info("The page is direct mapped addr[%lx] %s entry[%lx]\n", + addr, ENTRY_NAME(entry_page_size), entry); + pr->direct_map = true; + } else { + pr_info("The page is mapped into kernel addr[%lx] %s entry[%lx]\n", + addr, ENTRY_NAME(entry_page_size), entry); + } + + pr->maps++; + } +} + +static int pd_pud_entry_kernel(pud_t *pud, unsigned long addr, + unsigned long next, + struct mm_walk *walk) +{ + pud_t pudval = READ_ONCE(*pud); + + cond_resched(); + if (!pud_leaf(pudval)) + return 0; + + pd_print_entry_kernel(walk->private, pud_pfn(pudval), addr, + PUD_SIZE, pud_val(pudval)); + + return 0; +} + +static int pd_pmd_entry_kernel(pmd_t *pmd, unsigned long addr, + unsigned long next, + struct mm_walk *walk) +{ + pmd_t pmdval = READ_ONCE(*pmd); + + cond_resched(); + if (!pmd_leaf(pmdval)) + return 0; + + pd_print_entry_kernel(walk->private, pmd_pfn(pmdval), addr, + PMD_SIZE, pmd_val(pmdval)); + + return 0; +} + +static int pd_pte_entry_kernel(pte_t *pte, unsigned long addr, + unsigned long next, + struct mm_walk *walk) +{ + pte_t pteval = READ_ONCE(*pte); + + pd_print_entry_kernel(walk->private, pte_pfn(pteval), addr, + PAGE_SIZE, pte_val(pteval)); + + return 0; +} + +static const struct mm_walk_ops pd_kernel_ops = { + .pud_entry = pd_pud_entry_kernel, + .pmd_entry = pd_pmd_entry_kernel, + .pte_entry = pd_pte_entry_kernel, + .walk_lock = PGWALK_RDLOCK +}; + +/* + * Walk kernel page table, and print all mappings to this pfn, return 1 if + * pfn is mapped in direct map, return 0 if not mapped in direct map, and + * return -1 if operation canceled by user. + */ +static int page_detective_kernel_map_info(unsigned long pfn, + unsigned long direct_map_addr) +{ + struct pd_private_kernel pr = {0}; + unsigned long s, e; + + pr.direct_map_addr = direct_map_addr; + pr.pfn = pfn; + + for (s = PAGE_OFFSET; s != ~0ul; ) { + e = s + PD_WALK_MAX_RANGE; + if (e < s) + e = ~0ul; + + if (walk_page_range_kernel(s, e, &pd_kernel_ops, &pr)) { + pr_info("Received a cancel signal from user, while scanning kernel mappings\n"); + return -1; + } + cond_resched(); + s = e; + } + + if (!pr.vmalloc_maps) { + pr_info("The page is not mapped into kernel vmalloc area\n"); + } else if (pr.vmalloc_maps > 1) { + pr_info("The page is mapped into vmalloc area: %ld times\n", + pr.vmalloc_maps); + } + + if (!pr.direct_map) + pr_info("The page is not mapped into kernel direct map\n"); + + pr_info("The page mapped into kernel page table: %ld times\n", pr.maps); + + return pr.direct_map ? 1 : 0; +} + +/* Print kernel information about the pfn, return -1 if canceled by user */ +static int page_detective_kernel(unsigned long pfn) +{ + unsigned long *mem = __va((pfn) << PAGE_SHIFT); + unsigned long sum = 0; + int direct_map; + u64 s, e; + int i; + + s = sched_clock(); + direct_map = page_detective_kernel_map_info(pfn, (unsigned long)mem); + e = sched_clock() - s; + pr_info("Scanned kernel page table in [%llu.%09llus]\n", + e / NSEC_PER_SEC, e % NSEC_PER_SEC); + + /* Canceled by user or no direct map */ + if (direct_map < 1) + return direct_map; + + for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) + sum |= mem[i]; + + if (sum == 0) + pr_info("The page contains only zeroes\n"); + else + pr_info("The page contains some data\n"); + + return 0; +} + +static char __vma_name[PATH_MAX]; +static const char *vma_name(struct vm_area_struct *vma) +{ + const struct path *path; + const char *name_fmt, *name; + + get_vma_name(vma, &path, &name, &name_fmt); + + if (path) { + name = d_path(path, __vma_name, PATH_MAX); + if (IS_ERR(name)) { + strscpy(__vma_name, "[???]", PATH_MAX); + goto out; + } + } else if (name || name_fmt) { + snprintf(__vma_name, PATH_MAX, name_fmt ?: "%s", name); + } else { + if (vma_is_anonymous(vma)) + strscpy(__vma_name, "[anon]", PATH_MAX); + else if (vma_is_fsdax(vma)) + strscpy(__vma_name, "[fsdax]", PATH_MAX); + else if (vma_is_dax(vma)) + strscpy(__vma_name, "[dax]", PATH_MAX); + else + strscpy(__vma_name, "[other]", PATH_MAX); + } + +out: + return __vma_name; +} + +static void pd_show_vma_info(struct mm_struct *mm, unsigned long addr) +{ + struct vm_area_struct *vma = find_vma(mm, addr); + + if (!vma) { + pr_info("vma not found for this mapping\n"); + return; + } + + pr_info("vma[%px] start[%lx] end[%lx] flags[%016lx] name: %s\n", + vma, vma->vm_start, vma->vm_end, vma->vm_flags, vma_name(vma)); +} + +static void pd_get_comm_pid(struct mm_struct *mm, char *comm, int *pid) +{ + struct task_struct *task; + + rcu_read_lock(); + task = rcu_dereference(mm->owner); + if (task) { + strscpy(comm, task->comm, TASK_COMM_LEN); + *pid = task->pid; + } else { + strscpy(comm, "__ exited __", TASK_COMM_LEN); + *pid = -1; + } + rcu_read_unlock(); +} + +struct pd_private_user { + struct mm_struct *mm; + unsigned long pfn; + long maps; +}; + +static void pd_print_entry_user(struct pd_private_user *pr, + unsigned long pfn_current, + unsigned long addr, + unsigned long entry_page_size, + unsigned long entry, + bool is_hugetlb) +{ + unsigned long pfn = pr->pfn; + + if (pfn_current <= pfn && + pfn < (pfn_current + (entry_page_size >> PAGE_SHIFT))) { + char comm[TASK_COMM_LEN]; + int pid; + + pd_get_comm_pid(pr->mm, comm, &pid); + addr += ((pfn << PAGE_SHIFT) & (entry_page_size - 1)); + pr_info("%smapped by PID[%d] cmd[%s] mm[%px] pgd[%px] at addr[%lx] %s[%lx]\n", + is_hugetlb ? "hugetlb " : "", + pid, comm, pr->mm, pr->mm->pgd, addr, + ENTRY_NAME(entry_page_size), entry); + pd_show_vma_info(pr->mm, addr); + pr->maps++; + } +} + +static int pd_pud_entry_user(pud_t *pud, unsigned long addr, unsigned long next, + struct mm_walk *walk) +{ + pud_t pudval = READ_ONCE(*pud); + + cond_resched(); + if (!pud_user_accessible_page(pudval)) + return 0; + + pd_print_entry_user(walk->private, pud_pfn(pudval), addr, PUD_SIZE, + pud_val(pudval), false); + walk->action = ACTION_CONTINUE; + + return 0; +} + +static int pd_pmd_entry_user(pmd_t *pmd, unsigned long addr, unsigned long next, + struct mm_walk *walk) +{ + pmd_t pmdval = READ_ONCE(*pmd); + + cond_resched(); + if (!pmd_user_accessible_page(pmdval)) + return 0; + + pd_print_entry_user(walk->private, pmd_pfn(pmdval), addr, PMD_SIZE, + pmd_val(pmdval), false); + walk->action = ACTION_CONTINUE; + + return 0; +} + +static int pd_pte_entry_user(pte_t *pte, unsigned long addr, unsigned long next, + struct mm_walk *walk) +{ + pte_t pteval = READ_ONCE(*pte); + + if (!pte_user_accessible_page(pteval)) + return 0; + + pd_print_entry_user(walk->private, pte_pfn(pteval), addr, PAGE_SIZE, + pte_val(pteval), false); + walk->action = ACTION_CONTINUE; + + return 0; +} + +static int pd_hugetlb_entry(pte_t *pte, unsigned long hmask, unsigned long addr, + unsigned long next, struct mm_walk *walk) +{ + pte_t pteval = READ_ONCE(*pte); + + cond_resched(); + pd_print_entry_user(walk->private, pte_pfn(pteval), addr, next - addr, + pte_val(pteval), true); + walk->action = ACTION_CONTINUE; + + return 0; +} + +static const struct mm_walk_ops pd_user_ops = { + .pud_entry = pd_pud_entry_user, + .pmd_entry = pd_pmd_entry_user, + .pte_entry = pd_pte_entry_user, + .hugetlb_entry = pd_hugetlb_entry, + .walk_lock = PGWALK_RDLOCK +}; + +/* + * print information about mappings of pfn by mm, return -1 if canceled + * return number of mappings found. + */ +static long page_detective_user_mm_info(struct mm_struct *mm, unsigned long pfn) +{ + struct pd_private_user pr = {0}; + unsigned long s, e; + + pr.pfn = pfn; + pr.mm = mm; + + for (s = 0; s != TASK_SIZE; ) { + e = s + PD_WALK_MAX_RANGE; + if (e > TASK_SIZE || e < s) + e = TASK_SIZE; + + if (mmap_read_lock_killable(mm)) { + pr_info("Received a cancel signal from user, while scanning user mappings\n"); + return -1; + } + walk_page_range(mm, s, e, &pd_user_ops, &pr); + mmap_read_unlock(mm); + cond_resched(); + s = e; + } + return pr.maps; +} + +/* + * Report where/if PFN is mapped in user page tables, return -1 if canceled + * by user. + */ +static int page_detective_usermaps(unsigned long pfn) +{ + struct task_struct *task, *t; + struct mm_struct **mm_table, *mm; + unsigned long proc_nr, mm_nr, i; + bool canceled_by_user; + long maps, ret; + u64 s, e; + + s = sched_clock(); + /* Get the number of processes currently running */ + proc_nr = 0; + rcu_read_lock(); + for_each_process(task) + proc_nr++; + rcu_read_unlock(); + + /* Allocate mm_table to fit mm from every running process */ + mm_table = kvmalloc_array(proc_nr, sizeof(struct mm_struct *), + GFP_KERNEL); + + if (!mm_table) { + pr_info("No memory to traverse though user mappings\n"); + return 0; + } + + /* get mm from every processes and copy its pointer into mm_table */ + mm_nr = 0; + rcu_read_lock(); + for_each_process(task) { + if (mm_nr == proc_nr) { + pr_info("Number of processes increased while scanning, some will be skipped\n"); + break; + } + + t = find_lock_task_mm(task); + if (!t) + continue; + + mm = task->mm; + if (!mm || !mmget_not_zero(mm)) { + task_unlock(t); + continue; + } + task_unlock(t); + + mm_table[mm_nr++] = mm; + } + rcu_read_unlock(); + + /* Walk through every user page table,release mm reference afterwards */ + canceled_by_user = false; + maps = 0; + for (i = 0; i < mm_nr; i++) { + if (!canceled_by_user) { + ret = page_detective_user_mm_info(mm_table[i], pfn); + if (ret == -1) + canceled_by_user = true; + else + maps += ret; + } + mmput(mm_table[i]); + cond_resched(); + } + + kvfree(mm_table); + + e = sched_clock() - s; + pr_info("Scanned [%ld] user page tables in [%llu.%09llus]\n", + mm_nr, e / NSEC_PER_SEC, e % NSEC_PER_SEC); + pr_info("The page mapped into user page tables: %ld times\n", maps); + + return canceled_by_user ? -1 : 0; +} + +static void page_detective_iommu(unsigned long pfn) +{ +} + +static void page_detective_tdp(unsigned long pfn) +{ +} + +static void page_detective(unsigned long pfn) +{ + if (!pfn_valid(pfn)) { + pr_info("pfn[%lx] is invalid\n", pfn); + return; + } + + if (pfn == 0) { + pr_info("Skipping look-up for pfn[0] mapped many times into kernel page table\n"); + return; + } + + /* Report metadata information */ + page_detective_metadata(pfn); + + /* + * Report information about kernel mappings, and basic content + * information: i.e. all zero or not. + */ + if (page_detective_kernel(pfn) < 0) + return; + + /* Report where/if PFN is mapped in user page tables */ + if (page_detective_usermaps(pfn) < 0) + return; + + /* Report where/if PFN is mapped in IOMMU page tables */ + page_detective_iommu(pfn); + + /* Report where/if PFN is mapped in 2 dimensional paging */ + page_detective_tdp(pfn); +} + +static u64 pid_virt_to_phys(unsigned int pid, unsigned long virt_addr) +{ + unsigned long phys_addr = -1; + struct task_struct *task; + struct mm_struct *mm; + pgd_t *pgd, pgdval; + p4d_t *p4d, p4dval; + pud_t *pud, pudval; + pmd_t *pmd, pmdval; + pte_t *pte, pteval; + + if (virt_addr >= TASK_SIZE) { + pr_err("%s: virt_addr[%lx] is above TASK_SIZE[%lx]\n", + __func__, virt_addr, TASK_SIZE); + return -1; + } + + /* Find the task_struct using the PID */ + task = find_get_task_by_vpid(pid); + if (!task) { + pr_err("%s: Task not found for PID %d\n", __func__, pid); + return -1; + } + + mm = get_task_mm(task); + put_task_struct(task); + if (!mm) { + pr_err("%s: PID %d, can't get mm reference\n", __func__, pid); + return -1; + } + + if (mmap_read_lock_killable(mm)) { + pr_info("Received a cancel signal from user, while convirting virt to phys\n"); + mmput(mm); + return -1; + } + + pgd = pgd_offset(mm, virt_addr); + pgdval = READ_ONCE(*pgd); + if (!pgd_present(pgdval) || unlikely(pgd_bad(pgdval))) { + pr_err("%s: pgd[%llx] present[%d] bad[%d]\n", __func__, + (u64)pgd_val(pgdval), pgd_present(pgdval), + pgd_bad(pgdval)); + goto putmm_exit; + } + + p4d = p4d_offset(pgd, virt_addr); + p4dval = READ_ONCE(*p4d); + if (!p4d_present(p4dval) || unlikely(p4d_bad(p4dval))) { + pr_err("%s: p4d[%llx] present[%d] bad[%d]\n", __func__, + (u64)p4d_val(p4dval), p4d_present(p4dval), + p4d_bad(p4dval)); + goto putmm_exit; + } + + pud = pud_offset(p4d, virt_addr); + pudval = READ_ONCE(*pud); + if (!pud_present(pudval)) { + pr_err("%s: pud[%llx] present[%d]\n", __func__, + (u64)pud_val(pudval), pud_present(pudval)); + goto putmm_exit; + } + + if (pud_leaf(pudval)) { + phys_addr = (pud_pfn(pudval) << PAGE_SHIFT) + | (virt_addr & ~PUD_MASK); + goto putmm_exit; + } + + pmd = pmd_offset(pud, virt_addr); + pmdval = READ_ONCE(*pmd); + if (!pmd_present(pmdval)) { + pr_err("%s: pmd[%llx] present[%d]\n", __func__, + (u64)pmd_val(pmdval), pmd_present(pmdval)); + goto putmm_exit; + } + + if (pmd_leaf(pmdval)) { + phys_addr = (pmd_pfn(pmdval) << PAGE_SHIFT) + | (virt_addr & ~PMD_MASK); + goto putmm_exit; + } + + pte = pte_offset_kernel(pmd, virt_addr); + pteval = READ_ONCE(*pte); + if (!pte_present(pteval)) { + pr_err("%s: pte[%llx] present[%d]\n", __func__, + (u64)pte_val(pteval), pte_present(pteval)); + goto putmm_exit; + } + + phys_addr = pte_pfn(*pte) << PAGE_SHIFT; + +putmm_exit: + mmap_read_unlock(mm); + mmput(mm); + return phys_addr; +} + +static ssize_t page_detective_virt_write(struct file *file, + const char __user *data, + size_t count, loff_t *ppos) +{ + char *input_str, *pid_str, *virt_str; + unsigned int pid, err, i; + unsigned long virt_addr; + u64 phys_addr; + + /* If canceled by user simply return without printing anything */ + err = mutex_lock_killable(&page_detective_mutex); + if (err) + return count; + + input_str = kzalloc(count + 1, GFP_KERNEL); + if (!input_str) { + pr_err("%s: Unable to allocate input_str buffer\n", + __func__); + mutex_unlock(&page_detective_mutex); + return -EAGAIN; + } + + if (copy_from_user(input_str, data, count)) { + kfree(input_str); + pr_err("%s: Unable to copy user input into virt file\n", + __func__); + mutex_unlock(&page_detective_mutex); + return -EFAULT; + } + + virt_str = NULL; + pid_str = input_str; + for (i = 0; i < count - 1; i++) { + if (isspace(input_str[i])) { + input_str[i] = '\0'; + virt_str = &input_str[i + 1]; + break; + } + } + + if (!virt_str) { + kfree(input_str); + pr_err("%s: Invalid virt file input, should be: ' '\n", + __func__); + mutex_unlock(&page_detective_mutex); + return -EINVAL; + } + + err = kstrtouint(pid_str, 0, &pid); + if (err) { + kfree(input_str); + pr_err("%s: Failed to parse pid\n", __func__); + mutex_unlock(&page_detective_mutex); + return err; + } + + err = kstrtoul(virt_str, 0, &virt_addr); + if (err) { + kfree(input_str); + pr_err("%s: Failed to parse virtual address\n", __func__); + mutex_unlock(&page_detective_mutex); + return err; + } + + kfree(input_str); + + phys_addr = pid_virt_to_phys(pid, virt_addr); + if (phys_addr == -1) { + pr_err("%s: Can't translate virtual to physical address\n", + __func__); + mutex_unlock(&page_detective_mutex); + return -EINVAL; + } + + pr_info("Investigating pid[%u] virtual[%lx] physical[%llx] pfn[%lx]\n", + pid, virt_addr, phys_addr, PHYS_PFN(phys_addr)); + page_detective(PHYS_PFN(phys_addr)); + pr_info("Finished investigation of virtual[%lx]\n", virt_addr); + mutex_unlock(&page_detective_mutex); + + return count; +} + +static ssize_t page_detective_phys_write(struct file *file, + const char __user *data, + size_t count, loff_t *ppos) +{ + u64 phys_addr; + int err; + + /* If canceled by user simply return without printing anything */ + err = mutex_lock_killable(&page_detective_mutex); + if (err) + return count; + + err = kstrtou64_from_user(data, count, 0, &phys_addr); + + if (err) { + pr_err("%s: Failed to parse physical address\n", __func__); + mutex_unlock(&page_detective_mutex); + return err; + } + + pr_info("Investigating physical[%llx] pfn[%lx]\n", phys_addr, + PHYS_PFN(phys_addr)); + page_detective(PHYS_PFN(phys_addr)); + pr_info("Finished investigation of physical[%llx]\n", phys_addr); + mutex_unlock(&page_detective_mutex); + + return count; +} + +static int page_detective_open(struct inode *inode, struct file *file) +{ + /* Deny access if not CAP_SYS_ADMIN */ + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + return simple_open(inode, file); +} + +static const struct file_operations page_detective_virt_fops = { + .owner = THIS_MODULE, + .open = page_detective_open, + .write = page_detective_virt_write, +}; + +static const struct file_operations page_detective_phys_fops = { + .owner = THIS_MODULE, + .open = page_detective_open, + .write = page_detective_phys_write, +}; + +static int __init page_detective_init(void) +{ + page_detective_debugfs_dir = debugfs_create_dir("page_detective", NULL); + + debugfs_create_file("virt", 0200, page_detective_debugfs_dir, NULL, + &page_detective_virt_fops); + debugfs_create_file("phys", 0200, page_detective_debugfs_dir, NULL, + &page_detective_phys_fops); + + return 0; +} +module_init(page_detective_init); + +static void page_detective_exit(void) +{ + debugfs_remove_recursive(page_detective_debugfs_dir); +} +module_exit(page_detective_exit); + +MODULE_DESCRIPTION("Page Detective"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Pasha Tatashin "); From patchwork Sat Nov 16 17:59:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pasha Tatashin X-Patchwork-Id: 13877674 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 DCE9ED68BF6 for ; Sat, 16 Nov 2024 17:59:43 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 778FE9C001F; Sat, 16 Nov 2024 12:59:35 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 7286D9C0018; Sat, 16 Nov 2024 12:59:35 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 52D859C001F; Sat, 16 Nov 2024 12:59:35 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 1A3469C0018 for ; Sat, 16 Nov 2024 12:59:35 -0500 (EST) Received: from smtpin02.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id CA93B1A1D4E for ; Sat, 16 Nov 2024 17:59:34 +0000 (UTC) X-FDA: 82792720164.02.F1B6C1C Received: from mail-qk1-f171.google.com (mail-qk1-f171.google.com [209.85.222.171]) by imf23.hostedemail.com (Postfix) with ESMTP id 499FD140003 for ; Sat, 16 Nov 2024 17:59:02 +0000 (UTC) Authentication-Results: imf23.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=ct6XonbA; spf=pass (imf23.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.171 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1731779915; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=3/iffj9AwrmFtA4v15nvK21qog5xz91IornymITaB6w=; b=8ZZ+hXfEit58Qa5+ADy9BENI1ugl6pog+XD+JMH4Gjwy93buOb2lx6T4UgVQlKL6PuztwL FMq5ChZrjQ3K585Iv58eoYoVEMJBhLYkRr+3vfndOHWkvc711ZNh1U1g9JkZVTOHbOUyqF bLTCTyxHQdHlrmdAKQzCTJAp9t/VIJU= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1731779915; a=rsa-sha256; cv=none; b=fsn14AB6qaDqsw/qkiJhlbJuhXiTY5pHx5OH8tmAAEgbbtmJbT6wRPW6mcj5a6ugpJIV/f vmMRIJzjRHCjTWhEA/+gBWkmfxPm06Bv/s32T+R+J2W+7RCnD2utnwbfDKFXTLb0Bc3nn5 G0C76Rc7w7Qh7Nd8TW0yRI2xJWcOjfM= ARC-Authentication-Results: i=1; imf23.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=ct6XonbA; spf=pass (imf23.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.171 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com; dmarc=pass (policy=none) header.from=soleen.com Received: by mail-qk1-f171.google.com with SMTP id af79cd13be357-7b150dc7bc0so53375485a.1 for ; Sat, 16 Nov 2024 09:59:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen-com.20230601.gappssmtp.com; s=20230601; t=1731779972; x=1732384772; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=3/iffj9AwrmFtA4v15nvK21qog5xz91IornymITaB6w=; b=ct6XonbA6fDukT65hxGsRBl4Mu2ACuOurfs8qq+As/E0kS9apJeF1PeMhWqSAtG1Rj ay1gL8uRMPr+W3ZI+kwRnwn/3XhqOyf/N9dfewcJt73ahAOX8kfdGnf4z4ZE0vRxYpy+ HE5Q+CLw4VXbaJ5+VUAQCkpmwoyDl+vuUyFjKDwrvf2u5YtF/daSToFz/bnXlysjpWjJ Nap6IWq2jgmubUKUovw/ADRd1BQ3Dgy16AwEwWZFCgSPSPabShkOuP2ygxZatj7gQxbV Xl+/Ne+Tlj+0ArMhOfLPxk3q6Kg9AoP6e3R6cBL/tcLREK31rDvTh6bYxbXNkm88hy5W ytqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731779972; x=1732384772; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3/iffj9AwrmFtA4v15nvK21qog5xz91IornymITaB6w=; b=wG0vXPQ7p9PSzsCF79NUGZCiPuOiILuds33mc7hdrj+V14Sq0QkBE1ozz65AEUYK8A VKMNR45bgmsIG9SNCgbjz6vy7uZ4hTrYtBTWEiJMUX/Ys8JTA2g2VU3JsmwdPRSV+NXL 7rK7N5WHX/X1I9Yvn+J7x3SFkBo04GbLNmI0zJwpGUgaGj1p7xrxDO0He8ackQfSWril M6HE4L2Ha8VRZ/LZmHdN59EpY0df7z6+tNBB2KnPIo9ZmjG133+wteYzS7s7/hClNrK5 J2OU0emozgV7wMyulFWQemdu/D9sqkjA7KdkDn51kBMcHpaobsIPAjR+ktlFN1mS0DBJ JYFw== X-Forwarded-Encrypted: i=1; AJvYcCVN7ca2Yo3blRVONSD4+w52YMj13KlFzSiyUgIUTte1aGUwGu8+mb4KpxDNZehnmZ1wbn4E6OZ5hg==@kvack.org X-Gm-Message-State: AOJu0Yzna9Lus0Nvl2H9VJx/8HxY+QW6+16QDZioGTYR5B3USZHzVj3a e+jqqQ63KjN1r/IWSROL7TzXj8opiAMwq0zmt6cGiVliMjPv1kMwYnIfnCVXi/I= X-Google-Smtp-Source: AGHT+IE8nO0AKxOziuoNl9dbDG8TGtYIxbG42IN6xSk4xPBQ4y/OVn6DudmIksQC42h6NfG3SOwe+g== X-Received: by 2002:a05:620a:3186:b0:7b1:5306:a1ca with SMTP id af79cd13be357-7b3622de46amr1114698785a.36.1731779972207; Sat, 16 Nov 2024 09:59:32 -0800 (PST) Received: from soleen.c.googlers.com.com (51.57.86.34.bc.googleusercontent.com. [34.86.57.51]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7b35ca309d6sm280530085a.94.2024.11.16.09.59.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 Nov 2024 09:59:31 -0800 (PST) From: Pasha Tatashin To: pasha.tatashin@soleen.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, cgroups@vger.kernel.org, linux-kselftest@vger.kernel.org, akpm@linux-foundation.org, corbet@lwn.net, derek.kiernan@amd.com, dragan.cvetic@amd.com, arnd@arndb.de, gregkh@linuxfoundation.org, viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz, tj@kernel.org, hannes@cmpxchg.org, mhocko@kernel.org, roman.gushchin@linux.dev, shakeel.butt@linux.dev, muchun.song@linux.dev, Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, vbabka@suse.cz, jannh@google.com, shuah@kernel.org, vegard.nossum@oracle.com, vattunuru@marvell.com, schalla@marvell.com, david@redhat.com, willy@infradead.org, osalvador@suse.de, usama.anjum@collabora.com, andrii@kernel.org, ryan.roberts@arm.com, peterx@redhat.com, oleg@redhat.com, tandersen@netflix.com, rientjes@google.com, gthelen@google.com Subject: [RFCv1 5/6] misc/page_detective: enable loadable module Date: Sat, 16 Nov 2024 17:59:21 +0000 Message-ID: <20241116175922.3265872-6-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.47.0.338.g60cca15819-goog In-Reply-To: <20241116175922.3265872-1-pasha.tatashin@soleen.com> References: <20241116175922.3265872-1-pasha.tatashin@soleen.com> MIME-Version: 1.0 X-Stat-Signature: fs9k9cfj97c4j3ebd1xpgugtd7ptgyp9 X-Rspam-User: X-Rspamd-Queue-Id: 499FD140003 X-Rspamd-Server: rspam02 X-HE-Tag: 1731779942-76595 X-HE-Meta: U2FsdGVkX181xLd5QLjcJbk/qZ9ZOgOufM3nsKrosiAzjTXJBbPeyVTerHFBxVxcNY48sPfncl52ArbOUhtAStbfzVgqJfJwWmWYFRIOwh361THY6cm8jRngrTVFd12JTbCvCgOr5wJzTUwGaqiK06m3wtygSwmEU/FQwlkZkN37Voo/Hn00XLe0gns20j+bxXpZOXjQyy8HnELgi6pI4nLRgUlJ7Ld9Vh60vYqN0fWtc31DQYj0tw8xlCl3w73INQHQ+GQyNdJyuqRZJvk8U9kCu0Z3pU1UVcNIGQaR9iWGSaWhKKMIZ58Iu1AbQnteRJBV5fwjPbJKSaNwmQGy+ZyH9oN8x7ixbZKIWRs9vlC8uUUKsTjrP5g/+SzUOv7yik8Vt8z76RLYUEYEFEodGMZd48/oynNt+7mFRomYsBHHMAmAlByClfmBxXzia2DtPkkwrUnraRqYao9B6sZrlQHyyctB2ZuzIew/Et7VhZ5CGvF0fV0OC+xsH6/dxj8d6LE6cQvybAeOY81cu46+sfCgs5fnp6RVnOrwAgUYeyMWEArccwG5aU7Z45ChHk4BNUIlPrEBtyltEae7IiRRc83oPw9I8WQAaUR/02BN46TTHZHhVZpjXWNV04T9Yny4CNqausvTWHC+IrHoYbdQKtKJCrHnjM6v5RHB9KCr9+SiX9HNdVreTtqsVYrmIZvzVjv2S4Jr1Y+STDtN0OefgSGGKzsrM5RgUQbCCxNfFpOqFmUvjSYiwU4CGfgIGooHpWzKrD4MporIq5dRi171fpUdx/FCBJDQiYY5e9dqA2Y1eH3i4w8+5k5BYXJmNjQcm031xd4O5Ss6M/LmQinKC7QSxtT2vx+B70eRSsv1ry0VdvaF3W10Yo04sBcLScmrx4jS672qVX6UNZQddNxECybt6GTPl7FOIPcES4Dk6XPTy+c2lvSnlK97XwJtWkvCPYMYE5/x2jgSQl4LPiU 8iq3XZ0o 4nd1Lim4wh1LLi2efXxJJSzs/rB4+mnXgB4t002eh3mzpD9sOWmn056qsahPkaGCQcS5/0hdkf0N8uJsZGHu24Zjr4A6NOvScmgxl+2yFcWe1SzbEIQxrvuYld3bi3hrsovV5DHse2zxMiT3CGRz8s3zVvl6lHcHR8sXGGE5Y7rVRXj6nSBeZuYet92c+FUEtSPue2t9puoXvZNVfsEBWBxkYTI7BjFrxusXoIfdApv48wl2uajpL3VeF6Xumc0BeiZ/nMnO/bas316wdXV3caityVptQ9wo87tUfZlNsrlKJjieoBJ3eYfKJQjpPR+mfzYcN+F8veF73as8qFK2a06lta/d4c764+PzHST0JbcZ8dlxfb6m7YQcpWedbyA5mY2mRrzkxXI5Qn2kg3Hs1ml7Nn695WQw1O4rkro6KWt98GaeFxUaDmEc0tA== 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: Export the missing symbols, and allow page_detective to be built as a loadable module. This can be make this available in the field, where Page Detective is loaded only once it is needed. Signed-off-by: Pasha Tatashin --- drivers/misc/Kconfig | 2 +- fs/kernfs/dir.c | 1 + kernel/pid.c | 1 + mm/memcontrol.c | 1 + mm/oom_kill.c | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 2965c3c7cdef..b58b4f9567ff 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -495,7 +495,7 @@ config MISC_RTSX config PAGE_DETECTIVE depends on PAGE_TABLE_CHECK depends on MEMCG - bool "Page Detective" + tristate "Page Detective" help A debugging tool designed to provide detailed information about the usage and mapping of physical memory pages. This tool operates through diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 458519e416fe..84ad163a4281 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -279,6 +279,7 @@ void pr_cont_kernfs_path(struct kernfs_node *kn) out: spin_unlock_irqrestore(&kernfs_pr_cont_lock, flags); } +EXPORT_SYMBOL_GPL(pr_cont_kernfs_path); /** * kernfs_get_parent - determine the parent node and pin it diff --git a/kernel/pid.c b/kernel/pid.c index 2715afb77eab..89454dc9535e 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -447,6 +447,7 @@ struct task_struct *find_get_task_by_vpid(pid_t nr) return task; } +EXPORT_SYMBOL_GPL(find_get_task_by_vpid); struct pid *get_task_pid(struct task_struct *task, enum pid_type type) { diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 53db98d2c4a1..389aeec06a04 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -967,6 +967,7 @@ struct mem_cgroup *get_mem_cgroup_from_folio(struct folio *folio) rcu_read_unlock(); return memcg; } +EXPORT_SYMBOL_GPL(get_mem_cgroup_from_folio); /** * mem_cgroup_iter - iterate over memory cgroup hierarchy diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 4d7a0004df2c..df230a091dcc 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -149,6 +149,7 @@ struct task_struct *find_lock_task_mm(struct task_struct *p) return t; } +EXPORT_SYMBOL_GPL(find_lock_task_mm); /* * order == -1 means the oom kill is required by sysrq, otherwise only From patchwork Sat Nov 16 17:59:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pasha Tatashin X-Patchwork-Id: 13877675 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 6B443D68BE7 for ; Sat, 16 Nov 2024 17:59:46 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C0FDD9C0020; Sat, 16 Nov 2024 12:59:36 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id B70789C0018; Sat, 16 Nov 2024 12:59:36 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 900519C0020; Sat, 16 Nov 2024 12:59:36 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0011.hostedemail.com [216.40.44.11]) by kanga.kvack.org (Postfix) with ESMTP id 683759C0018 for ; Sat, 16 Nov 2024 12:59:36 -0500 (EST) Received: from smtpin01.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 0468F161D35 for ; Sat, 16 Nov 2024 17:59:35 +0000 (UTC) X-FDA: 82792718316.01.4B28AD9 Received: from mail-qk1-f181.google.com (mail-qk1-f181.google.com [209.85.222.181]) by imf05.hostedemail.com (Postfix) with ESMTP id AF54E100016 for ; Sat, 16 Nov 2024 17:58:05 +0000 (UTC) Authentication-Results: imf05.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=TlvrAEex; dmarc=pass (policy=none) header.from=soleen.com; spf=pass (imf05.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.181 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1731779909; a=rsa-sha256; cv=none; b=OqxYBj0vW2MnOAOSu8YxsZPlT9mJefBx/SOSwzpUQnMuWr2mBYCKjuRu/XjuhClxHclUGM +kBGIhS1fmGxLEnDqlKQ24ngrQVrTK/X6CM8Roz+zW8yQujzKcOKWU4IdECJ5ipOSv7Zin /NJKcMygcZi3zbcScgOCOt1Bo5nKAdo= ARC-Authentication-Results: i=1; imf05.hostedemail.com; dkim=pass header.d=soleen-com.20230601.gappssmtp.com header.s=20230601 header.b=TlvrAEex; dmarc=pass (policy=none) header.from=soleen.com; spf=pass (imf05.hostedemail.com: domain of pasha.tatashin@soleen.com designates 209.85.222.181 as permitted sender) smtp.mailfrom=pasha.tatashin@soleen.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1731779909; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=QG3SRrOSiFJ9NPWhEP5q+JEDCSQKlJpYQw3cIJlKt/Q=; b=T673wbDvL3H6JvNdn7/3OuP+xY1/sDHbFdW+XjeQQcZpYi9qqdIgQ6TDhX5piYFHn72Fry mdJpykZnU/S4WyzKObG0guPGlgaqpKhVHmP4IMDcwmcYEMezb9rHSoCq1DK9YDytXQCTG1 wWCiQ1CmL+YOzKMFT5Bb2xJZ9nCvXhA= Received: by mail-qk1-f181.google.com with SMTP id af79cd13be357-7b1434b00a2so59463385a.0 for ; Sat, 16 Nov 2024 09:59:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen-com.20230601.gappssmtp.com; s=20230601; t=1731779973; x=1732384773; darn=kvack.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=QG3SRrOSiFJ9NPWhEP5q+JEDCSQKlJpYQw3cIJlKt/Q=; b=TlvrAEex4VsHJaXmepwK0n2QNwoJtts1ffiZXzpoIi/DSqUsWwMYPv6tdbMhDtZrwj 01pV9hArcRnp2qYnqXjBi4TWdM4aM+VbwwXQ1ulXWZm3FsIwi0BqkHTJ3zonf9+vBx6+ 4V6jTCZePZzQdTI+CGmc8rvRKKO8PiaXYLViz5GZAk6T01ThU1GYsbkH7ncCtfag9OgP VIOcJeHj3r5llfctX6cMnt4kUgohqshdzifVOCte4bRdGeajcJAQmffZRQ/zfoWzmpfc vssvP2vJNdRlLLmIuwtbshAbZYEaZkd9xOgN0gIAVnFTfK+vvaJ7OM/SLApq2tNx0iQD 02FQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731779973; x=1732384773; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QG3SRrOSiFJ9NPWhEP5q+JEDCSQKlJpYQw3cIJlKt/Q=; b=QH4uMVnDvx92EYSIJr8Jb7dcN8E344RsN1EKSIqerxgxBHxyWVBkmt61hQuwSBQVLL BYZGV0uDTckQQTeMCsdxxGRtlvBPLdahgzKr+DTRNr15FfW0WgfTxrHA6kfqIgVh24kz gwhiKxU/obgLBZqoexwfWqUnbF8K2FKP8+V9cjwZ880Lk9jA9eSBx9V4a/iDkB6VL+Ao 1OlxuIX/8ZcXr22E4Iqh4yMgOTyabXYWF1B1qfwY71IVGshL5vVptaIBdOqKV1m/6Ihf VziEN09ccwshHYLl7OJnnfnviqrcYjmz2WBVV7vSvzoHofii1OlsBDsfV6MKOs/yly6x KZYA== X-Forwarded-Encrypted: i=1; AJvYcCXk7cGsnxbgbI01h8FZcXRv5jCm431ZIf5u+RzVAbd+NoeIiusjESgzWPN6s0tzb1qAPV/Vh2SSJA==@kvack.org X-Gm-Message-State: AOJu0YwyS1+EZq1Dtw/AbYoUcoejufEDLQP1z52ajP8lHwbaEN8xBWtN lTBkjtc3BI/xuMo2ShwQbs9/y7OyYnkNU3Bxvb8HFWLQ9JtRqGZTKQJySYVag6jFH2FDeQqrOss Mb6g= X-Google-Smtp-Source: AGHT+IGVCl6rH2CJUvmAwSg/6gzKEwfvGbuKVgBlp4JYH/2BQo3mFCfAA8mR+IzxB5NHlDV6V4Jxiw== X-Received: by 2002:a05:620a:4625:b0:7b1:43e2:712b with SMTP id af79cd13be357-7b3622c6430mr1076751285a.11.1731779973279; Sat, 16 Nov 2024 09:59:33 -0800 (PST) Received: from soleen.c.googlers.com.com (51.57.86.34.bc.googleusercontent.com. [34.86.57.51]) by smtp.gmail.com with ESMTPSA id af79cd13be357-7b35ca309d6sm280530085a.94.2024.11.16.09.59.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 16 Nov 2024 09:59:32 -0800 (PST) From: Pasha Tatashin To: pasha.tatashin@soleen.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-doc@vger.kernel.org, linux-fsdevel@vger.kernel.org, cgroups@vger.kernel.org, linux-kselftest@vger.kernel.org, akpm@linux-foundation.org, corbet@lwn.net, derek.kiernan@amd.com, dragan.cvetic@amd.com, arnd@arndb.de, gregkh@linuxfoundation.org, viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz, tj@kernel.org, hannes@cmpxchg.org, mhocko@kernel.org, roman.gushchin@linux.dev, shakeel.butt@linux.dev, muchun.song@linux.dev, Liam.Howlett@oracle.com, lorenzo.stoakes@oracle.com, vbabka@suse.cz, jannh@google.com, shuah@kernel.org, vegard.nossum@oracle.com, vattunuru@marvell.com, schalla@marvell.com, david@redhat.com, willy@infradead.org, osalvador@suse.de, usama.anjum@collabora.com, andrii@kernel.org, ryan.roberts@arm.com, peterx@redhat.com, oleg@redhat.com, tandersen@netflix.com, rientjes@google.com, gthelen@google.com Subject: [RFCv1 6/6] selftests/page_detective: Introduce self tests for Page Detective Date: Sat, 16 Nov 2024 17:59:22 +0000 Message-ID: <20241116175922.3265872-7-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.47.0.338.g60cca15819-goog In-Reply-To: <20241116175922.3265872-1-pasha.tatashin@soleen.com> References: <20241116175922.3265872-1-pasha.tatashin@soleen.com> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Queue-Id: AF54E100016 X-Rspamd-Server: rspam11 X-Stat-Signature: 194n1gh76j9reg55tau1i4frd1gt69e7 X-HE-Tag: 1731779885-888131 X-HE-Meta: U2FsdGVkX1+kkPfW7bc5ZJU3OmLjFYZp3Z1eXijOSnrM6OyB613KLjsBfVWjDP9fRLxZHw+1lLwoEZJogxmpx2nbCEX83gejw0HB2ztmpYSIV/Z5irWDHjliWb3xeh1p6S/rqH+YfksFsmib7ClRJxIkscIkh+bTIYLc5MKZfKL3rY/CIA/5Z9YP5CDDRtK/lYzQBXodNwLqdYvYtj1ikmms5ymIOiQE/WuOnPnzaxvNCfS9oE/BKRd/QBwZ8cn/orFgMX6WSTdQ1LmUnK64uyC3bm/bFLRz1BLdwbuZ6+L70OAitwVyfynpDmvDun0wWkswOTgwqlVxfsMe7mEhb27mC50Y3j0oEDTsO40L69Y4cxliVJbASj8VCrdA+E79zfto0jS2NZHZYMz+NPeBUOFno+IvFTDnd33eNKfZZfvIupDD4lqTPwo2SHhf2OHKI1BXSjnu+bX+uh/GeO/qDX1PoMVML09YxLFYy41mbtU6JiZ3aSMezYoDdSMNTvLFZXHjsAKcwCnEUHhYNo04dPvbmV2TYoq8QfJEqXi0aDOlkKPAvUeBbyltp9HwFixnKaBdKviyweMoXD+vbX7wopS+lzTwE5kaxwrpslaquqDwYzbzHD3izulq1Mb7KOZcVro2emWvNLTccePginW3xZkrHFDb2ily0tooZteBVzkkIK23yxQ4KHMfOlagP6FG93DjBAAJcSaAVQFFwOfQc85wq2zBcyYAQH1WkTOZnWYS0u2J0Icc/xw29zLhmtnOr4UT8T8DcyFpuaFOyboojkKPKpdRYEctmFRwm7ysIVLy5IpsXhca6dQA0468YfHixzXTAN9GD2X33OeIijpV/O5ljCMlW07fJllECYe/V/x6grt+A9CelJhkieKnKJch+j6lCF/tABga0mY2ZSBFOKX+ttdFGc/MCon/TyNNFEMYjUjUkSYUyA1rZMlRuDe0LQtLU5lXecvihKwhZ0M Nz8Vb0QA TKFZDrJUroNqectuIptpfVavHOkcgyulVT3rf+xbH2U8Q/qTE9YS+7JtAhaT5Bxjtq6nj3nZyzvkTBpHIbALDZeF+91pdxa7vl+zDMr+UAOCs6iWlPgVRYA2i16Hhu3uFaZEGhXKBDyxGXNdovMHw9dRg0mm95zkQRKDc0HfV/J5ErukPy/07cbV/pDS4I5e//HLmZ7XNViQnOijP1Pw2RB3rYDRXQP5RQvWnKX1AmptHycL/2eQPIbup/N6tYYsIDwuvCuwOmvA9VfmHGIGhKhARcjr1RfTX8KesLco7xA2r8V0YrCuF0qUVGw53pTn9z6mLzXEZacEGSXlS+Nfxx/CLJX8GFY/q4rcj/g9Eh8gRFzqVB1p97O02eTVvdmX+H7/GlqATMYBQSH0Q1XZX5kbmF+u3HYG/T/Tq8zqJQF6KMAooakB/21kWqv+g+z0Ysw+kt9XcBP0uSo4= 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: Add self tests for Page Detective, it contains testing of several memory types, and also some negative/bad input tests. Signed-off-by: Pasha Tatashin --- MAINTAINERS | 1 + tools/testing/selftests/Makefile | 1 + .../selftests/page_detective/.gitignore | 1 + .../testing/selftests/page_detective/Makefile | 7 + tools/testing/selftests/page_detective/config | 4 + .../page_detective/page_detective_test.c | 727 ++++++++++++++++++ 6 files changed, 741 insertions(+) create mode 100644 tools/testing/selftests/page_detective/.gitignore create mode 100644 tools/testing/selftests/page_detective/Makefile create mode 100644 tools/testing/selftests/page_detective/config create mode 100644 tools/testing/selftests/page_detective/page_detective_test.c diff --git a/MAINTAINERS b/MAINTAINERS index 654d4650670d..ec09b28776b0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -17456,6 +17456,7 @@ L: linux-kernel@vger.kernel.org S: Maintained F: Documentation/misc-devices/page_detective.rst F: drivers/misc/page_detective.c +F: tools/testing/selftests/page_detective/ PAGE POOL M: Jesper Dangaard Brouer diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 363d031a16f7..9c828025fdfa 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -72,6 +72,7 @@ TARGETS += net/packetdrill TARGETS += net/rds TARGETS += net/tcp_ao TARGETS += nsfs +TARGETS += page_detective TARGETS += perf_events TARGETS += pidfd TARGETS += pid_namespace diff --git a/tools/testing/selftests/page_detective/.gitignore b/tools/testing/selftests/page_detective/.gitignore new file mode 100644 index 000000000000..21a78bee7b4a --- /dev/null +++ b/tools/testing/selftests/page_detective/.gitignore @@ -0,0 +1 @@ +page_detective_test diff --git a/tools/testing/selftests/page_detective/Makefile b/tools/testing/selftests/page_detective/Makefile new file mode 100644 index 000000000000..43c4dccb6a13 --- /dev/null +++ b/tools/testing/selftests/page_detective/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +CFLAGS += -g -Wall + +TEST_GEN_PROGS := page_detective_test + +include ../lib.mk + diff --git a/tools/testing/selftests/page_detective/config b/tools/testing/selftests/page_detective/config new file mode 100644 index 000000000000..ddfeed4ddf13 --- /dev/null +++ b/tools/testing/selftests/page_detective/config @@ -0,0 +1,4 @@ +CONFIG_PAGE_TABLE_CHECK=y +CONFIG_MEMCG=y +CONFIG_TRANSPARENT_HUGEPAGE=y +CONFIG_PAGE_DETECTIVE=y diff --git a/tools/testing/selftests/page_detective/page_detective_test.c b/tools/testing/selftests/page_detective/page_detective_test.c new file mode 100644 index 000000000000..f86cf0fdd8fc --- /dev/null +++ b/tools/testing/selftests/page_detective/page_detective_test.c @@ -0,0 +1,727 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024, Google LLC. + * Pasha Tatashin + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../kselftest.h" + +#define OPT_STR "hpvaAsnHtbBS" +#define HELP_STR \ +"Usage: %s [-h] [-p] [-v] [-a] [-A] [-s] [-n] [-H] [-t] [-b] [-S]\n" \ +"-h\tshow this help\n" \ +"Interfaces:\n" \ +"-p\tphysical address page detective interface\n" \ +"-v\tvirtual address page detective interface\n" \ +"Tests:\n" \ +"-a\ttest anonymous page\n" \ +"-A\ttest anonymous huge page\n" \ +"-s\ttest anonymous shared page\n" \ +"-n\ttest named shared page\n" \ +"-H\ttest HugeTLB shared page\n" \ +"-t\ttest tmpfs page\n" \ +"-b\ttest bad/fail input cases\n" \ +"-S\ttest stack page\n" \ +"If no arguments specified all tests are performed\n" \ + +#define FIRST_LINE_PREFIX "Page Detective: Investigating " +#define LAST_LINE_PREFIX "Page Detective: Finished investigation of " + +#define TMP_FILE "/tmp/page_detective_test.out" + +#define NR_HUGEPAGES "/sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages" + +#define NANO 1000000000ul +#define MICRO 1000000ul +#define MILLI 1000ul +#define BIT(nr) (UL(1) << (nr)) + +#define ARG_INTERFACE_PHYS BIT(0) +#define ARG_INTERFACE_VIRT BIT(1) + +#define ARG_TEST_ANON BIT(2) +#define ARG_TEST_ANON_HUGE BIT(3) +#define ARG_TEST_ANON_SHARED BIT(4) +#define ARG_TEST_NAMED_SHARED BIT(5) +#define ARG_TEST_HUGETLB_SHARED BIT(6) +#define ARG_TEST_TMPFS BIT(7) +#define ARG_TEST_FAIL_CASES BIT(8) +#define ARG_TEST_STACK BIT(9) + +#define ARG_DEFAULT (~0) /* Run verything by default */ + +#define ARG_INTERFACE_MASK (ARG_INTERFACE_PHYS | ARG_INTERFACE_VIRT) +#define ARG_TEST_MASK (~ARG_INTERFACE_MASK) + +#define INTERFACE_NAME(in) (((in) == ARG_INTERFACE_PHYS) ? \ + "/sys/kernel/debug/page_detective/phys" : \ + "/sys/kernel/debug/page_detective/virt") + +#define PAGE_SIZE ((unsigned long)sysconf(_SC_PAGESIZE)) +#define HUGE_PAGE_SIZE (PAGE_SIZE * PAGE_SIZE / sizeof(uint64_t)) + +#ifndef MAP_HUGE_2MB +#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) +#endif + +#ifndef MFD_HUGEPAGE +#define MFD_HUGEPAGE (MFD_GOOGLE_SPECIFIC_BASE << 0) +#endif + +#ifndef MFD_GOOGLE_SPECIFIC_BASE +#define MFD_GOOGLE_SPECIFIC_BASE 0x0200U +#endif + +static int old_dmesg; + +static uint64_t virt_to_phys(uint64_t virt, uint64_t *physp) +{ + uint64_t tbloff, offset, tblen, pfn; + int fd, nr; + + fd = open("/proc/self/pagemap", O_RDONLY); + if (fd < 0) { + ksft_print_msg("%s open(/proc/self/pagemap): %s\n", __func__, + strerror(errno)); + return 1; + } + + /* see: Documentation/admin-guide/mm/pagemap.rst */ + tbloff = virt / PAGE_SIZE * sizeof(uint64_t); + offset = lseek(fd, tbloff, SEEK_SET); + if (offset == (off_t)-1) { + ksft_print_msg("%s lseek: %s\n", __func__, strerror(errno)); + return 1; + } + + if (offset != tbloff) { + ksft_print_msg("%s: cannot find virtual address\n", __func__); + return 1; + } + + nr = read(fd, &tblen, sizeof(uint64_t)); + if (nr != sizeof(uint64_t)) { + ksft_print_msg("%s: read\n", __func__); + return 1; + } + close(fd); + + if (!(tblen & (1ul << 63))) { + ksft_print_msg("%s: present bit is not set\n", __func__); + return 1; + } + + /* Bits 0-54 page frame number (PFN) if present */ + pfn = tblen & 0x7fffffffffffffULL; + + *physp = PAGE_SIZE * pfn | (virt & (PAGE_SIZE - 1)); + + return 0; +} + +static int __phys_test(unsigned long long phys) +{ + char phys_str[128]; + int fd, nr; + + fd = open("/sys/kernel/debug/page_detective/phys", O_WRONLY); + if (fd < 0) { + ksft_print_msg("%s open: %s\n", __func__, strerror(errno)); + return 4; + } + + sprintf(phys_str, "%llu", phys); + + nr = write(fd, phys_str, strlen(phys_str)); + if (nr != strlen(phys_str)) { + ksft_print_msg("%s write failed\n", __func__); + return 1; + } + close(fd); + + return 0; +} + +static int phys_test(char *mem) +{ + uint64_t phys; + + if (virt_to_phys((uint64_t)mem, &phys)) + return 1; + + return __phys_test(phys); +} + +static int __virt_test(int pid, unsigned long virt) +{ + char virt_str[128]; + int fd, nr; + + fd = open("/sys/kernel/debug/page_detective/virt", O_WRONLY); + if (fd < 0) { + ksft_print_msg("%s open: %s\n", __func__, strerror(errno)); + return 4; + } + + sprintf(virt_str, "%d %#lx", pid, virt); + nr = write(fd, virt_str, strlen(virt_str)); + if (nr != strlen(virt_str)) { + ksft_print_msg("%s: write(%s): %s\n", __func__, virt_str, + strerror(errno)); + close(fd); + + return 1; + } + close(fd); + + return 0; +} + +static int virt_test(char *mem) +{ + return __virt_test(getpid(), (unsigned long)mem); +} + +static int test_anon(int in) +{ + char *mem; + int rv; + + mem = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (mem == MAP_FAILED) { + ksft_print_msg("%s mmap: %s\n", __func__, strerror(errno)); + return 1; + } + + if (madvise(mem, PAGE_SIZE, MADV_NOHUGEPAGE)) { + ksft_print_msg("%s madvise: %s\n", __func__, strerror(errno)); + return 1; + } + + mem[0] = 0; + + if (in == ARG_INTERFACE_PHYS) + rv = phys_test(mem); + else + rv = virt_test(mem); + + munmap(mem, PAGE_SIZE); + + return rv; +} + +static int test_anon_huge(int in) +{ + uint64_t i; + char *mem; + int rv; + + mem = mmap(NULL, HUGE_PAGE_SIZE * 8, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + if (mem == MAP_FAILED) { + ksft_print_msg("%s mmap: %s\n", __func__, strerror(errno)); + return 1; + } + + if (madvise(mem, HUGE_PAGE_SIZE * 8, MADV_HUGEPAGE)) { + ksft_print_msg("%s madvise: %s\n", __func__, strerror(errno)); + return 1; + } + + /* Fault huge pages */ + for (i = 0; i < HUGE_PAGE_SIZE * 8; i += HUGE_PAGE_SIZE) + mem[i] = 0; + + /* In case huge pages were not used for some reason */ + mem[HUGE_PAGE_SIZE * 7 + 101 * PAGE_SIZE] = 0; + + if (in == ARG_INTERFACE_PHYS) + rv = phys_test(mem + HUGE_PAGE_SIZE * 7 + 101 * PAGE_SIZE); + else + rv = virt_test(mem + HUGE_PAGE_SIZE * 7 + 101 * PAGE_SIZE); + + munmap(mem, HUGE_PAGE_SIZE * 8); + + return rv; +} + +static int test_anon_shared(int in) +{ + char *mem; + int rv; + + mem = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, -1, 0); + if (mem == MAP_FAILED) { + ksft_print_msg("%s mmap: %s\n", __func__, strerror(errno)); + return 1; + } + + if (madvise(mem, PAGE_SIZE, MADV_NOHUGEPAGE)) { + ksft_print_msg("%s madvise: %s\n", __func__, strerror(errno)); + return 1; + } + + mem[0] = 0; + + if (in == ARG_INTERFACE_PHYS) + rv = phys_test(mem); + else + rv = virt_test(mem); + + munmap(mem, PAGE_SIZE); + + return rv; +} + +static int test_named_shared(int in) +{ + char *mem; + int rv; + + mem = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, -1, 0); + if (mem == MAP_FAILED) { + ksft_print_msg("%s mmap: %s\n", __func__, strerror(errno)); + return 1; + } + + if (madvise(mem, PAGE_SIZE, MADV_NOHUGEPAGE)) { + ksft_print_msg("%s madvise: %s\n", __func__, strerror(errno)); + return 1; + } + + mem[0] = 0; + + if (in == ARG_INTERFACE_PHYS) + rv = phys_test(mem); + else + rv = virt_test(mem); + + munmap(mem, PAGE_SIZE); + + return rv; +} + +static int test_hugetlb_shared(int in) +{ + char hugepg_add_cmd[256], hugepg_rm_cmd[256]; + unsigned long nr_hugepages; + char *mem; + FILE *f; + int rv; + + f = fopen(NR_HUGEPAGES, "r"); + if (!f) { + ksft_print_msg("%s fopen: %s\n", __func__, strerror(errno)); + return 4; + } + + fscanf(f, "%lu", &nr_hugepages); + fclose(f); + sprintf(hugepg_add_cmd, "echo %lu > " NR_HUGEPAGES, nr_hugepages + 1); + sprintf(hugepg_rm_cmd, "echo %lu > " NR_HUGEPAGES, nr_hugepages); + + if (system(hugepg_add_cmd)) { + ksft_print_msg("%s system(hugepg_add_cmd): %s\n", __func__, + strerror(errno)); + return 4; + } + + mem = mmap(NULL, HUGE_PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_HUGETLB | MAP_HUGE_2MB | MAP_ANONYMOUS | MAP_SHARED, + -1, 0); + if (mem == MAP_FAILED) { + ksft_print_msg("%s mmap: %s\n", __func__, strerror(errno)); + return 1; + } + + mem[0] = 0; + + if (in == ARG_INTERFACE_PHYS) + rv = phys_test(mem); + else + rv = virt_test(mem); + + munmap(mem, HUGE_PAGE_SIZE); + + if (system(hugepg_rm_cmd)) { + ksft_print_msg("%s system(hugepg_rm_cmd): %s\n", __func__, + strerror(errno)); + return 1; + } + + return rv; +} + +static int test_tmpfs(int in) +{ + char *mem; + int fd; + int rv; + + fd = memfd_create("tmpfs_page", + MFD_CLOEXEC | MFD_ALLOW_SEALING); + if (fd < 0) { + ksft_print_msg("%s memfd_create: %s\n", __func__, + strerror(errno)); + return 1; + } + + if (ftruncate(fd, PAGE_SIZE) == -1) { + ksft_print_msg("%s ftruncate: %s\n", __func__, strerror(errno)); + return 1; + } + + mem = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + if (mem == MAP_FAILED) { + ksft_print_msg("%s mmap: %s\n", __func__, strerror(errno)); + return 1; + } + + mem[0] = 0; + + if (in == ARG_INTERFACE_PHYS) + rv = phys_test(mem); + else + rv = virt_test(mem); + + munmap(mem, PAGE_SIZE); + close(fd); + + return rv; +} + +static int test_stack(int in) +{ + char *mem = alloca(PAGE_SIZE); + int rv; + + mem[0] = 0; + if (in == ARG_INTERFACE_PHYS) + rv = phys_test(mem); + else + rv = virt_test(mem); + + return rv; +} + +static int test_bad_phys(void) +{ + int rv; + + rv = __phys_test(0); + if (rv) + return rv; + + rv = __phys_test(1); + if (rv) + return rv; + + rv = __phys_test(~0); + + return rv; +} + +static int test_bad_virt(void) +{ + int rv; + + rv = __virt_test(0, 0); + if (rv == 4) + return rv; + + if (!rv) { + ksft_print_msg("%s: write(0, 0) did not fail\n", __func__); + return 1; + } + + if (!__virt_test(0, -1)) { + ksft_print_msg("%s: write(0, -1) did not fail\n", __func__); + return 1; + } + + if (!__virt_test(0, -1)) { + ksft_print_msg("%s: write(0, -1) did not fail\n", __func__); + return 1; + } + + if (!__virt_test(-1, 0)) { + ksft_print_msg("%s: write(-1, 0) did not fail\n", __func__); + return 1; + } + + return 0; +} + +static int test_fail_cases(int in) +{ + if (in == ARG_INTERFACE_VIRT) + return test_bad_virt(); + else + return test_bad_phys(); +} + +/* Return time in nanosecond since epoch */ +static uint64_t gethrtime(void) +{ + struct timespec ts; + + clock_gettime(CLOCK_REALTIME, &ts); + + return (ts.tv_sec * NANO) + ts.tv_nsec; +} + +static int sanity_check_fail_cases(int in, int test_ttpe, FILE *f) +{ + char *line; + size_t len; + ssize_t nr; + + line = NULL; + len = 0; + while ((nr = getline(&line, &len, f)) != -1) { + char *l = strchr(line, ']') + 2; /* skip time stamp */ + + if (l == (char *)2) + continue; + + ksft_print_msg("%s", l); + } + + free(line); + + return 0; +} + +static int sanity_check_test_result(int in, int test_type, uint64_t start) +{ + uint64_t end = gethrtime() + NANO; + char dmesg[256], *line; + int first_line, last_line; + size_t len; + ssize_t nr; + FILE *f; + + sprintf(dmesg, "dmesg --since=@%ld.%06ld --until=@%ld.%06ld > " + TMP_FILE, start / NANO, (start / MILLI) % MICRO, end / NANO, + (end / MILLI) % MICRO); + + if (old_dmesg) + system("dmesg > " TMP_FILE); + else + system(dmesg); + f = fopen(TMP_FILE, "r"); + if (!f) { + ksft_print_msg("%s: %s", __func__, strerror(errno)); + return 1; + } + + if (test_type == ARG_TEST_FAIL_CASES) { + sanity_check_fail_cases(in, test_type, f); + fclose(f); + unlink(TMP_FILE); + return 0; + } + + line = NULL; + len = 0; + first_line = 0; + last_line = 0; + while ((nr = getline(&line, &len, f)) != -1) { + char *l = strchr(line, ']') + 2; /* skip time stamp */ + + if (l == (char *)2) + continue; + + if (!first_line) { + first_line = !strncmp(l, FIRST_LINE_PREFIX, + strlen(FIRST_LINE_PREFIX)); + } else if (!last_line) { + last_line = !strncmp(l, LAST_LINE_PREFIX, + strlen(LAST_LINE_PREFIX)); + if (last_line) + ksft_print_msg("%s", l); + } + + /* + * Output everything between the first and last line of page + * detective output + */ + if (first_line && !last_line) + ksft_print_msg("%s", l); + } + ksft_print_msg("\n"); + + free(line); + fclose(f); + unlink(TMP_FILE); + + if (!first_line) { + ksft_print_msg("Test failed, bad first line\n"); + return 1; + } + if (!last_line) { + ksft_print_msg("Test failed, bad last line\n"); + return 1; + } + + return 0; +} + +/* + * interface ARG_INTERFACE_VIRT or ARG_INTERFACE_PHYS + * test_arg one of the ARG_TEST_* + * test_f function for this test + * arg the provided user arguments. + * + * Run the test using the provided interface if it is requested interface arg. + */ +#define TEST(interface, test_type, test_f, arg) \ + do { \ + int __in = (interface); \ + int __tt = (test_type); \ + int __rv; \ + \ + if ((arg) & __tt) { \ + uint64_t start = gethrtime(); \ + \ + if (old_dmesg) \ + system("dmesg -C"); \ + else \ + usleep(100000); \ + \ + __rv = test_f(__in); \ + if (__rv == 4) { \ + ksft_test_result_skip(#test_f " via [%s]\n", \ + INTERFACE_NAME(__in)); \ + break; \ + } \ + \ + if (__rv) { \ + ksft_test_result_fail(#test_f " via [%s]\n", \ + INTERFACE_NAME(__in)); \ + break; \ + } \ + \ + if (sanity_check_test_result(__in, __tt, \ + start)) { \ + ksft_test_result_fail(#test_f " via [%s]\n", \ + INTERFACE_NAME(__in)); \ + break; \ + } \ + ksft_test_result_pass(#test_f " via [%s]\n", \ + INTERFACE_NAME(__in)); \ + } \ + } while (0) + +static void run_tests(int in, int arg) +{ + if (in & arg) { + TEST(in, ARG_TEST_ANON, test_anon, arg); + TEST(in, ARG_TEST_ANON_HUGE, test_anon_huge, arg); + TEST(in, ARG_TEST_ANON_SHARED, test_anon_shared, arg); + TEST(in, ARG_TEST_NAMED_SHARED, test_named_shared, arg); + TEST(in, ARG_TEST_HUGETLB_SHARED, test_hugetlb_shared, arg); + TEST(in, ARG_TEST_TMPFS, test_tmpfs, arg); + TEST(in, ARG_TEST_STACK, test_stack, arg); + TEST(in, ARG_TEST_FAIL_CASES, test_fail_cases, arg); + } +} + +static int count_tests(int in, int arg) +{ + int tests = 0; + + if (in & arg) { + tests += (arg & ARG_TEST_ANON) ? 1 : 0; + tests += (arg & ARG_TEST_ANON_HUGE) ? 1 : 0; + tests += (arg & ARG_TEST_ANON_SHARED) ? 1 : 0; + tests += (arg & ARG_TEST_NAMED_SHARED) ? 1 : 0; + tests += (arg & ARG_TEST_HUGETLB_SHARED) ? 1 : 0; + tests += (arg & ARG_TEST_TMPFS) ? 1 : 0; + tests += (arg & ARG_TEST_STACK) ? 1 : 0; + tests += (arg & ARG_TEST_FAIL_CASES) ? 1 : 0; + } + + return tests; +} + +int main(int argc, char **argv) +{ + int arg = 0; + int opt; + + while ((opt = getopt(argc, argv, OPT_STR)) != -1) { + switch (opt) { + case 'h': + printf(HELP_STR, argv[0]); + exit(EXIT_SUCCESS); + case 'v': + arg |= ARG_INTERFACE_VIRT; + break; + case 'p': + arg |= ARG_INTERFACE_PHYS; + break; + case 'a': + arg |= ARG_TEST_ANON; + break; + case 'A': + arg |= ARG_TEST_ANON_HUGE; + break; + case 's': + arg |= ARG_TEST_ANON_SHARED; + break; + case 'n': + arg |= ARG_TEST_NAMED_SHARED; + break; + case 'H': + arg |= ARG_TEST_HUGETLB_SHARED; + break; + case 't': + arg |= ARG_TEST_TMPFS; + break; + case 'S': + arg |= ARG_TEST_STACK; + break; + case 'b': + arg |= ARG_TEST_FAIL_CASES; + break; + default: + errx(EXIT_FAILURE, HELP_STR, argv[0]); + } + } + + if (arg == 0) + arg = ARG_DEFAULT; + if (!(arg & ARG_INTERFACE_MASK)) + errx(EXIT_FAILURE, "No page detective interface specified"); + + if (!(arg & ARG_TEST_MASK)) + errx(EXIT_FAILURE, "No tests specified"); + + /* Return 1 when dmesg does not have --since and --until arguments */ + old_dmesg = system("dmesg --since @0 > /dev/null 2>&1"); + + ksft_print_header(); + ksft_set_plan(count_tests(ARG_INTERFACE_VIRT, arg) + + count_tests(ARG_INTERFACE_PHYS, arg)); + + run_tests(ARG_INTERFACE_VIRT, arg); + run_tests(ARG_INTERFACE_PHYS, arg); + ksft_finished(); +}