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

pkarashchenko pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 759898c0909342b625b12352e6df15eb8921008b
Author: ligd <liguidi...@xiaomi.com>
AuthorDate: Wed Feb 16 15:23:49 2022 +0800

    rptun: add ping rpmsg support
    
    Signed-off-by: ligd <liguidi...@xiaomi.com>
---
 drivers/rptun/Kconfig                        |   7 +
 drivers/rptun/Make.defs                      |   6 +-
 drivers/rptun/rptun.c                        |  60 ++++++---
 drivers/rptun/rptun.h                        |  44 ++++++
 drivers/rptun/{rpmsg_dump.c => rptun_dump.c} |  18 +--
 drivers/rptun/rptun_ping.c                   | 192 +++++++++++++++++++++++++++
 include/nuttx/rptun/openamp.h                |   2 -
 include/nuttx/rptun/rptun.h                  |  12 +-
 8 files changed, 308 insertions(+), 33 deletions(-)

diff --git a/drivers/rptun/Kconfig b/drivers/rptun/Kconfig
index c1a2415..327b20a 100644
--- a/drivers/rptun/Kconfig
+++ b/drivers/rptun/Kconfig
@@ -52,4 +52,11 @@ config RPTUN_PM
                goto RAM-retention mode, can't access from another CPU.
                So, we provide this method to resolve this.
 
+config RPTUN_PING
+       bool "rptun ping support"
+       default n
+       ---help---
+               This is for rptun debugging & profiling, create ping rpmsg
+               channel, user can use it to get send/recv speed & latency.
+
 endif # RPTUN
diff --git a/drivers/rptun/Make.defs b/drivers/rptun/Make.defs
index 8c79e0a..03446ec 100644
--- a/drivers/rptun/Make.defs
+++ b/drivers/rptun/Make.defs
@@ -22,7 +22,11 @@
 
 ifeq ($(CONFIG_RPTUN),y)
 
-CSRCS += rptun.c rpmsg_dump.c
+CSRCS += rptun.c rptun_dump.c
+
+ifeq ($(CONFIG_RPTUN_PING),y)
+CSRCS += rptun_ping.c
+endif
 
 DEPPATH += --dep-path rptun
 VPATH += :rptun
diff --git a/drivers/rptun/rptun.c b/drivers/rptun/rptun.c
index 624c927..949cf97 100644
--- a/drivers/rptun/rptun.c
+++ b/drivers/rptun/rptun.c
@@ -39,6 +39,8 @@
 #include <nuttx/wqueue.h>
 #include <metal/utilities.h>
 
+#include "rptun.h"
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -81,6 +83,9 @@ struct rptun_priv_s
 #ifdef CONFIG_RPTUN_PM
   bool                         stay;
 #endif
+#ifdef CONFIG_RPTUN_PING
+  struct rpmsg_endpoint        ping;
+#endif
 };
 
 struct rptun_bind_s
@@ -268,7 +273,7 @@ static inline void rptun_pm_action(FAR struct rptun_priv_s 
*priv,
       priv->stay = true;
     }
 
-  if (!stay && priv->stay && !rpmsg_buffer_nused(&priv->rvdev, false))
+  if (!stay && priv->stay && !rptun_buffer_nused(&priv->rvdev, false))
     {
       pm_relax(0, PM_IDLE);
       priv->stay = false;
@@ -785,6 +790,10 @@ static int rptun_dev_start(FAR struct remoteproc *rproc)
   rptun_unlock();
 
   virtqueue_enable_cb(priv->rvdev.svq);
+
+#ifdef CONFIG_RPTUN_PING
+  rptun_ping_init(&priv->rvdev, &priv->ping);
+#endif
   return 0;
 }
 
@@ -794,6 +803,10 @@ static int rptun_dev_stop(FAR struct remoteproc *rproc)
   FAR struct metal_list *node;
   FAR struct rptun_cb_s *cb;
 
+#ifdef CONFIG_RPTUN_PING
+  rptun_ping_deinit(&priv->ping);
+#endif
+
   /* Unregister callback from mbox */
 
   RPTUN_UNREGISTER_CALLBACK(priv->dev);
