From patchwork Mon Jul 22 16:29:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Danilo Krummrich X-Patchwork-Id: 13738939 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 AEB11C3DA5D for ; Mon, 22 Jul 2024 16:31:56 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 344D26B0089; Mon, 22 Jul 2024 12:31:56 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 2CD3D6B008A; Mon, 22 Jul 2024 12:31:56 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 178156B008C; Mon, 22 Jul 2024 12:31:56 -0400 (EDT) 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 E95B76B0089 for ; Mon, 22 Jul 2024 12:31:55 -0400 (EDT) Received: from smtpin10.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id 2DA39C14F2 for ; Mon, 22 Jul 2024 16:31:55 +0000 (UTC) X-FDA: 82367930190.10.B3812A4 Received: from sin.source.kernel.org (sin.source.kernel.org [145.40.73.55]) by imf20.hostedemail.com (Postfix) with ESMTP id CFB291C002E for ; Mon, 22 Jul 2024 16:31:52 +0000 (UTC) Authentication-Results: imf20.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=apt6UI3X; spf=pass (imf20.hostedemail.com: domain of dakr@kernel.org designates 145.40.73.55 as permitted sender) smtp.mailfrom=dakr@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=1721665852; 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=lG3/KAkEApsl6UplgKKObpNoWCqOzKPnf5F+fwNa6uQ=; b=Ci56CS5cwIRj7JIfOIKAPUQ6ZtgH0CBkOtnLa5kdFqi4QhkdsSOB2sghJ+9WJOG0bNzaAZ 9GJh84OSMZFUbG43w5yldQCpvP+Zry+WRRVYmBC/nOfgrIbOpVo8iEys3Hv2NgTIjkcSMc 1q8RgcwQyy86NOII38WJkIupsLFLH1E= ARC-Authentication-Results: i=1; imf20.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=apt6UI3X; spf=pass (imf20.hostedemail.com: domain of dakr@kernel.org designates 145.40.73.55 as permitted sender) smtp.mailfrom=dakr@kernel.org; dmarc=pass (policy=none) header.from=kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1721665852; a=rsa-sha256; cv=none; b=z4vrg/lwz1Qir5o5u/bniCz0eZqLi3MgjzCIGUY4dbdxyCFPK4pY3ldSHEAvZ9ncT5ZZaL t27402e9Bk+SHLjX5G9x/DhCIjsYOkE7dKC6jduVMNnkWOScbmsO6zXu32ZM/MK/HLgckJ XnUtb2q5SZK9eGqOeM1B1E21QmRBT60= Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by sin.source.kernel.org (Postfix) with ESMTP id ACB2CCE0B9A; Mon, 22 Jul 2024 16:31:48 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4D35FC116B1; Mon, 22 Jul 2024 16:31:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721665907; bh=8R5zLx4UelCLfyVht0GJQcdBO0xBkZadv109mekdLLM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=apt6UI3XCpX9famE1RKBq9IxyCaLlbsuNOSSSCetsAo3Ccd6iOmtq2aw/OEgdOV9N yjQK039V0lwMuJluAOKh85GkhNES/hTRB0foU7Qehnd/Isq1dimaVRxVwrvW/PWWH+ g7kjlZ80Xul72QYxRUdKzhYUIht4L8LHGblAOAaA49j6k8iDQ0lE9BviAU8AWExbmp WpWO1NsmDthK2QhGzYIXLmYOJnRvTfIiqXEyNjkPEV/vyaW9nztTV4PoiXDtsAQYI6 BAlHaRVGQFEmdywmM7vomRsNKZWfD3HuRwIyfFlx/gqo+iwJVqIu0u8PfxpYGe6fxG RUdnzyypKuRog== From: Danilo Krummrich To: cl@linux.com, penberg@kernel.org, rientjes@google.com, iamjoonsoo.kim@lge.com, akpm@linux-foundation.org, vbabka@suse.cz, roman.gushchin@linux.dev, 42.hyeyoo@gmail.com, urezki@gmail.com, hch@infradead.org, kees@kernel.org, ojeda@kernel.org, wedsonaf@gmail.com, mhocko@kernel.org, mpe@ellerman.id.au, chandan.babu@oracle.com, christian.koenig@amd.com, maz@kernel.org, oliver.upton@linux.dev Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, rust-for-linux@vger.kernel.org, Danilo Krummrich Subject: [PATCH v2 1/2] mm: vmalloc: implement vrealloc() Date: Mon, 22 Jul 2024 18:29:23 +0200 Message-ID: <20240722163111.4766-2-dakr@kernel.org> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240722163111.4766-1-dakr@kernel.org> References: <20240722163111.4766-1-dakr@kernel.org> MIME-Version: 1.0 X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: CFB291C002E X-Stat-Signature: y3iaobodmmqabho8rpght6aq9e8ktgf7 X-Rspam-User: X-HE-Tag: 1721665912-783444 X-HE-Meta: U2FsdGVkX18Io3wGjkgqMuGDcCMZhNQ4I1qh80qVnPxNX1B8ADQfGUJf6di092ZfuJuXun9U/08NA2mtNWw8WgD7ITSBARMMN0vZUKxG6826+mvqLmc4v847lyZXXp/hJ/hQ60j2YSSD1rwfY9EmZgDG9rbtQPc3+k5iGXT7sOr4z+uIhmqplUyJhgXGtJMDaEJkMR0ycldOmjLqNu1rctazmXNAHgi5+V+KEXH0R3d27qj2LJ4DxcrxCfeN47MoQs3h/RkBe2zwc+XBzRusdIVXN/YKxNYzn0JL/6rgBCnP7t2CRxPn3UPOiAPvVpalTEhMuW7RKRKDrkIIr+x1H27nwOp2KvpV3pQKAQLNkXt5iN856Dma2XGksE1i70MRY8S879zSN093TrTRUur4ToCpGjWCaCr2g6aVwlGjuOzXsyue1/hWGiKytXBRcVxoKghM55XRclhw4c5p1z7gzDPwoNkV4UrHpUnj6q7XurTfjE7FcjVN6YH9vy5mHgUYTVXuDv84J2AbVvPd0Ji1asOQUkjYyUWsWNkscnH6gy9MWfbp272FsC5IX+Fr6PZrWl1gu/eupZBqcn5lhldrHCUtepy2Zu73MhlNauwlz8fpBBBdVRsmRchbGAT09s01DFW0qQAVdmC1EJhDyI0YvJLaofrPW2gjhsBJjC1z2hGbz/yGpfHwxYL6mL2RysfMtk+8He3tN2A/uWZayH9J7KLZFV/64zJeeiA1LAzY4udFjAwkWMh4wziN5bJv4LM864eLLxmkAdbUxJit74GSjAIjJZ2LlCUVx1K9/rdCYUhsO6B0c+4+2wDDBC3yljSVLSgI/4iEg3aWUk2vl/7rHD02VCEvxwfSVxco9hlWlET2C1ZIPh8h8LdhXZJ3Cijc0lKVV3fBej89tLselCR701omTa5RjGMWXIY3FA4MDOgJH2ab5eVLwAnqP6iVbHsuhpzFrroKbzoH8zuLWo0 EcXgQVJi b17qHnWjLLPrsEwDnMvWvYT8W3d4yvbai5J7chr8aV/Mo65wzHtfcw6flT9WGzmnz7UuRldMrfg1SRl0veA0T2vhvVPoDDKz0ZSi/nbvupg/RFbj+VVgEQgpjW2nURQy73JYMD42R0SpFFng1GSCj286Q5iZvzsgeYFOaqEwFPjQaqEh+mdd6wCeQkfYA7YWSOcjAuiBJJqQizWDWo90TqBmUGFmqe5qhxTF4NfcXLJSIcHNJeMF4CqaD7g9JS9hQwk7AM3V9h0A6VZ6yoz7NM0CN5XST1mNeDLYkZPVc4pNt3+n5FxCLsuz18A== 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: Implement vrealloc() analogous to krealloc(). Currently, krealloc() requires the caller to pass the size of the previous memory allocation, which, instead, should be self-contained. We attempt to fix this in a subsequent patch which, in order to do so, requires vrealloc(). Besides that, we need realloc() functions for kernel allocators in Rust too. With `Vec` or `KVec` respectively, potentially growing (and shrinking) data structures are rather common. Signed-off-by: Danilo Krummrich Acked-by: Vlastimil Babka --- include/linux/vmalloc.h | 4 +++ mm/vmalloc.c | 59 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index e4a631ec430b..ad2ce7a6ab7a 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -189,6 +189,10 @@ extern void *__vcalloc_noprof(size_t n, size_t size, gfp_t flags) __alloc_size(1 extern void *vcalloc_noprof(size_t n, size_t size) __alloc_size(1, 2); #define vcalloc(...) alloc_hooks(vcalloc_noprof(__VA_ARGS__)) +void * __must_check vrealloc_noprof(const void *p, size_t size, gfp_t flags) + __realloc_size(2); +#define vrealloc(...) alloc_hooks(vrealloc_noprof(__VA_ARGS__)) + extern void vfree(const void *addr); extern void vfree_atomic(const void *addr); diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 6b783baf12a1..caf032f0bd69 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c @@ -4037,6 +4037,65 @@ void *vzalloc_node_noprof(unsigned long size, int node) } EXPORT_SYMBOL(vzalloc_node_noprof); +/** + * vrealloc - reallocate virtually contiguous memory; contents remain unchanged + * @p: object to reallocate memory for + * @size: the size to reallocate + * @flags: the flags for the page level allocator + * + * The contents of the object pointed to are preserved up to the lesser of the + * new and old size (__GFP_ZERO flag is effectively ignored). + * + * If @p is %NULL, vrealloc() behaves exactly like vmalloc(). If @size is 0 and + * @p is not a %NULL pointer, the object pointed to is freed. + * + * Return: pointer to the allocated memory; %NULL if @size is zero or in case of + * failure + */ +void *vrealloc_noprof(const void *p, size_t size, gfp_t flags) +{ + size_t old_size = 0; + void *n; + + if (!size) { + vfree(p); + return NULL; + } + + if (p) { + struct vm_struct *vm; + + vm = find_vm_area(p); + if (unlikely(!vm)) { + WARN(1, "Trying to vrealloc() nonexistent vm area (%p)\n", p); + return NULL; + } + + old_size = get_vm_area_size(vm); + } + + if (size <= old_size) { + /* + * TODO: Shrink the vm_area, i.e. unmap and free unused pages. + * What would be a good heuristic for when to shrink the + * vm_area? + */ + return (void *)p; + } + + /* TODO: Grow the vm_area, i.e. allocate and map additional pages. */ + n = __vmalloc_noprof(size, flags); + if (!n) + return NULL; + + if (p) { + memcpy(n, p, old_size); + vfree(p); + } + + return n; +} + #if defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA32) #define GFP_VMALLOC32 (GFP_DMA32 | GFP_KERNEL) #elif defined(CONFIG_64BIT) && defined(CONFIG_ZONE_DMA)