From nobody Sat Sep 26 01:42:01 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (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 1575338F226; Sun, 6 Sep 2026 12:41:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788698468; cv=none; b=EKNVS76sjvjRPyEjbDpA4eCyRPydc8iVurs22ucjzXjVCsTQKjHT/X+eEmzl9PdlDh1GCeoH2HZKOPWK69AwnF0dtiN4dcQl5iKTqyfw1s9RWNfgXR1dzeZNTAm3q7XB6P0adxGviKNU2tzALx/mNZiP9ahOuX47mVJs73CibpM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788698468; c=relaxed/simple; bh=fNuM8yoVG9IS3kB+I9ATZiBsZEBz9edAYbcxO26Rcdg=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=MXwZzuRrDP/Yy+oDz9dIXyqddys7IdBS/kRdnm8cgQ3drbB5XxLj66pJ8jFG71/Bgv4eJxagpwNRxKIDz0FV153kwow2NUct3fVMfS0J0V6hdqL21NEgJSYNum3Kyqro1hZgrlEBRx4v+Bke961XXaRaE4FpSpoSh+NdJN8f8Sw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dMZ0Axdf; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dMZ0Axdf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 918011F00A3A; Sun, 6 Sep 2026 12:41:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1788698464; bh=U3JfcolKhWuGBZd+pPAMx4DP4zPhwZzJyNp/2+tGFjM=; h=From:To:Cc:Subject:Date; b=dMZ0AxdfxbfX8Qw/W+iVl5jpZfJh0lDCrVd9YIeeLAR/EKex0xTIIw9Ozz7tWe6AK Mfas/DjLnBGb5MD63ScSzkCeM98s8EA2vmcK2VhaPDAymDcjyW4omsX1tJhh2zKeZG 5nRHGw0gCFbziweExGJKEcatTGoDn95az90obMWbb2s7+WWIOiXdYugcWtop/dTGLY X6WPbzBKLWQSs4jKGquOlOjsiAPgbJ8yRqYEikx9bW8qtMBMtSw8TwhtMNPJYKvOeG VIcJJMKZGk0ZVS7Xhp4NkNDPUNDMjVtFcyeMz4sqzvPrL9TVovVNeUrwlsCRR/wBxj 37pXN5oDqo4SQ== From: Leon Romanovsky To: Sumit Semwal , =?utf-8?q?Christian_K=C3=B6nig?= , Jonathan Corbet , Shuah Khan Cc: Logan Gunthorpe , linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, Jason Gunthorpe Subject: [PATCH v2] dma-buf: Document how exporters and importers agree on mapping lifetime Date: Sun, 6 Sep 2026 15:40:54 +0300 Message-ID: <20260906-document-dma-buf-v2-1-942710fe82c6@nvidia.com> X-Mailer: git-send-email 2.55.0 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" X-Change-ID: 20260820-document-dma-buf-3f8b41e32f57 X-Mailer: b4 0.15-dev-18f8f Content-Transfer-Encoding: quoted-printable From: Leon Romanovsky Nothing in DMA-buf declares whether a mapping may be moved or taken away. Nearly every callback on both sides is optional, so the answer follows from which ones are implemented and from whether dma_buf_pin() succeeds. Documentation/ says none of this, and the rules sit in the kdoc of dma_buf_ops.pin, dma_buf_attach_ops.invalidate_mappings and dma_buf_invalidate_mappings(), which a driver author has to know by name before finding them. Describe the three flows an importer has to handle, the callbacks each one asks of both sides, and dma_buf_pin() as the runtime negotiation. Signed-off-by: Leon Romanovsky --- Let's try this variant from importer POV. Thanks Changes in v2: - Split pci p2p documentation patch to separate series - Improved dma-buf documentation patch. - Link to v1: https://patch.msgid.link/20260825-document-dma-buf-v1-0-5ecfb= 3e1371c@nvidia.com --- Documentation/driver-api/dma-buf.rst | 6 ++++ drivers/dma-buf/dma-buf.c | 69 ++++++++++++++++++++++++++++++++= +++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/Documentation/driver-api/dma-buf.rst b/Documentation/driver-ap= i/dma-buf.rst index 2f36c21d9948..39c201f38aa6 100644 --- a/Documentation/driver-api/dma-buf.rst +++ b/Documentation/driver-api/dma-buf.rst @@ -113,6 +113,12 @@ Basic Operation and Device DMA Access .. kernel-doc:: drivers/dma-buf/dma-buf.c :doc: dma buf device access =20 +Mapping Lifetime Negotiation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. kernel-doc:: drivers/dma-buf/dma-buf.c + :doc: mapping lifetime negotiation + CPU Access to DMA Buffer Objects ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ =20 diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index d504c636dc29..aa47142cd9ed 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -684,7 +684,74 @@ static struct file *dma_buf_getfile(size_t size, int f= lags) * reference acquired with dma_buf_get() by calling dma_buf_put(). * * For the detailed semantics exporters are expected to implement see - * &dma_buf_ops. + * &dma_buf_ops. Whether the exporter may still move or take away the back= ing + * storage after step 3 depends on what both sides implement. See the mapp= ing + * lifetime negotiation section below. + */ + +/** + * DOC: mapping lifetime negotiation + * + * Nearly everything in DMA-buf is optional. No flag or enum says whether = the + * exporter may move or take away the backing storage while an importer ho= lds + * a mapping. Each side simply implements the callbacks it can offer, and + * dma_buf_pin() settles the result at runtime. + * + * Out of that optionality the importer sees three main flows. They are na= med + * from the importer's point of view, because each one demands a different + * capability of its hardware: + * + * - Pinned: the memory is never taken away. The importer offers no way + * to stop DMA. + * - Revoked: the storage never moves, but the exporter may take it away. = The + * importer must be able to stop DMA, and may hit user visible errors wh= ile + * doing so. + * - Movable: the exporter may relocate the storage at any time. The impor= ter + * must be able to pause DMA, and must raise no error while the storage = is + * moving. + * + * An importer reaches its flow like this: + * + * 1. Attach with dma_buf_dynamic_attach(). Leaving out the optional + * &dma_buf_attach_ops.invalidate_mappings callback pins the buffer for= as + * long as the attachment exists. + * 2. Call dma_buf_pin() under the reservation lock. + * 3. On failure, run the movable flow or give up. + * 4. On success, the flow is the revoked one if the optional + * &dma_buf_attach_ops.invalidate_mappings is implemented, and the pinn= ed + * one if it is not. + * + * Pinned flow: + * + * - Exporter: implement &dma_buf_ops.pin and &dma_buf_ops.unpin to hold t= he + * storage still on request. An exporter whose storage never moves imple= ments + * neither, and dma_buf_pin() then succeeds on its own. An exporter which + * refuses to be pinned implements &dma_buf_ops.pin and fails it. + * - Importer: nothing more. The mapping stays valid until the importer un= maps. + * + * Revoked flow: + * + * - Exporter: answer dma_buf_pin() as above. Call + * dma_buf_invalidate_mappings() when the storage goes away and fail + * &dma_buf_ops.map_dma_buf while it is gone. The two waits which comple= te a + * revocation are described in dma_buf_invalidate_mappings(). + * - Importer: &dma_buf_attach_ops.invalidate_mappings has to unmap within + * bounded time and drop the pin. + * + * Movable flow: + * + * - Exporter: call dma_buf_invalidate_mappings() before each move, then w= ait + * for the &dma_buf.resv fences. &dma_buf_ops.pin and &dma_buf_ops.unpin= play + * no part here. + * - Importer: hold no pin. &dma_buf_attach_ops.invalidate_mappings drops = the + * cached mapping and has to lead to dma_buf_unmap_attachment() within + * bounded time. It need not stop the hardware, because access runs unti= l the + * importer's &dma_buf.resv fences retire. The importer maps again befor= e the + * next DMA. + * + * &dma_buf_ops.attach is the best place for an exporter to turn an import= er + * away, because the importer can still fall back to another flow and atta= ch + * again. */ =20 /** --- base-commit: 63367df6e7255067ad6a83abe0d2799dfa491876 change-id: 20260820-document-dma-buf-3f8b41e32f57 Best regards, -- =20 Leon Romanovsky