@@ -862,8 +875,13 @@ static int rptun_dev_ioctl(FAR struct file *filep, int cmd,
         rptun_dev_reset(&priv->rproc, RPTUN_STATUS_PANIC);
         break;
       case RPTUNIOC_DUMP:
-        rpmsg_dump(&priv->rvdev);
+        rptun_dump(&priv->rvdev);
+        break;
+#ifdef CONFIG_RPTUN_PING
+      case RPTUNIOC_PING:
+        rptun_ping(&priv->ping, (FAR const struct rptun_ping_s *)arg);
         break;
+#endif
       default:
         ret = -ENOTTY;
         break;
@@ -996,7 +1014,7 @@ int rpmsg_wait(FAR struct rpmsg_endpoint *ept, FAR sem_t 
*sem)
   FAR struct rptun_priv_s *priv;
   int ret;
 
-  if (!ept)
+  if (!ept || !sem)
     {
       return -EINVAL;
     }
@@ -1028,7 +1046,7 @@ int rpmsg_post(FAR struct rpmsg_endpoint *ept, FAR sem_t 
*sem)
   int semcount;
   int ret;
 
-  if (!ept)
+  if (!ept || !sem)
     {
       return -EINVAL;
     }
@@ -1052,21 +1070,6 @@ FAR const char *rpmsg_get_cpuname(FAR struct 
rpmsg_device *rdev)
   return RPTUN_GET_CPUNAME(priv->dev);
 }
 
-int rpmsg_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, bool rx)
-{
-  FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq;
-
-  if ((rpmsg_virtio_get_role(rvdev) == RPMSG_MASTER) ^ rx)
-    {
-      return vq->vq_ring.avail->idx - vq->vq_ring.used->idx;
-    }
-  else
-    {
-      return vq->vq_nentries -
-             (vq->vq_ring.avail->idx - vq->vq_ring.used->idx);
-    }
-}
-
 int rpmsg_register_callback(FAR void *priv_,
                             rpmsg_dev_cb_t device_created,
                             rpmsg_dev_cb_t device_destroy,
@@ -1295,7 +1298,22 @@ int rptun_panic(FAR const char *cpuname)
   return rptun_reset(cpuname, RPTUN_STATUS_PANIC);
 }
 
-void rptun_dump(void)
+int rptun_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, bool rx)
+{
+  FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq;
+
+  if ((rpmsg_virtio_get_role(rvdev) == RPMSG_MASTER) ^ rx)
+    {
+      return vq->vq_ring.avail->idx - vq->vq_ring.used->idx;
+    }
+  else
+    {
+      return vq->vq_nentries -
+             (vq->vq_ring.avail->idx - vq->vq_ring.used->idx);
+    }
+}
+
+void rptun_dump_all(void)
 {
   FAR struct metal_list *node;
 
@@ -1304,6 +1322,6 @@ void rptun_dump(void)
       FAR struct rptun_priv_s *priv =
           metal_container_of(node, struct rptun_priv_s, node);
 
-      rpmsg_dump(&priv->rvdev);
+      rptun_dump(&priv->rvdev);
     }
 }
diff --git a/drivers/rptun/rptun.h b/drivers/rptun/rptun.h
new file mode 100644
index 0000000..77038b6
--- /dev/null
+++ b/drivers/rptun/rptun.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+ * drivers/rptun/rptun.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __DRIVERS_RPTUN_RPTUN_H
+#define __DRIVERS_RPTUN_RPTUN_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/rptun/rptun.h>
+#include <openamp/open_amp.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int rptun_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, bool rx);
+void rptun_dump(FAR struct rpmsg_virtio_device *rvdev);
+
+int rptun_ping_init(FAR struct rpmsg_virtio_device *rvdev,
+                    FAR struct rpmsg_endpoint *ept);
+void rptun_ping_deinit(FAR struct rpmsg_endpoint *ept);
+int rptun_ping(FAR struct rpmsg_endpoint *ept,
+               FAR const struct rptun_ping_s *ping);
+
+#endif /* __DRIVERS_RPTUN_RPTUN_H */
diff --git a/drivers/rptun/rpmsg_dump.c b/drivers/rptun/rptun_dump.c
similarity index 90%
rename from drivers/rptun/rpmsg_dump.c
rename to drivers/rptun/rptun_dump.c
index 413431a..cb041cf 100644
--- a/drivers/rptun/rpmsg_dump.c
+++ b/drivers/rptun/rptun_dump.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * drivers/rptun/rpmsg_dump.c
+ * drivers/rptun/rptun_dump.c
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -28,11 +28,13 @@
 
 #include <rpmsg/rpmsg_internal.h>
 
