From patchwork Wed Aug 14 18:54:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrii Nakryiko X-Patchwork-Id: 13763841 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 64F28C531DC for ; Wed, 14 Aug 2024 18:54:47 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id EEDED6B009A; Wed, 14 Aug 2024 14:54:46 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id E9FB26B009B; Wed, 14 Aug 2024 14:54:46 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id CA43C6B009C; Wed, 14 Aug 2024 14:54:46 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 9E3646B009A for ; Wed, 14 Aug 2024 14:54:46 -0400 (EDT) Received: from smtpin20.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 4E9FF1C45C0 for ; Wed, 14 Aug 2024 18:54:46 +0000 (UTC) X-FDA: 82451752572.20.2A20BCE Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by imf20.hostedemail.com (Postfix) with ESMTP id 08C921C000B for ; Wed, 14 Aug 2024 18:54:43 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=QFfhQ2kE; spf=pass (imf20.hostedemail.com: domain of andrii@kernel.org designates 145.40.73.55 as permitted sender) smtp.mailfrom=andrii@kernel.org; dmarc=pass (policy=none) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1723661672; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=MUs/x7lpqmbg6sstR6+AtoRBucJ7haabJ3JekNIs3Pg=; b=rhUIQ4OtiATabN2KlG+hGMpEwu6Hd8zjikhOIwy0pO9P0987iyC+YnOAqieDXnEaSWIhyZ iteb/dha7Mj4F1TgLmhfLF1o123X1iNS42tD8/SbPEFDFkma0a0QqQ1zBaUpCSUjkcZ5mv XwR+higqOrpP8ak2Ozu1zi+R+ykxswQ= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=QFfhQ2kE; spf=pass (imf20.hostedemail.com: domain of andrii@kernel.org designates 145.40.73.55 as permitted sender) smtp.mailfrom=andrii@kernel.org; dmarc=pass (policy=none) header.from=kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1723661672; a=rsa-sha256; cv=none; b=TryIXZjxwY3O32YyfykaCU0e1LBIR/D4S1dLcBB4lO5lkcSXQdlV6NS2u858zLPXhHWhd4 YUio2e5WkxW4pYScFMxVr8w884nGOZPpEdVMskmrs6MA3WFeS1EMpQa2lss3MfnowWe3Sy foASqtSAewywNJ+/nDG11SZ3/SK6WJo= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id 352CCCE1ADF; Wed, 14 Aug 2024 18:54:41 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9C4D6C4AF09; Wed, 14 Aug 2024 18:54:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1723661680; bh=xupJ424Tw41nEe7GfCN7i5gyQGldYzv2WcV+UpjPy8M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QFfhQ2kEKCp0C9ynVtGldcKgIAZORCu9yY50B70ZwdJFLN1XH6Lczqb+WFkflGP7z 5SNUAsF70zUrZXum57h2b5NxeExP70e16C/aR+inDFIRh6NRKUIz9SjbZBN23xc23C QHRkYWf+Ab0BXna1CEnI/HVcO1lcWoQ7eyy0CQzYNZ/HvezGtw7WzeiUuaQ5m0h9OW h6mKBpLDmBePTdb2o9PBOVcsTABzVEYJhnj+E7XSz/o0ssCjrIPbZZqIi+CGUrpGZw Li7O9VNEYcqgXrOBvtZGgFbZ6c1f0dgchN8wGMU5R1ufxzBeiWLd9MDSdfUXZOi5yy zn8Wg2oAThXqA== From: Andrii Nakryiko To: bpf@vger.kernel.org Cc: linux-mm@kvack.org, akpm@linux-foundation.org, adobriyan@gmail.com, shakeel.butt@linux.dev, hannes@cmpxchg.org, ak@linux.intel.com, osandov@osandov.com, song@kernel.org, jannh@google.com, linux-fsdevel@vger.kernel.org, willy@infradead.org, Andrii Nakryiko , Omar Sandoval Subject: [PATCH v6 bpf-next 06/10] lib/buildid: implement sleepable build_id_parse() API Date: Wed, 14 Aug 2024 11:54:13 -0700 Message-ID: <20240814185417.1171430-7-andrii@kernel.org> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20240814185417.1171430-1-andrii@kernel.org> References: <20240814185417.1171430-1-andrii@kernel.org> MIME-Version: 1.0 X-Rspam-User: X-Stat-Signature: wrhgc379dxkd1uczmbjgd7o6w3rykk9t X-Rspamd-Queue-Id: 08C921C000B X-Rspamd-Server: rspam11 X-HE-Tag: 1723661683-840798 X-HE-Meta: U2FsdGVkX18nndFrn2kE+EFd43pushx4/no+kQSGlkbQIIgCHhBmyjRw3T/9FKGUhwf6UcUJQN2JALWxRv27iOH/RQVjpFfKyNllJVnnmxt6QGMAM1EBnphoPilb1nn2BaoMA+FbGl98qhGVzvOl5QIbzrh6vxG6nG+hoK/IFIBMHO91sr84IdSj/fQrIhVoLWEdSpIAhHVyGGtHSOmUOBs8a17kBT1U/izaV7FCrjMGH/o96xMS3FuJ7WMgXJTEQbpX8NxH5L8XoySG9a8JgiiYdljA8zbrf1nOfVzyKUGbhC8qVZxl8uw0fvCFZVu6qvMDBWwww0QTPBapF34+sYJXBkJF6nBtLT42xQsdHFcNegAnqxn3++Twjb5XadcLjRJUkVDnlKR+Drcgwyscjhbg/7dBQHXrd77f6HSrLxUPbd4X5dzXD/seyw9LoJAWZxR1VGP/NbYfspnN8+I41tAC2h3IaUhDwK+3r/DBHgDsLDCEnuA2llRFDQGZ3fRI3txqCndEy1Yw0fB2D1DOOxNZGCj2Og0w1nZvyFbh6mNIbsDokwEWLFxTgZ3avgmGFTApDu7VckW0+T7U2D9Ph2+B7TxDQsTRUKN7cYfmauHGivRf/bBQAOE60ypsSGE4+VCRng9oshunQPD08g6k7p1C4ykWsrTz88NPHDI7pPLeDcnb8UzKotcSBYXNoKke3oicEqutuHs3lOzfZ/eRBSh9sNDnM+Guha5qAKCg94/BVzK38+J6IHK6POgKb1koXYhZ0jisV25Q5W1ut0Qdimu2yXN3a8NicyxS8Ze5vKKrE+rwceTVFtDF8sHSHR6xpzFJokEmKycOqapTMCjAp/IppTfGDVMsKeK9r/PyPS9amm+sIDQyz8IGVr+N4k9G8sKZMda61IoVCnWsKHwXNGv1NHLgOVEundQlC7Q3vKSXIrNly1mVPm1T+zlyE7ltsq/zTEmNenb75iWCRMh bWuQg98I eIpDyEU3CzNo+A2ccJOJ7ruWt5XyKkAeHifkyDMJsKdUGTQe/+gw6f5YA3HSdeHeZA6uLx//K1PhL3yhLKHaVGWM7nIJxlNmCmRj6Bdf04pyFOaql6MiJZ9/vzQjGI0MVFb6Oc/TbzyZjxc+ao/Z58Shsp8QWXEO1hGBGiwSTNOqhVoPpN6VfGdrNCEkF9D8pzNLpgVDP2SQ3/Y73BS8OA0zZoBaEJ4TGaaBNsyO+PvPog80KoVx6ilajmzZp4+IJXt/Dyu1rclRvpHYm65a5lxppAbU5nCFIUdcAiOzjmAymqKxLODKLeH86i2eO/XfBiMTBGFRqRhISbYgVcdFqLuIFl7fgBeQEIavSTvUqthcPILpC/nPQ4taLMy1vLoqwnKP6TD6OafsLBGTed/jlwa7QDg== 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: Extend freader with a flag specifying whether it's OK to cause page fault to fetch file data that is not already physically present in memory. With this, it's now easy to wait for data if the caller is running in sleepable (faultable) context. We utilize read_cache_folio() to bring the desired folio into page cache, after which the rest of the logic works just the same at folio level. Suggested-by: Omar Sandoval Cc: Shakeel Butt Cc: Johannes Weiner Reviewed-by: Shakeel Butt Signed-off-by: Andrii Nakryiko --- lib/buildid.c | 52 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/lib/buildid.c b/lib/buildid.c index c1cbd34f3685..5da5a32a1af8 100644 --- a/lib/buildid.c +++ b/lib/buildid.c @@ -16,10 +16,11 @@ struct freader { int err; union { struct { - struct address_space *mapping; + struct file *file; struct folio *folio; void *addr; loff_t folio_off; + bool may_fault; }; struct { const char *data; @@ -29,12 +30,13 @@ struct freader { }; static void freader_init_from_file(struct freader *r, void *buf, u32 buf_sz, - struct address_space *mapping) + struct file *file, bool may_fault) { memset(r, 0, sizeof(*r)); r->buf = buf; r->buf_sz = buf_sz; - r->mapping = mapping; + r->file = file; + r->may_fault = may_fault; } static void freader_init_from_mem(struct freader *r, const char *data, u64 data_sz) @@ -62,7 +64,14 @@ static int freader_get_folio(struct freader *r, loff_t file_off) freader_put_folio(r); - r->folio = filemap_get_folio(r->mapping, file_off >> PAGE_SHIFT); + r->folio = filemap_get_folio(r->file->f_mapping, file_off >> PAGE_SHIFT); + + /* if sleeping is allowed, wait for the page, if necessary */ + if (r->may_fault && (IS_ERR(r->folio) || !folio_test_uptodate(r->folio))) { + r->folio = read_cache_folio(r->file->f_mapping, file_off >> PAGE_SHIFT, + NULL, r->file); + } + if (IS_ERR(r->folio) || !folio_test_uptodate(r->folio)) { if (!IS_ERR(r->folio)) folio_put(r->folio); @@ -287,18 +296,8 @@ static int get_build_id_64(struct freader *r, unsigned char *build_id, __u32 *si /* enough for Elf64_Ehdr, Elf64_Phdr, and all the smaller requests */ #define MAX_FREADER_BUF_SZ 64 -/* - * Parse build ID of ELF file mapped to vma - * @vma: vma object - * @build_id: buffer to store build id, at least BUILD_ID_SIZE long - * @size: returns actual build id size in case of success - * - * Assumes no page fault can be taken, so if relevant portions of ELF file are - * not already paged in, fetching of build ID fails. - * - * Return: 0 on success; negative error, otherwise - */ -int build_id_parse_nofault(struct vm_area_struct *vma, unsigned char *build_id, __u32 *size) +static int __build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, + __u32 *size, bool may_fault) { const Elf32_Ehdr *ehdr; struct freader r; @@ -309,7 +308,7 @@ int build_id_parse_nofault(struct vm_area_struct *vma, unsigned char *build_id, if (!vma->vm_file) return -EINVAL; - freader_init_from_file(&r, buf, sizeof(buf), vma->vm_file->f_mapping); + freader_init_from_file(&r, buf, sizeof(buf), vma->vm_file, may_fault); /* fetch first 18 bytes of ELF header for checks */ ehdr = freader_fetch(&r, 0, offsetofend(Elf32_Ehdr, e_type)); @@ -337,6 +336,22 @@ int build_id_parse_nofault(struct vm_area_struct *vma, unsigned char *build_id, return ret; } +/* + * Parse build ID of ELF file mapped to vma + * @vma: vma object + * @build_id: buffer to store build id, at least BUILD_ID_SIZE long + * @size: returns actual build id size in case of success + * + * Assumes no page fault can be taken, so if relevant portions of ELF file are + * not already paged in, fetching of build ID fails. + * + * Return: 0 on success; negative error, otherwise + */ +int build_id_parse_nofault(struct vm_area_struct *vma, unsigned char *build_id, __u32 *size) +{ + return __build_id_parse(vma, build_id, size, false /* !may_fault */); +} + /* * Parse build ID of ELF file mapped to VMA * @vma: vma object @@ -350,8 +365,7 @@ int build_id_parse_nofault(struct vm_area_struct *vma, unsigned char *build_id, */ int build_id_parse(struct vm_area_struct *vma, unsigned char *build_id, __u32 *size) { - /* fallback to non-faultable version for now */ - return build_id_parse_nofault(vma, build_id, size); + return __build_id_parse(vma, build_id, size, true /* may_fault */); } /**