From patchwork Tue Oct 1 15:00:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Danilo Krummrich X-Patchwork-Id: 13818244 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 5120ECEACD5 for ; Tue, 1 Oct 2024 15:02:35 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id DAF0A68001C; Tue, 1 Oct 2024 11:02:34 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id D5C2C280068; Tue, 1 Oct 2024 11:02:34 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id C23B168001C; Tue, 1 Oct 2024 11:02:34 -0400 (EDT) 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 A218C280068 for ; Tue, 1 Oct 2024 11:02:34 -0400 (EDT) Received: from smtpin09.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 543871A15D8 for ; Tue, 1 Oct 2024 15:02:34 +0000 (UTC) X-FDA: 82625349828.09.D69AB38 Received: from nyc.source.kernel.org (nyc.source.kernel.org [147.75.193.91]) by imf13.hostedemail.com (Postfix) with ESMTP id A5E7520013 for ; Tue, 1 Oct 2024 15:02:32 +0000 (UTC) Authentication-Results: imf13.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b="PXHOT/Rl"; spf=pass (imf13.hostedemail.com: domain of dakr@kernel.org designates 147.75.193.91 as permitted sender) smtp.mailfrom=dakr@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1727794826; 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=3AYZbO3il7IMjj6UU6a8G8k9T1mEpgQVoLLNur0v6rk=; b=cSVatM7tRU+BalYi/DZBW0ntEXMqvkfhdFSto5kkBSjEr8AKhirad7dYvv+n3qJVqV54ps 5yKoTM+cGs2bs6Tl0B2zkMC82lh5ts9jjLSl2AVqM5Cz822SbVG2363NONT/VAaiAbiFxj meZzZwt3XW4dR+sIUdEMuX6oA33cHlU= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1727794826; a=rsa-sha256; cv=none; b=WV0OhfahyX3MZCTVXZxIQU1WjV/D9bTgM1LT5YjzNMbrrSDx1sjbdtvsSXd46IOcmS9OX6 J48JJ+pasaDMp5/np4dlpjsoWPWBN5ZA6P9uoK3OyD9cdPTw0BJMVmts/OZKISg577+Tqp YvsaMwLe02DqTxXCnntpw9ZIQ8DUK0Q= ARC-Authentication-Results: i=1; imf13.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b="PXHOT/Rl"; spf=pass (imf13.hostedemail.com: domain of dakr@kernel.org designates 147.75.193.91 as permitted sender) smtp.mailfrom=dakr@kernel.org; dmarc=pass (policy=quarantine) header.from=kernel.org Received: from smtp.kernel.org (transwarp.subspace.kernel.org [100.75.92.58]) by nyc.source.kernel.org (Postfix) with ESMTP id A9CC7A40104; Tue, 1 Oct 2024 15:02:23 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id C10B0C4CED2; Tue, 1 Oct 2024 15:02:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1727794951; bh=MnOa0U7RkKOR0+keHOw6H4AlceJPUYq3oyu7nzf0U7Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PXHOT/Rl3F/gV5bzZmYoMj3Lj6bB+QWZ6CFnpagPAn4v3r5fesP9NRdvhyI+8c02G A7Hodb3ILKzIyl9YxMN9XhaINWLBHyJSZMLuJe7cZyor3wU6X8G0XiIPJJKcM3hllg 5vyYjdWQ4IWw6JFP9SGBGgr3q0XUwwcBkBg1EgVi8BU0uNJusT02tHclobkE0WTLXI 30fSduTv7LTnmP4yCapuQQlkJmxjxZ+HQmSdztcNFGU08Nr/s+jK8TLoKKaGlp9y5F 6nXxVYZOI2pLAD4Kx5XyY0xppBDwA+jf1rWm/Qz6wjHkeSTWSuFMHWpq6ihUBbBYxH vRBmarcEnJD2g== From: Danilo Krummrich To: ojeda@kernel.org, alex.gaynor@gmail.com, wedsonaf@gmail.com, boqun.feng@gmail.com, gary@garyguo.net, bjorn3_gh@protonmail.com, benno.lossin@proton.me, a.hindborg@samsung.com, aliceryhl@google.com, akpm@linux-foundation.org Cc: daniel.almeida@collabora.com, faith.ekstrand@collabora.com, boris.brezillon@collabora.com, lina@asahilina.net, mcanal@igalia.com, zhiw@nvidia.com, cjia@nvidia.com, jhubbard@nvidia.com, airlied@redhat.com, ajanulgu@redhat.com, lyude@redhat.com, linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org, linux-mm@kvack.org, Danilo Krummrich Subject: [PATCH v8 25/29] rust: alloc: implement `Cmalloc` in module allocator_test Date: Tue, 1 Oct 2024 17:00:00 +0200 Message-ID: <20241001150008.183102-26-dakr@kernel.org> X-Mailer: git-send-email 2.46.1 In-Reply-To: <20241001150008.183102-1-dakr@kernel.org> References: <20241001150008.183102-1-dakr@kernel.org> MIME-Version: 1.0 X-Rspamd-Queue-Id: A5E7520013 X-Stat-Signature: 9cjk6cineiwisjwkqk3gq4ysyqzbbnzk X-Rspamd-Server: rspam09 X-Rspam-User: X-HE-Tag: 1727794952-68869 X-HE-Meta: U2FsdGVkX19FZScmcXEAZoMdYCg1Ridu7d9dUIP4kuGDYHeEISwWJvcI5Lgu8zgbSILHCDnh3hDXzPzWpCjKVJ1nK6yvRI1Z/bI768qPfa75OI6uML+zUdav/e1Fl2w1kVdKv43fil4VDKR33O6M4y0+wk+Q004U6iZz1eKPffgFO8ULh3WlS+SM2qQPbvwdeeQ6QbKeOR8nMrbQfZXgg4+MTmdZ8cT4kGNamkaiehy4Iq/bZt/+zF8HRswqaUXwIlO8DyCRXU+8cWUocUIHt2WgQy3Duqggn1v4rlRF6q2aQgizNTfibIHbyr0e6uzzOr9h13Q1GSkkQfXYol59DpSVJxi7bCAnqjdZXBP+d2YJp4jqyNMgDUraHWzOiWhB2a05HsPD7RJhQtHqAElhovqrC8tUD8/mEctMIE4QKJbd5iKHZeT7fdymcVBXKTX1XjrCDPDL2AK1Pb4LqWFEZxU8CVG0ZlJN+WyXBa1W1WNIZYfhiWXDeWN/WeOWbBTjIimhzF1kfN5fzPgJDNcIX2DOlnJq1Brz7SNqvBSvK0APKdFsYe+G7Vn+RdiXT4Ip2MGCgNs7qdx76rqJFOY2S6Yv2zS33n3qf6TIMouwxwo1U9ikUuCvwkGMDlZ5tVCOwRuA3IU7/TwEqmtRb6l3x5fOCXrsdjjrlZrlaI4c2Vzya+8J/Ez4DxKR7VhMulE2F/L4cKozChwfEqHNQmhi2bbsWXu81pYVBk6MSiNd5KfUGNWm/gDMx/xBXXVg6A4zTFLFNKxZ7+6sQwdx5X+r3pnUgSMEOJVeHscvDnXlX2BjnmcJ0I/qorlYW4vuWLqIycZ+yM/qJflplE3K4pzIiHIBS0AfJcLq3b6Yu3Cl1b34Hyz095l+T5PdFXoKGPXlVSxqH2EZW/YVxYvmW0lDIqKMTP/tQ7cS996SAZ6mgx11DTFnyBclvvaX28pEhrcUH+HHaMo6JSfnH65JCrz 24+YYM9d 0wZjgaqNZvEWrvFer0m7ENVVM/923Ib+JSc+jwYtQK4JZHqhsIEiwkITJXucAz1CxTU/sEtYk5/Eru8EPq6rpmZER1Yipuyw8u9nTjXAkLtj4UzMSTFHK8edLdl6suRV1AE/xVNPPV9NuOpL+R9jhYRGOl+ngcPr3WebMQ/dB98tU7LOZiYle+ZA9iuJxq9lQCanWUN7jiWaUXE8XXQHB1C+a+IPv6rwZxJxiJruIr1/tfqwVPSo8XJbfK63RP0dTcf0EXFMMLmkveI0+PGZ61W3uP1Tg9U5BTnwj1MFLj7gMyRBaSC1wysky2RucGPw6jpB0W19ZqZP3PcUuobQ9C/7nzaRlRZmSZutF 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: So far the kernel's `Box` and `Vec` types can't be used by userspace test cases, since all users of those types (e.g. `CString`) use kernel allocators for instantiation. In order to allow userspace test cases to make use of such types as well, implement the `Cmalloc` allocator within the allocator_test module and type alias all kernel allocators to `Cmalloc`. The `Cmalloc` allocator uses libc's realloc() function as allocator backend. Signed-off-by: Danilo Krummrich Reviewed-by: Benno Lossin Reviewed-by: Gary Guo --- rust/kernel/alloc/allocator_test.rs | 88 ++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 7 deletions(-) diff --git a/rust/kernel/alloc/allocator_test.rs b/rust/kernel/alloc/allocator_test.rs index 1b2642c547ec..47c2b509898e 100644 --- a/rust/kernel/alloc/allocator_test.rs +++ b/rust/kernel/alloc/allocator_test.rs @@ -1,21 +1,95 @@ // SPDX-License-Identifier: GPL-2.0 +//! So far the kernel's `Box` and `Vec` types can't be used by userspace test cases, since all users +//! of those types (e.g. `CString`) use kernel allocators for instantiation. +//! +//! In order to allow userspace test cases to make use of such types as well, implement the +//! `Cmalloc` allocator within the allocator_test module and type alias all kernel allocators to +//! `Cmalloc`. The `Cmalloc` allocator uses libc's realloc() function as allocator backend. + #![allow(missing_docs)] -use super::{AllocError, Allocator, Flags}; +use super::{flags::*, AllocError, Allocator, Flags}; use core::alloc::Layout; +use core::cmp; +use core::ptr; use core::ptr::NonNull; -pub struct Kmalloc; +/// The userspace allocator based on libc. +pub struct Cmalloc; + +pub type Kmalloc = Cmalloc; pub type Vmalloc = Kmalloc; pub type KVmalloc = Kmalloc; -unsafe impl Allocator for Kmalloc { +extern "C" { + #[link_name = "aligned_alloc"] + fn libc_aligned_alloc(align: usize, size: usize) -> *mut core::ffi::c_void; + + #[link_name = "free"] + fn libc_free(ptr: *mut core::ffi::c_void); +} + +// SAFETY: +// - memory remains valid until it is explicitly freed, +// - passing a pointer to a valid memory allocation created by this `Allocator` is always OK, +// - `realloc` provides the guarantees as provided in the `# Guarantees` section. +unsafe impl Allocator for Cmalloc { unsafe fn realloc( - _ptr: Option>, - _layout: Layout, - _flags: Flags, + ptr: Option>, + layout: Layout, + old_layout: Layout, + flags: Flags, ) -> Result, AllocError> { - panic!(); + let src = match ptr { + Some(src) => { + if old_layout.size() == 0 { + ptr::null_mut() + } else { + src.as_ptr() + } + } + None => ptr::null_mut(), + }; + + if layout.size() == 0 { + // SAFETY: `src` is either NULL or was previously allocated with this `Allocator` + unsafe { libc_free(src.cast()) }; + + return Ok(NonNull::slice_from_raw_parts( + crate::alloc::dangling_from_layout(layout), + 0, + )); + } + + // SAFETY: Returns either NULL or a pointer to a memory allocation that satisfies or + // exceeds the given size and alignment requirements. + let dst = unsafe { libc_aligned_alloc(layout.align(), layout.size()) } as *mut u8; + let dst = NonNull::new(dst).ok_or(AllocError)?; + + if flags.contains(__GFP_ZERO) { + // SAFETY: The preceeding calls to `libc_aligned_alloc` and `NonNull::new` + // guarantee that `dst` points to memory of at least `layout.size()` bytes. + unsafe { dst.as_ptr().write_bytes(0, layout.size()) }; + } + + if !src.is_null() { + // SAFETY: + // - `src` has previously been allocated with this `Allocator`; `dst` has just been + // newly allocated, hence the memory regions do not overlap. + // - both` src` and `dst` are properly aligned and valid for reads and writes + unsafe { + ptr::copy_nonoverlapping( + src, + dst.as_ptr(), + cmp::min(layout.size(), old_layout.size()), + ) + }; + } + + // SAFETY: `src` is either NULL or was previously allocated with this `Allocator` + unsafe { libc_free(src.cast()) }; + + Ok(NonNull::slice_from_raw_parts(dst, layout.size())) } }