+#include "rptun.h"
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
-static void rpmsg_dump_addr(FAR struct rpmsg_device *rdev,
+static void rptun_dump_addr(FAR struct rpmsg_device *rdev,
                             FAR void *addr, bool rx)
 {
   FAR struct rpmsg_hdr *hdr = addr;
@@ -47,7 +49,7 @@ static void rpmsg_dump_addr(FAR struct rpmsg_device *rdev,
     }
 }
 
-static void rpmsg_dump_buffer(FAR struct rpmsg_virtio_device *rvdev,
+static void rptun_dump_buffer(FAR struct rpmsg_virtio_device *rvdev,
                               bool rx)
 {
   FAR struct virtqueue *vq = rx ? rvdev->rvq : rvdev->svq;
@@ -56,7 +58,7 @@ static void rpmsg_dump_buffer(FAR struct rpmsg_virtio_device 
*rvdev,
   int num;
   int i;
 
-  num = rpmsg_buffer_nused(rvdev, rx);
+  num = rptun_buffer_nused(rvdev, rx);
   metal_log(METAL_LOG_INFO,
             "    %s buffer, total %d, pending %d\n",
             rx ? "RX" : "TX", vq->vq_nentries, num);
@@ -78,7 +80,7 @@ static void rpmsg_dump_buffer(FAR struct rpmsg_virtio_device 
*rvdev,
                                    vq->vq_ring.desc[desc_idx].addr);
       if (addr)
         {
-          rpmsg_dump_addr(&rvdev->rdev, addr, rx);
+          rptun_dump_addr(&rvdev->rdev, addr, rx);
         }
     }
 }
@@ -87,7 +89,7 @@ static void rpmsg_dump_buffer(FAR struct rpmsg_virtio_device 
*rvdev,
  * Public Functions
  ****************************************************************************/
 
-void rpmsg_dump(FAR struct rpmsg_virtio_device *rvdev)
+void rptun_dump(FAR struct rpmsg_virtio_device *rvdev)
 {
   FAR struct rpmsg_device *rdev = &rvdev->rdev;
   FAR struct rpmsg_endpoint *ept;
@@ -114,8 +116,8 @@ void rpmsg_dump(FAR struct rpmsg_virtio_device *rvdev)
 
   metal_log(METAL_LOG_INFO, "  rpmsg buffer list:\n");
 
-  rpmsg_dump_buffer(rvdev, true);
-  rpmsg_dump_buffer(rvdev, false);
+  rptun_dump_buffer(rvdev, true);
+  rptun_dump_buffer(rvdev, false);
 
   metal_mutex_release(&rdev->lock);
 }
diff --git a/drivers/rptun/rptun_ping.c b/drivers/rptun/rptun_ping.c
new file mode 100644
index 0000000..60055ce
--- /dev/null
+++ b/drivers/rptun/rptun_ping.c
@@ -0,0 +1,192 @@
+/****************************************************************************
+ * drivers/rptun/rptun_ping.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <inttypes.h>
+#include <string.h>
+
+#include "rptun.h"
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+
+#ifndef MIN
+  #define MIN(n,m)                  (((n) < (m)) ? (n) : (m))
+#endif
+
+#ifndef MAX
+  #define MAX(n,m)                  (((n) < (m)) ? (m) : (n))
+#endif
+
+#define RPTUN_PING_EPT_NAME         "rpmsg-ping"
+#define RPTUN_PING_SEND             1
+#define RPTUN_PING_SEND_NOACK       2
+#define RPTUN_PING_ACK              3
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+begin_packed_struct struct rptun_ping_msg_s
+{
+  uint32_t cmd;
+  uint32_t len;
+  uint64_t cookie;
+} end_packed_struct;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int rptun_ping_ept_cb(FAR struct rpmsg_endpoint *ept,
+                             FAR void *data, size_t len, uint32_t src,
+                             FAR void *priv)
+{
+  FAR struct rptun_ping_msg_s *msg = data;
+  FAR sem_t *sem = (FAR sem_t *)(uintptr_t)msg->cookie;
+
+  if (msg->cmd == RPTUN_PING_SEND)
+    {
+      msg->cmd = RPTUN_PING_ACK;
+      rpmsg_send(ept, msg, len);
+    }
+  else if (msg->cmd == RPTUN_PING_ACK)
+    {
+      nxsem_post(sem);
+    }
+
+  return 0;
+}
+
+static int rptun_ping_once(FAR struct rpmsg_endpoint *ept,
+                           int len, bool ack)
+{
+  FAR struct rptun_ping_msg_s *msg;
+  uint32_t space;
+  int ret;
+
+  msg = rpmsg_get_tx_payload_buffer(ept, &space, true);
+  if (!msg)
+    {
+      return -ENOMEM;
+    }
+
+  len = MAX(len, sizeof(struct rptun_ping_msg_s));
+  len = MIN(len, space);
+
+  memset(msg, 0, len);
+
+  if (ack)
+    {
+      sem_t sem;
+
+      msg->cmd    = RPTUN_PING_SEND;
+      msg->len    = len;
+      msg->cookie = (uintptr_t)&sem;
+
+      nxsem_init(&sem, 0, 0);
+      nxsem_set_protocol(&sem, SEM_PRIO_NONE);
+
+      ret = rpmsg_send_nocopy(ept, msg, len);
+      if (ret >= 0)
+        {
+          nxsem_wait_uninterruptible(&sem);
+        }
+
+      nxsem_destroy(&sem);
+    }
+  else
+    {
+      msg->cmd = RPTUN_PING_SEND_NOACK;
+      msg->len = len;
+      ret = rpmsg_send_nocopy(ept, msg, len);
+    }
+
+  return ret;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int rptun_ping(FAR struct rpmsg_endpoint *ept,
+               FAR const struct rptun_ping_s *ping)
+{
+  uint32_t min = UINT32_MAX;
+  uint32_t max = 0;
+  uint64_t total = 0;
+  struct timespec ts;
+  int i;
+
+  if (!ept || !ping || ping->times <= 0)
+    {
+      return -EINVAL;
+    }
+
+  for (i = 0; i < ping->times; i++)
+    {
+      uint32_t tm = up_perf_gettime();
+
+      int ret = rptun_ping_once(ept, ping->len, ping->ack);
+      if (ret < 0)
+        {
+          return ret;
+        }
+
+      tm     = up_perf_gettime() - tm;
+      min    = MIN(min, tm);
+      max    = MAX(max, tm);
+      total += tm;
+    }
+
+  syslog(LOG_INFO, "current CPU freq: %" PRIu32 ", ping times: %d\n",
+                    up_perf_getfreq(), ping->times);
+
+  up_perf_convert(total / ping->times, &ts);
+  syslog(LOG_INFO, "avg: s %" PRIu32 ", ns %ld\n", ts.tv_sec, ts.tv_nsec);
+
+  up_perf_convert(min, &ts);
+  syslog(LOG_INFO, "min: s %" PRIu32 ", ns %ld\n", ts.tv_sec, ts.tv_nsec);
+
+  up_perf_convert(max, &ts);
+  syslog(LOG_INFO, "max: s %" PRIu32 ", ns %ld\n", ts.tv_sec, ts.tv_nsec);
+
+  return 0;
+}
+
+int rptun_ping_init(FAR struct rpmsg_virtio_device *rvdev,
+                    FAR struct rpmsg_endpoint *ept)
+{
+  return rpmsg_create_ept(ept, &rvdev->rdev, RPTUN_PING_EPT_NAME,
+                          RPMSG_ADDR_ANY, RPMSG_ADDR_ANY,
+                          rptun_ping_ept_cb, NULL);
+}
+
+void rptun_ping_deinit(FAR struct rpmsg_endpoint *ept)
+{
+  rpmsg_destroy_ept(ept);
+}
diff --git a/include/nuttx/rptun/openamp.h b/include/nuttx/rptun/openamp.h
index 4188c41..833c477 100644
--- a/include/nuttx/rptun/openamp.h
+++ b/include/nuttx/rptun/openamp.h
@@ -58,8 +58,6 @@ int rpmsg_wait(FAR struct rpmsg_endpoint *ept, FAR sem_t 
*sem);
 int rpmsg_post(FAR struct rpmsg_endpoint *ept, FAR sem_t *sem);
 
 const char *rpmsg_get_cpuname(FAR struct rpmsg_device *rdev);
-int rpmsg_buffer_nused(FAR struct rpmsg_virtio_device *rvdev, bool rx);
-void rpmsg_dump(FAR struct rpmsg_virtio_device *rvdev);
 
 int rpmsg_register_callback(FAR void *priv,
                             rpmsg_dev_cb_t device_created,
diff --git a/include/nuttx/rptun/rptun.h b/include/nuttx/rptun/rptun.h
index eb31847..95fba39 100644
--- a/include/nuttx/rptun/rptun.h
+++ b/include/nuttx/rptun/rptun.h
@@ -41,6 +41,7 @@
 #define RPTUNIOC_RESET              _RPTUNIOC(3)
 #define RPTUNIOC_PANIC              _RPTUNIOC(4)
 #define RPTUNIOC_DUMP               _RPTUNIOC(5)
+#define RPTUNIOC_PING               _RPTUNIOC(6)
 
 #define RPTUN_NOTIFY_ALL            (UINT32_MAX - 0)
 
@@ -303,6 +304,15 @@ struct rptun_dev_s
   FAR const struct rptun_ops_s *ops;
 };
 
+/* used for ioctl RPTUNIOC_PING */
+
+struct rptun_ping_s
+{
+  int  times;
+  int  len;
+  bool ack;
+};
+
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -319,7 +329,7 @@ int rptun_initialize(FAR struct rptun_dev_s *dev);
 int rptun_boot(FAR const char *cpuname);
 int rptun_reset(FAR const char *cpuname, int value);
 int rptun_panic(FAR const char *cpuname);
-void rptun_dump(void);
+void rptun_dump_all(void);
 
 #ifdef __cplusplus
 }

Reply via email to