From patchwork Wed May 3 09:07:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Hindborg X-Patchwork-Id: 89660 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b0ea:0:b0:3b6:4342:cba0 with SMTP id b10csp1185062vqo; Wed, 3 May 2023 02:15:49 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4wO2ckU2ZDsadRV6zXws8Lg7NlNUVfdokN6LOEQrFeBLeDnFWGjl30rprAz3mYhTxGkY3b X-Received: by 2002:a17:90a:d798:b0:246:5fbb:43bf with SMTP id z24-20020a17090ad79800b002465fbb43bfmr21208889pju.4.1683105348774; Wed, 03 May 2023 02:15:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1683105348; cv=none; d=google.com; s=arc-20160816; b=xfyTqAg7xhWr8fzzEKtKG0sXhIIO9vHIPdw37oj/HDqYVX6q9IjDRkSdD6Yx0bVVHo z7z6vjNQZo3rjfz+axa/IRTlSMXGhYLhWthAkZW0QDI4KW6Fnw9V2S+hoa+TosYbjM68 ACYawei7SFLUuG923TAj40+bR/6mtJPg2IuHigV1l5Kc72FkjgN63gyWPxg+xY6wfqSa FkALgzzxkSCgHYjxSS5jnXaCIwsh4JIo8e81haNQpqmlRxEt73c99tWd3oRRBjfA6RGP V90taIbAAM9+EAO3HU2ocxmwQh/V+xqsyyU6sFbSBcNDMe1NjVGL30AYOCqGC0OLqd5W 25og== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=pfKdjWdresPJSdXc5oUQnKkLhNP+u1b3Z6UA6/bvZEs=; b=maTpNGTOPQ6XeXmsYIjeUFBFXYwpwAPUm1Wy8QQTsWUxGfnlh+ClA3131bDk9JJkq/ ofLg0q6VnStSA7aULk6jREHvMc7RS05EhXpRP+ZmccM0lVq+8/6Gm/yTPQxonPnTswKO NVBtj/AOLRXO3P2lME4UeZBGNVZgFFMsN+pxZYBTOapBwJrRFYcoF8J8bG31nnw78raL YeeiOExylgy6b4TokF/JnQklPKeWLMFTm+1oUPOAK8bDiGB8sUKEUGpCyj4ahP2Fu6XO 93d6SGZiHalXDEhIMXiyd/MJj7LsiUnDwmg+hdABS5CfDV/rvPw5EJjQy0QQE4oJg6Oj fyMQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@metaspace-dk.20221208.gappssmtp.com header.s=20221208 header.b=zxf3V0pi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 81-20020a630054000000b0051f11134681si33233713pga.546.2023.05.03.02.15.35; Wed, 03 May 2023 02:15:48 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@metaspace-dk.20221208.gappssmtp.com header.s=20221208 header.b=zxf3V0pi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229813AbjECJIG (ORCPT + 99 others); Wed, 3 May 2023 05:08:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45922 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229707AbjECJHj (ORCPT ); Wed, 3 May 2023 05:07:39 -0400 Received: from mail-wr1-x436.google.com (mail-wr1-x436.google.com [IPv6:2a00:1450:4864:20::436]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98CAF46B7 for ; Wed, 3 May 2023 02:07:26 -0700 (PDT) Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-305f0491e62so4324421f8f.3 for ; Wed, 03 May 2023 02:07:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=metaspace-dk.20221208.gappssmtp.com; s=20221208; t=1683104844; x=1685696844; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=pfKdjWdresPJSdXc5oUQnKkLhNP+u1b3Z6UA6/bvZEs=; b=zxf3V0pixeyAdrD64XjVTcoz5GBZP1Ez2NPEYfg4bJ+8OpHIgbs5IPYWoyRFF/oRls 1HiTMTqiw5oPzKcjXk85WtG2qWppkjvU02IYtCNv/P6lilDjZ3I/tCqie+hxdHS9fI72 TFUlh6Wb66UftjAJVkN8zXebQeRzUQEjndgJGChQSPHdwiL4EDhLk2wZR45z/mLS3qsS 0hle1vi+M/A5q3ANxKiVAd1H1NxXbl8yRYYvbayFD9yVys1oohANbByOMWC+mJ8fu1Aq h3If9GnckODucwV34nms5ONfQlshxGTXJ2YdkMkaVW/TPTSFD4UmrIVnUA6QvhXfqCL+ 1Ffw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1683104844; x=1685696844; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=pfKdjWdresPJSdXc5oUQnKkLhNP+u1b3Z6UA6/bvZEs=; b=lftjJpWP1QyAbXWOngXxkaxwWypbOFLENowjk5U4EZaxG0arc7GNpK0/tMgVish332 pAfoshzNNVuE+aXaEoyJZV8OIKSURQsBUHinDuHHJvRR4jtZG3RSzHu4Pz2Ax4o9QHMi zm8ehaJIZ6ckwBdvQ6VC8/EcPDsZiOBvLWESm+dInbsOCdkR0EHp0yi+b+xhvA22cBtS TP2SXP0holCznkb7oqe7HRQh1UhkkIkVWYlSgF9Tm05E9RwRfIt599JfPQNmXjjsOHyD RVxcec/l6RNr3ct8Lu6bRjdeuL3itb3GOE8q/IcE0jK8sMTjAB1owis/5V1NVgV1M9XP BN+Q== X-Gm-Message-State: AC+VfDxzegZtZjWk2lrL40Gk4uoiMWXq0u8yEw3SrItsGS3K2hsXsZLZ 314OSSOUjW5bLr5eR6D2fgzRvA== X-Received: by 2002:adf:ee8d:0:b0:306:42e2:5ec3 with SMTP id b13-20020adfee8d000000b0030642e25ec3mr912726wro.6.1683104844271; Wed, 03 May 2023 02:07:24 -0700 (PDT) Received: from localhost ([147.161.155.99]) by smtp.gmail.com with ESMTPSA id k11-20020a7bc40b000000b003f173a2b2f6sm1248839wmi.12.2023.05.03.02.07.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 May 2023 02:07:24 -0700 (PDT) From: Andreas Hindborg To: Jens Axboe , Christoph Hellwig , Keith Busch , Damien Le Moal , Hannes Reinecke , lsf-pc@lists.linux-foundation.org, rust-for-linux@vger.kernel.org, linux-block@vger.kernel.org Cc: Wedson Almeida Filho , Matthew Wilcox , Miguel Ojeda , Alex Gaynor , Wedson Almeida Filho , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Andreas Hindborg , linux-kernel@vger.kernel.org (open list), gost.dev@samsung.com Subject: [RFC PATCH 08/11] rust: lock: implement `IrqSaveBackend` for `SpinLock` Date: Wed, 3 May 2023 11:07:05 +0200 Message-Id: <20230503090708.2524310-9-nmi@metaspace.dk> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230503090708.2524310-1-nmi@metaspace.dk> References: <20230503090708.2524310-1-nmi@metaspace.dk> MIME-Version: 1.0 X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE, T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1764863874352213359?= X-GMAIL-MSGID: =?utf-8?q?1764863874352213359?= From: Wedson Almeida Filho This allows Rust code to use the `lock_irqsave` variant of spinlocks. Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Will Deacon Cc: Waiman Long Reviewed-by: Martin Rodriguez Reboredo Signed-off-by: Wedson Almeida Filho --- rust/helpers.c | 16 ++++++++++++ rust/kernel/sync/lock/spinlock.rs | 41 +++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/rust/helpers.c b/rust/helpers.c index a59341084774..7f5b95f652e1 100644 --- a/rust/helpers.c +++ b/rust/helpers.c @@ -203,6 +203,22 @@ struct page *rust_helper_alloc_pages(gfp_t gfp_mask, unsigned int order) } EXPORT_SYMBOL_GPL(rust_helper_alloc_pages); +unsigned long rust_helper_spin_lock_irqsave(spinlock_t *lock) +{ + unsigned long flags; + + spin_lock_irqsave(lock, flags); + + return flags; +} +EXPORT_SYMBOL_GPL(rust_helper_spin_lock_irqsave); + +void rust_helper_spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags) +{ + spin_unlock_irqrestore(lock, flags); +} +EXPORT_SYMBOL_GPL(rust_helper_spin_unlock_irqrestore); + /* * We use `bindgen`'s `--size_t-is-usize` option to bind the C `size_t` type * as the Rust `usize` type, so we can use it in contexts where Rust diff --git a/rust/kernel/sync/lock/spinlock.rs b/rust/kernel/sync/lock/spinlock.rs index e39142a8148c..50b8775bb49d 100644 --- a/rust/kernel/sync/lock/spinlock.rs +++ b/rust/kernel/sync/lock/spinlock.rs @@ -64,6 +64,8 @@ macro_rules! new_spinlock { /// assert_eq!(e.c, 10); /// assert_eq!(e.d.lock().a, 20); /// assert_eq!(e.d.lock().b, 30); +/// assert_eq!(e.d.lock_irqsave().a, 20); +/// assert_eq!(e.d.lock_irqsave().b, 30); /// ``` /// /// The following example shows how to use interior mutability to modify the contents of a struct @@ -81,6 +83,12 @@ macro_rules! new_spinlock { /// let mut guard = m.lock(); /// guard.a += 10; /// guard.b += 20; +/// +/// fn example2(m: &SpinLock) { +/// let mut guard = m.lock_irqsave(); +/// guard.a += 10; +/// guard.b += 20; +/// } /// } /// ``` /// @@ -94,7 +102,7 @@ pub struct SpinLockBackend; // default implementation that always calls the same locking method. unsafe impl super::Backend for SpinLockBackend { type State = CachePadded; - type GuardState = (); + type GuardState = Option; unsafe fn init( ptr: *mut Self::State, @@ -110,13 +118,32 @@ unsafe impl super::Backend for SpinLockBackend { unsafe fn lock(ptr: *mut Self::State) -> Self::GuardState { // SAFETY: The safety requirements of this function ensure that `ptr` points to valid // memory, and that it has been initialised before. - unsafe { bindings::spin_lock((&mut *ptr).deref_mut()) } + unsafe { bindings::spin_lock((&mut *ptr).deref_mut()) }; + None } - #[inline(always)] - unsafe fn unlock(ptr: *mut Self::State, _guard_state: &Self::GuardState) { - // SAFETY: The safety requirements of this function ensure that `ptr` is valid and that the - // caller is the owner of the mutex. - unsafe { bindings::spin_unlock((&mut *ptr).deref_mut()) } + unsafe fn unlock(ptr: *mut Self::State, guard_state: &Self::GuardState) { + match guard_state { + // SAFETY: The safety requirements of this function ensure that `ptr` is valid and that + // the caller is the owner of the mutex. + Some(flags) => unsafe { + bindings::spin_unlock_irqrestore((&mut *ptr).deref_mut(), *flags) + }, + // SAFETY: The safety requirements of this function ensure that `ptr` is valid and that + // the caller is the owner of the mutex. + None => unsafe { bindings::spin_unlock((&mut *ptr).deref_mut()) }, + } + } +} + +// SAFETY: The underlying kernel `spinlock_t` object ensures mutual exclusion. We use the `irqsave` +// variant of the C lock acquisition functions to disable interrupts and retrieve the original +// interrupt state, and the `irqrestore` variant of the lock release functions to restore the state +// in `unlock` -- we use the guard context to determine which method was used to acquire the lock. +unsafe impl super::IrqSaveBackend for SpinLockBackend { + unsafe fn lock_irqsave(ptr: *mut Self::State) -> Self::GuardState { + // SAFETY: The safety requirements of this function ensure that `ptr` points to valid + // memory, and that it has been initialised before. + Some(unsafe { bindings::spin_lock_irqsave((&mut *ptr).deref_mut()) }) } }