This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit c79646d93a647785448da77282338b5b9585716c Author: Yongrong Wang <[email protected]> AuthorDate: Wed Oct 18 20:39:01 2023 +0800 net/vsock: add vsock local transport support The vsock local transport can be used to communicate with the local cpu just like the local socket, in Linux, this transport is used for the test Signed-off-by: Bowen Wang <[email protected]> Signed-off-by: Yongrong Wang <[email protected]> --- net/vsock/CMakeLists.txt | 4 + net/vsock/Kconfig | 6 ++ net/vsock/Make.defs | 4 + net/vsock/vsock.h | 4 + net/vsock/vsock_local.c | 264 +++++++++++++++++++++++++++++++++++++++++++++++ net/vsock/vsock_sockif.c | 8 ++ 6 files changed, 290 insertions(+) diff --git a/net/vsock/CMakeLists.txt b/net/vsock/CMakeLists.txt index 5895c124a2d..8d7dd006db8 100644 --- a/net/vsock/CMakeLists.txt +++ b/net/vsock/CMakeLists.txt @@ -31,5 +31,9 @@ if(CONFIG_NET_VSOCK) list(APPEND SRCS vsock_vhost.c) endif() + if(CONFIG_NET_VSOCK_LOCAL) + list(APPEND SRCS vsock_local.c) + endif() + target_sources(net PRIVATE ${SRCS}) endif() diff --git a/net/vsock/Kconfig b/net/vsock/Kconfig index f94cccf7fd6..36de4c08e61 100644 --- a/net/vsock/Kconfig +++ b/net/vsock/Kconfig @@ -52,4 +52,10 @@ config NET_VSOCK_VHOST select DRIVERS_VHOST select NET_VSOCK +config NET_VSOCK_LOCAL + bool "Virtual Socket Local Transport Layer Support" + default n + select NET_VSOCK + select OPENAMP + endmenu # Virtual Socket networking stack API diff --git a/net/vsock/Make.defs b/net/vsock/Make.defs index 03b06e052de..fa272c6e1b0 100644 --- a/net/vsock/Make.defs +++ b/net/vsock/Make.defs @@ -32,6 +32,10 @@ ifeq ($(CONFIG_NET_VSOCK_VHOST),y) SOCK_CSRCS += vsock_vhost.c endif +ifeq ($(CONFIG_NET_VSOCK_LOCAL),y) + SOCK_CSRCS += vsock_local.c +endif + # Include Virtio Socket build support DEPPATH += --dep-path vsock diff --git a/net/vsock/vsock.h b/net/vsock/vsock.h index ca6f21f73a1..546e4325a70 100644 --- a/net/vsock/vsock.h +++ b/net/vsock/vsock.h @@ -136,6 +136,10 @@ int vsock_virtio_initialize(void); int vsock_vhost_initialize(void); #endif +#ifdef CONFIG_NET_VSOCK_LOCAL +int vsock_local_initialize(void); +#endif + #ifdef __cplusplus } #endif diff --git a/net/vsock/vsock_local.c b/net/vsock/vsock_local.c new file mode 100644 index 00000000000..4dfd34cd23a --- /dev/null +++ b/net/vsock/vsock_local.c @@ -0,0 +1,264 @@ +/**************************************************************************** + * net/vsock/vsock_local.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 <assert.h> +#include <stdio.h> + +#include <nuttx/list.h> +#include <nuttx/nuttx.h> +#include <nuttx/spinlock.h> +#include <nuttx/semaphore.h> + +#include "vsock/vsock.h" +#include "vsock/vsock_virtio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct vsock_local_priv_s +{ + struct vsock_transport_s t; + + spinlock_t buf_lock; + struct list_node buf_list; + int buf_num; + sem_t buf_sem; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static uint64_t vsock_local_get_localcid(FAR struct vsock_transport_s *t); +static uint64_t vsock_local_get_remotecid(FAR struct vsock_transport_s *t); +static int vsock_local_alloc_pkt(FAR struct vsock_transport_s *t, + FAR struct vsock_pkt_s *pkt, + size_t data_len); +static ssize_t vsock_local_send_pkt(FAR struct vsock_transport_s *t, + FAR struct vsock_pkt_s *pkt); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct vsock_transport_ops_s g_vsock_local_transport_ops = +{ + .get_localcid = vsock_local_get_localcid, + .get_remotecid = vsock_local_get_remotecid, + .alloc_pkt = vsock_local_alloc_pkt, + .send_pkt = vsock_local_send_pkt, +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vsock_virtio_trans2priv + ****************************************************************************/ + +static FAR struct vsock_local_priv_s * +vsock_virtio_trans2priv(FAR struct vsock_transport_s *t) +{ + return container_of(t, struct vsock_local_priv_s, t); +} + +/**************************************************************************** + * Name: vsock_local_get_localcid + ****************************************************************************/ + +static uint64_t vsock_local_get_localcid(FAR struct vsock_transport_s *t) +{ + return VMADDR_CID_LOCAL; +} + +/**************************************************************************** + * Name: vsock_local_get_remotecid + ****************************************************************************/ + +static uint64_t vsock_local_get_remotecid(FAR struct vsock_transport_s *t) +{ + return VMADDR_CID_LOCAL; +} + +/**************************************************************************** + * Name: vsock_local_alloc_pkt + ****************************************************************************/ + +static int vsock_local_alloc_pkt(FAR struct vsock_transport_s *t, + FAR struct vsock_pkt_s *pkt, + size_t data_len) +{ + FAR struct vsock_local_priv_s *priv = vsock_virtio_trans2priv(t); + irqstate_t flags; + size_t vbcnt; + + data_len += VIRTIO_VSOCK_HDR_LEN; + vbcnt = div_round_up(data_len, CONFIG_NET_VSOCK_PKT_BUFSIZE); + vbcnt = MIN(vbcnt, CONFIG_NET_VSOCK_PKT_BUFCOUNT); + + for (; ; ) + { + flags = spin_lock_irqsave(&priv->buf_lock); + if (priv->buf_num > 0) + { + size_t i; + + vbcnt = MIN(vbcnt, priv->buf_num); + for (i = 0; i < vbcnt; i++) + { + pkt->vb[i].buf = list_remove_head(&priv->buf_list); + DEBUGASSERT(pkt->vb[i].buf != NULL); + if (data_len >= CONFIG_NET_VSOCK_PKT_BUFSIZE) + { + pkt->vb[i].len = CONFIG_NET_VSOCK_PKT_BUFSIZE; + data_len -= CONFIG_NET_VSOCK_PKT_BUFSIZE; + } + else + { + pkt->vb[i].len = data_len; + } + + pkt->len += pkt->vb[i].len; + } + + priv->buf_num -= vbcnt; + spin_unlock_irqrestore(&priv->buf_lock, flags); + + pkt->vbcnt = vbcnt; + pkt->vbidx = 0; + pkt->vboff = VIRTIO_VSOCK_HDR_LEN; + return 0; + } + + spin_unlock_irqrestore(&priv->buf_lock, flags); + nxsem_wait(&priv->buf_sem); + } +} + +/**************************************************************************** + * Name: vsock_local_send_pkt + ****************************************************************************/ + +static ssize_t vsock_local_send_pkt(FAR struct vsock_transport_s *t, + FAR struct vsock_pkt_s *pkt) +{ + FAR struct vsock_local_priv_s *priv = vsock_virtio_trans2priv(t); + FAR struct vsock_hdr_s *hdr = vsock_pkt2hdr(pkt); + ssize_t len = hdr->len; + irqstate_t flags; + size_t i; + + pkt->vbidx = 0; + pkt->vboff = VIRTIO_VSOCK_HDR_LEN; + vsock_recv_pkt(&priv->t, pkt); + + flags = spin_lock_irqsave(&priv->buf_lock); + for (i = 0; i < pkt->vbcnt; i++) + { + list_add_head(&priv->buf_list, pkt->vb[i].buf); + priv->buf_num++; + } + + spin_unlock_irqrestore(&priv->buf_lock, flags); + vsock_post(&priv->buf_sem); + return len; +} + +/**************************************************************************** + * Name: vsock_local_buf_init + ****************************************************************************/ + +static int vsock_local_buf_init(FAR struct vsock_local_priv_s *priv) +{ + FAR char *buf; + size_t size; + int i; + + spin_lock_init(&priv->buf_lock); + list_initialize(&priv->buf_list); + nxsem_init(&priv->buf_sem, 0, 0); + + priv->buf_num = CONFIG_NET_VSOCK_VQ_BUFCOUNT; + size = VIRTIO_VSOCK_HDR_LEN + CONFIG_NET_VSOCK_PKT_BUFSIZE; + buf = kmm_memalign(16, priv->buf_num * size); + if (buf == NULL) + { + nxsem_destroy(&priv->buf_sem); + return -ENOMEM; + } + + for (i = 0; i < priv->buf_num; i++) + { + list_add_tail(&priv->buf_list, (FAR struct list_node *)buf); + buf += size; + } + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vsock_local_initialize + ****************************************************************************/ + +int vsock_local_initialize(void) +{ + FAR struct vsock_local_priv_s *priv; + int ret; + + priv = kmm_zalloc(sizeof(*priv)); + if (priv == NULL) + { + vrterr("No enough memory\n"); + return -ENOMEM; + } + + ret = vsock_local_buf_init(priv); + if (ret < 0) + { + vrterr("vsock_local_buf_init failed, ret=%d\n", ret); + goto err_with_priv; + } + + /* Register Virtual Socket Local transport */ + + priv->t.ops = &g_vsock_local_transport_ops; + vsock_transport_register(&priv->t); + return ret; + +err_with_priv: + kmm_free(priv); + return ret; +} diff --git a/net/vsock/vsock_sockif.c b/net/vsock/vsock_sockif.c index cc7089407c7..a7506eaed81 100644 --- a/net/vsock/vsock_sockif.c +++ b/net/vsock/vsock_sockif.c @@ -2475,5 +2475,13 @@ int vsock_initialize(void) } #endif +#ifdef CONFIG_NET_VSOCK_LOCAL + ret = vsock_local_initialize(); + if (ret < 0) + { + vrterr("ERROR: vsock_local_initialize failed, ret=%d\n", ret); + } +#endif + return ret; }
