Received: by 2002:ab2:1149:0:b0:1f3:1f8c:d0c6 with SMTP id z9csp2928565lqz; Wed, 3 Apr 2024 12:38:06 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCWIPAFBKd3J3RkQZ3LqDe9tZMw/WY0X0L/4gEtdiJS/3xex5MbQu3VXt0re0gggvfaeZC9Ax9UXQhAcqGAb3TblPsdntAKFwzyBnvK/Yg== X-Google-Smtp-Source: AGHT+IG+jZwNkxmdIeRMRxDB6wlKkVY7T7o7IP3aFSuvU3mFpHe6h0lVONTY+vx6jGn5uZsPPers X-Received: by 2002:a9d:6418:0:b0:6e7:39ab:a990 with SMTP id h24-20020a9d6418000000b006e739aba990mr225427otl.9.1712173086515; Wed, 03 Apr 2024 12:38:06 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1712173086; cv=pass; d=google.com; s=arc-20160816; b=GISNusY5rVGvcUF7qG2kwvc7Q7rekaoItp2U/xVb3RltfJ/dis0031L4TuUtvw+o7q qEbSoW1Uoh9ioBLUF2k2HB9Pdfkf7kXwrn1gksXRKWEDSgko3a8AbZnVKTyctnfXDni6 36EVz1e5p15ZzUKYrQ0YmtaBkMn54HQ7/9TMTqfmLBKZ6RH5FghyPBG5+SCKkZ/d0+Om WuVPQuXKXhSQ4lrLN7qXnuuRDY53rYuh+EiBMxAiBE9aeN01GoZdQ8YWJEj3ZQZYs1re QRq2x2vj5/NsPMvY5u8JaHIM/YmGZ7GlWOHzf6Y/PzhsKKfeEZqYmms5PRwwO7GpYFdJ 9pxA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:feedback-id:references :in-reply-to:message-id:subject:cc:from:to:date:dkim-signature; bh=vLw1EUqqXu0E0eV8EO0iY5ZyKumQlE4AJba1Jz1x2ok=; fh=inZYH/v3NzjFycuVogAW3BTDF8DWFOh4BLkA413aPuM=; b=IcN5CjjbcvPJSQ81Ucyhmqj8XXOdcn2ki7PO9XyumveN3QJBP59bcm7jWAxPcLs1Pv hTqDfcLIkTED/Ah6/g3r5ShcqujHTIg4N7iy9PD3KZ0sCnPuHfS3Fqot+CgO75iBHCsm lgSLV7/jqe9VzMYFSE/h3XIu7iixSAtppfBCz7k6YJuCpRV4NCPyAjkyhfPvJFEBp8bN kUMuLEm5AIctDPi6KyVU0VGpeOyRLTgtLK+VNIBnjcjT8LyOTPvxNDFZBHPMMGP8bc+w 2oZzl26G0Mp32VRM+4au/m2LbVlJOoNgmB5zKaYoBJN/LVpU58y1rtu6/DzuFXa79H1+ r4eA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b="eRTf/YaV"; arc=pass (i=1 spf=pass spfdomain=proton.me dkim=pass dkdomain=proton.me dmarc=pass fromdomain=proton.me); spf=pass (google.com: domain of linux-kernel+bounces-130512-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-130512-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Return-Path: Received: from ny.mirrors.kernel.org (ny.mirrors.kernel.org. [2604:1380:45d1:ec00::1]) by mx.google.com with ESMTPS id h11-20020a05620a244b00b0078a1e412169si16517228qkn.709.2024.04.03.12.38.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 03 Apr 2024 12:38:06 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-130512-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) client-ip=2604:1380:45d1:ec00::1; Authentication-Results: mx.google.com; dkim=pass header.i=@proton.me header.s=protonmail header.b="eRTf/YaV"; arc=pass (i=1 spf=pass spfdomain=proton.me dkim=pass dkdomain=proton.me dmarc=pass fromdomain=proton.me); spf=pass (google.com: domain of linux-kernel+bounces-130512-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45d1:ec00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-130512-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=proton.me Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ny.mirrors.kernel.org (Postfix) with ESMTPS id E81871C243C0 for ; Wed, 3 Apr 2024 19:38:05 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E68BC1553A0; Wed, 3 Apr 2024 19:37:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b="eRTf/YaV" Received: from mail-4316.protonmail.ch (mail-4316.protonmail.ch [185.70.43.16]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5CF101401C for ; Wed, 3 Apr 2024 19:37:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.70.43.16 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712173074; cv=none; b=dE+/TCCj1dpUNpDZ7ahneZWRi7dZvcECaJqU+o6bvAEL/wYHoGXa4ChlNQMiOBWn+TGuGw17eWloBteNipEKAQUnNicdO5NgLenZIiKDfTFEJhOSzKRV61EmIxRRuW73RaUq+IqgFbZN5A2VgdszNIzk/vQWsz1KKo+h/s3wpJs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1712173074; c=relaxed/simple; bh=dXEOpxiE2RCJ9FBYM438Z1FVC+BmQcHQgxYhuc5OAqM=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=rMrWqSuapPKQpJPaXvLSU5IVw7MuDLDmZ7ls65pMN5H9Rtt0UY5/4weA0D61c9cBQ6QH022jMI2h03CaVZ7jbbTCnqrfOeWNN+40bvkeMdQArjTJZNYc71DrTALPzoC/NH/tei/DyfVvADF6IgRQ+7Vd4IvQpwFm48BU95ceiVQ= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me; spf=pass smtp.mailfrom=proton.me; dkim=pass (2048-bit key) header.d=proton.me header.i=@proton.me header.b=eRTf/YaV; arc=none smtp.client-ip=185.70.43.16 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=proton.me Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=proton.me DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=proton.me; s=protonmail; t=1712173069; x=1712432269; bh=vLw1EUqqXu0E0eV8EO0iY5ZyKumQlE4AJba1Jz1x2ok=; h=Date:To:From:Cc:Subject:Message-ID:In-Reply-To:References: Feedback-ID:From:To:Cc:Date:Subject:Reply-To:Feedback-ID: Message-ID:BIMI-Selector; b=eRTf/YaVgrIkJNR0WTMp4U/nw7/iMQrP+XEuzQm95Y6Cbc0k5V8oyCBAXcj0uwPg2 JrZ2mrYoc8XBDwj9LyX3Ovhz9XVubhjCTrQZBXMMrPrLG+hOSxKqjBYODcxhwtBks6 PFCf3LWUNfdeWlv4+xxO0GZdsC6Zev7ge0xZZBzk5D+kYVjRx05iXRU4HGd1h/1RH0 qZ+Oa2anQp9jKemSCTS8RtOZ7JnZVVH0aZjGVsKHXBu+XEI9ytSajehXXIv+9SQhIq Dy5WlMhBwmmY5/UlVzj+p0gRP5nmF0uRI0Jky7TMOrrNnshpAg6+mqEe1tJ5+E3jgT nb7KeDofat4RQ== Date: Wed, 03 Apr 2024 19:37:44 +0000 To: Andreas Hindborg From: Benno Lossin Cc: Jens Axboe , Christoph Hellwig , Keith Busch , Damien Le Moal , Bart Van Assche , Hannes Reinecke , "linux-block@vger.kernel.org" , Andreas Hindborg , Wedson Almeida Filho , Niklas Cassel , Greg KH , Matthew Wilcox , Miguel Ojeda , Alex Gaynor , Boqun Feng , Gary Guo , =?utf-8?Q?Bj=C3=B6rn_Roy_Baron?= , Alice Ryhl , Chaitanya Kulkarni , Luis Chamberlain , Yexuan Yang <1182282462@bupt.edu.cn>, =?utf-8?Q?Sergio_Gonz=C3=A1lez_Collado?= , Joel Granados , "Pankaj Raghav (Samsung)" , Daniel Gomez , open list , "rust-for-linux@vger.kernel.org" , "lsf-pc@lists.linux-foundation.org" , "gost.dev@samsung.com" , Ming Lei Subject: Re: [RFC PATCH 1/5] rust: block: introduce `kernel::block::mq` module Message-ID: In-Reply-To: <87v84ysujo.fsf@metaspace.dk> References: <86cd5566-5f1b-434a-9163-2b2d60a759d1@proton.me> <871q7o54el.fsf@metaspace.dk> <7ed2a8df-3088-42a1-b257-dba3c2c9fc92@proton.me> <87v84ysujo.fsf@metaspace.dk> Feedback-ID: 71780778:user:proton Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 03.04.24 10:46, Andreas Hindborg wrote: > Benno Lossin writes: >=20 >> On 23.03.24 07:32, Andreas Hindborg wrote: >>> Benno Lossin writes: >>>> On 3/13/24 12:05, Andreas Hindborg wrote: >>>>> +//! implementations of the `Operations` trait. >>>>> +//! >>>>> +//! IO requests are passed to the driver as [`Request`] references. = The >>>>> +//! `Request` type is a wrapper around the C `struct request`. The d= river must >>>>> +//! mark start of request processing by calling [`Request::start`] a= nd end of >>>>> +//! processing by calling one of the [`Request::end`], methods. Fail= ure to do so >>>>> +//! can lead to IO failures. >>>> >>>> I am unfamiliar with this, what are "IO failures"? >>>> Do you think that it might be better to change the API to use a >>>> callback? So instead of calling start and end, you would do >>>> >>>> request.handle(|req| { >>>> // do the stuff that would be done between start and end >>>> }); >>>> >>>> I took a quick look at the rnull driver and there you are calling >>>> `Request::end_ok` from a different function. So my suggestion might no= t >>>> be possible, since you really need the freedom. >>>> >>>> Do you think that a guard approach might work better? ie `start` retur= ns >>>> a guard that when dropped will call `end` and you need the guard to >>>> operate on the request. >>> >>> I don't think that would fit, since the driver might not complete the >>> request immediately. We might be able to call `start` on behalf of the >>> driver. >>> >>> At any rate, since the request is reference counted now, we can >>> automatically fail a request when the last reference is dropped and it >>> was not marked successfully completed. I would need to measure the >>> performance implications of such a feature. >> >> Are there cases where you still need access to the request after you >> have called `end`? >=20 > In general no, there is no need to handle the request after calling end. > C drivers are not allowed to, because this transfers ownership of the > request back to the block layer. This patch series defer the transfer of > ownership to the point when the ARef refcount goes to zero, so > there should be no danger associated with touching the `Request` after > end. >=20 >> If no, I think it would be better for the request to >> be consumed by the `end` function. >> This is a bit difficult with `ARef`, since the user can just clone it >> though... Do you think that it might be necessary to clone requests? >=20 > Looking into the details now I see that calling `Request::end` more than > once will trigger UAF, because C code decrements the refcount on the > request. When we have `ARef` around, that is a problem. It > probably also messes with other things in C land. Good catch. >=20 > I did implement `Request::end` to consume the request at one point > before I fell back on reference counting. It works fine for simple > drivers. However, most drivers will need to use the block layer tag set > service, that allows conversion of an integer id to a request pointer. > The abstraction for this feature is not part of this patch set. But the > block layer manages a mapping of integer to request mapping, and drivers > typically use this to identify the request that corresponds to > completion messages that arrive from hardware. When drivers are able to > turn integers into requests like this, consuming the request in the call > to `end` makes little sense (because we can just construct more). How do you ensure that this is fine?: let r1 =3D tagset.get(0); let r2 =3D tagset.get(0); r1.end_ok(); r2.do_something_that_would_only_be_done_while_active(); One thing that comes to my mind would be to only give out `&Request` from the tag set. And to destroy, you could have a separate operation that also removes the request from the tag set. (I am thinking of a tag set as a `HashMap`. >=20 > What I do now is issue the an `Option>` with > `bindings::req_ref_inc_not_zero(rq_ptr)`, to make sure that the request > is currently owned by the driver. >=20 > I guess we can check the absolute value of the refcount, and only issue > a request handle if the count matches what we expect. Then we can be cert= ain > that the handle is unique, and we can require transfer of ownership of > the handle to `Request::end` to make sure it can never be called more > than once. >=20 > Another option is to error out in `Request::end` if the > refcount is not what we expect. I am a bit confused, why does the refcount matter in this case? Can't the user just have multiple `ARef`s? I think it would be weird to use `ARef` if you expect the refcount to be 1. Maybe the API should be different? As I understand it, a request has the following life cycle (please correct me if I am wrong): 1. A new request is created, it is given to the driver via `queue_rq`. 2. The driver can now decide what to do with it (theoretically it can store it somewhere and later do something with it), but it should at some point call `Request::start`. 3. Work happens and eventually the driver calls `Request::end`. To me this does not seem like something where we need a refcount (we still might need one for safety, but it does not need to be exposed to the user). --=20 Cheers, Benno