public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Huan Yang <link@vivo.com>
To: "Sumit Semwal" <sumit.semwal@linaro.org>,
	"Benjamin Gaignard" <benjamin.gaignard@collabora.com>,
	"Brian Starkey" <Brian.Starkey@arm.com>,
	"John Stultz" <jstultz@google.com>,
	"T.J. Mercier" <tjmercier@google.com>,
	"Christian König" <christian.koenig@amd.com>,
	linux-media@vger.kernel.org, dri-devel@lists.freedesktop.org,
	linaro-mm-sig@lists.linaro.org, linux-kernel@vger.kernel.org
Cc: opensource.kernel@vivo.com, Huan Yang <link@vivo.com>
Subject: [PATCH v2 4/5] dma-buf: heaps: system_heap alloc support async read
Date: Tue, 30 Jul 2024 15:57:48 +0800	[thread overview]
Message-ID: <20240730075755.10941-5-link@vivo.com> (raw)
In-Reply-To: <20240730075755.10941-1-link@vivo.com>

The system heap cyclically allocates pages and then places these pages
into a scatter_list, which is then managed by the dma-buf.

This process can parallelize memory allocation and I/O read operations:

Gather each allocated page and trigger a submit once the limit is reached.
Once the memory allocation is complete, there is no need to wait
immediately for the file read to finish. Instead, continue preparing the
dma-buf until it is necessary to return the dma-buf, at which point
waiting for the file content to be fully read is required.

Note that the content of the page cannot be modified after it is
allocated in the heap, as it may cause conflicts with accessing the page
when reading from the file. There are currently no conflicts in the
system_heap for this part.

The formula for the time taken for system_heap buffer allocation and
file reading through async_read is as follows:

  T(total) = T(first gather page) + Max(T(remain alloc), T(I/O))

Compared to the synchronous read:
  T(total) = T(alloc) + T(I/O)

If the allocation time or I/O time is long, the time difference will be
covered by the maximum value between the allocation and I/O. The other
party will be concealed.

Therefore, the larger the size of the file that needs to be read, the
greater the corresponding benefits will be.

Signed-off-by: Huan Yang <link@vivo.com>
---
 drivers/dma-buf/heaps/system_heap.c | 70 +++++++++++++++++++++++++++--
 1 file changed, 66 insertions(+), 4 deletions(-)

diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c
index d78cdb9d01e5..ba0c3d8ce090 100644
--- a/drivers/dma-buf/heaps/system_heap.c
+++ b/drivers/dma-buf/heaps/system_heap.c
@@ -331,10 +331,10 @@ static struct page *alloc_largest_available(unsigned long size,
 	return NULL;
 }
 
-static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
-					    unsigned long len,
-					    u32 fd_flags,
-					    u64 heap_flags)
+static struct dma_buf *__system_heap_allocate(struct dma_heap *heap,
+					      struct dma_heap_file *heap_file,
+					      unsigned long len, u32 fd_flags,
+					      u64 heap_flags)
 {
 	struct system_heap_buffer *buffer;
 	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
@@ -346,6 +346,7 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 	struct list_head pages;
 	struct page *page, *tmp_page;
 	int i, ret = -ENOMEM;
+	struct dma_heap_file_task *heap_ftask;
 
 	buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
 	if (!buffer)
@@ -357,6 +358,15 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 	buffer->len = len;
 
 	INIT_LIST_HEAD(&pages);
+
+	if (heap_file) {
+		heap_ftask = dma_heap_declare_file_read(heap_file);
+		if (!heap_ftask) {
+			kfree(buffer);
+			return ERR_PTR(-ENOMEM);
+		}
+	}
+
 	i = 0;
 	while (size_remaining > 0) {
 		/*
@@ -372,6 +382,13 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 		if (!page)
 			goto free_buffer;
 
+		/**
+		 * If alloc and read, gather each page to read task.
+		 * If got error, free buffer and return error.
+		 */
+		if (heap_file && dma_heap_gather_file_page(heap_ftask, page))
+			goto free_buffer;
+
 		list_add_tail(&page->lru, &pages);
 		size_remaining -= page_size(page);
 		max_order = compound_order(page);
@@ -400,9 +417,29 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 		ret = PTR_ERR(dmabuf);
 		goto free_pages;
 	}
+
+	/**
+	 * End of alloc, dma-buf export and anything we need, but maybe
+	 * file read is still work, so, wait it. if done, destroy all file
+	 * task.
+	 * But maybe something wrong when read file, if so, abandon dma-buf
+	 * return error.
+	 */
+	if (heap_file && dma_heap_end_file_read(heap_ftask)) {
+		dma_buf_put(dmabuf);
+		dmabuf = ERR_PTR(-EIO);
+	}
+
 	return dmabuf;
 
 free_pages:
+	/**
+	 * maybe we already trigger file read, so, before release pages,
+	 * wait for all running file read task done.
+	 */
+	if (heap_file)
+		dma_heap_wait_for_file_read(heap_ftask);
+
 	for_each_sgtable_sg(table, sg, i) {
 		struct page *p = sg_page(sg);
 
@@ -410,6 +447,13 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 	}
 	sg_free_table(table);
 free_buffer:
+	/**
+	 * maybe we already trigger file read, so, before release pages and
+	 * return, destroy file task, include running task.
+	 */
+	if (heap_file)
+		dma_heap_end_file_read(heap_ftask);
+
 	list_for_each_entry_safe(page, tmp_page, &pages, lru)
 		__free_pages(page, compound_order(page));
 	kfree(buffer);
@@ -417,8 +461,26 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
 	return ERR_PTR(ret);
 }
 
