You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by kp...@apache.org on 2022/04/12 13:58:35 UTC

[tvm] branch main updated: [HEXAGON] Split huge 1D DMA Transfers into smaller transfers with legal sizes. (#10971)

This is an automated email from the ASF dual-hosted git repository.

kparzysz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new 03bbf14511 [HEXAGON] Split huge 1D DMA Transfers into smaller transfers with legal sizes. (#10971)
03bbf14511 is described below

commit 03bbf145116f0a3805ded0ddb873f8517220871a
Author: arangasa <76...@users.noreply.github.com>
AuthorDate: Tue Apr 12 19:28:26 2022 +0530

    [HEXAGON] Split huge 1D DMA Transfers into smaller transfers with legal sizes. (#10971)
---
 src/runtime/hexagon/hexagon/hexagon_user_dma.cc | 31 ++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/src/runtime/hexagon/hexagon/hexagon_user_dma.cc b/src/runtime/hexagon/hexagon/hexagon_user_dma.cc
index f943dfd5ab..6e286ae8b3 100644
--- a/src/runtime/hexagon/hexagon/hexagon_user_dma.cc
+++ b/src/runtime/hexagon/hexagon/hexagon_user_dma.cc
@@ -39,7 +39,7 @@ int init_hexagon_user_dma() {
   return DMA_SUCCESS;
 }
 
-int hexagon_user_dma_1d_sync(void* dst, void* src, uint32_t length) {
+int hexagon_user_dma_1d_sync_helper(void* dst, void* src, uint32_t length) {
 #if defined(__hexagon__) && __HEXAGON_ARCH__ >= 68
   static int config_dma = init_hexagon_user_dma();
   if (config_dma != DMA_SUCCESS) {
@@ -114,6 +114,35 @@ int hexagon_user_dma_1d_sync(void* dst, void* src, uint32_t length) {
 #endif
 }
 
+int hexagon_user_dma_1d_sync(void* dst, void* src, uint32_t length) {
+  // One DMA transfer can copy atmost DESC_LENGTH_MASK bytes.
+  // Make the common case quick.
+  if (length <= DESC_LENGTH_MASK) return hexagon_user_dma_1d_sync_helper(dst, src, length);
+
+  // Split big transfers into smaller transfers.
+  char* cast_src = static_cast<char*>(src);
+  char* cast_dst = static_cast<char*>(dst);
+  for (uint32_t i = 0; i < length;) {
+    // Ensure there is no overflow while updating i
+    uint32_t cur_len = std::min<uint32_t>(length - i, DESC_LENGTH_MASK);
+    int ret_val = hexagon_user_dma_1d_sync_helper(&cast_dst[i], &cast_src[i], cur_len);
+    if (ret_val != DMA_SUCCESS) return ret_val;
+    // 2 cases for new val for i:
+    // 1. length - i <= DESC_LENGTH_MASK (<= MAX_UINT)
+    //    new_i = i + (length - i) = length, no more iter
+    //            and no overflow (since (length - i) <= (MAX_UINT - i))
+    // 2. length - i > DESC_LENGTH_MASK
+    //    length > (i + DESC_LENGTH_MASK)
+    //    new_i = (i + DESC_LENGTH_MASK)
+    //    length > new_i for next iter, we're done
+    //    length - i > DESC_LENGTH_MASK
+    //    and length <= MAX_UINT,
+    //    so MAX_UINT >= length > DESC_LEN_MASK + i
+    //    MAX_UINT > (DESC_LEN_MASK + i), so no overflow
+    i += cur_len;
+  }
+  return DMA_SUCCESS;
+}
 }  // namespace hexagon
 }  // namespace runtime
 }  // namespace tvm