+static struct dma_buf *system_heap_allocate(struct dma_heap *heap,
+					    unsigned long len, u32 fd_flags,
+					    u64 heap_flags)
+{
+	return __system_heap_allocate(heap, NULL, len, fd_flags, heap_flags);
+}
+
+static struct dma_buf *
+system_heap_allocate_async_read_file(struct dma_heap *heap,
+				     struct dma_heap_file *heap_file,
+				     u32 fd_flags, u64 heap_flags)
+{
+	return __system_heap_allocate(heap, heap_file,
+				      PAGE_ALIGN(dma_heap_file_size(heap_file)),
+				      fd_flags, heap_flags);
+}
+
 static const struct dma_heap_ops system_heap_ops = {
 	.allocate = system_heap_allocate,
+	.allocate_async_read = system_heap_allocate_async_read_file,
 };
 
 static int system_heap_create(void)
-- 
2.45.2


  parent reply	other threads:[~2024-07-30  7:58 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-30  7:57 [PATCH v2 0/5] Introduce DMA_HEAP_ALLOC_AND_READ_FILE heap flag Huan Yang
2024-07-30  7:57 ` [PATCH v2 1/5] dma-buf: heaps: " Huan Yang
2024-07-31 11:08   ` kernel test robot
2024-07-30  7:57 ` [PATCH v2 2/5] dma-buf: heaps: Introduce async alloc read ops Huan Yang
2024-07-30  7:57 ` [PATCH v2 3/5] dma-buf: heaps: support alloc async read file Huan Yang
2024-07-31 14:44   ` kernel test robot
2024-07-30  7:57 ` Huan Yang [this message]
2024-07-30  7:57 ` [PATCH v2 5/5] dma-buf: heaps: configurable async read gather limit Huan Yang
2024-07-30  8:03 ` [PATCH v2 0/5] Introduce DMA_HEAP_ALLOC_AND_READ_FILE heap flag Christian König
2024-07-30  8:14   ` Huan Yang
2024-07-30  8:37     ` Christian König
2024-07-30  8:46       ` Huan Yang
2024-07-30 10:43         ` Christian König
2024-07-30 11:36           ` Huan Yang
2024-07-30 13:11             ` Christian König
2024-07-31  1:48               ` Huan Yang
2024-07-30 17:19     ` T.J. Mercier
2024-07-31  1:47       ` Huan Yang
2024-07-30  8:56 ` Daniel Vetter
2024-07-30  9:05   ` Huan Yang
2024-07-30 10:42     ` Christian König
2024-07-30 11:33       ` Huan Yang
2024-07-30 12:04     ` Huan Yang
2024-07-31 20:46       ` Daniel Vetter
2024-08-01  2:53         ` Huan Yang
2024-08-05 17:53           ` Daniel Vetter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240730075755.10941-5-link@vivo.com \
    --to=link@vivo.com \
    --cc=Brian.Starkey@arm.com \
    --cc=benjamin.gaignard@collabora.com \
    --cc=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=jstultz@google.com \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=opensource.kernel@vivo.com \
    --cc=sumit.semwal@linaro.org \
    --cc=tjmercier@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox