diff options
author | Harald Welte <laforge@osmocom.org> | 2024-03-16 18:15:47 +0100 |
---|---|---|
committer | Harald Welte <laforge@osmocom.org> | 2024-03-16 21:08:22 +0100 |
commit | 3c133dc3863415ca86c3e453e664667aea44cf13 (patch) | |
tree | 9cba5e597096a9f118e79647ac00e533e5460e4c /src | |
parent | 3af73977ddd88a43da3457057152a34246d2a967 (diff) |
osmo-bts-virtual: Port over to osmo_io
osmo_io permits us to use the io_uring backend, which should
significantly speed up the many small read/writes we're doing
on virt-um.
Change-Id: Icfe42da00fd446c38090055e2baa5d5e0ae5b70c
Diffstat (limited to 'src')
-rw-r--r-- | src/osmo-bts-virtual/osmo_mcast_sock.c | 112 | ||||
-rw-r--r-- | src/osmo-bts-virtual/osmo_mcast_sock.h | 28 | ||||
-rw-r--r-- | src/osmo-bts-virtual/scheduler_virtbts.c | 2 | ||||
-rw-r--r-- | src/osmo-bts-virtual/virtual_um.c | 49 |
4 files changed, 100 insertions, 91 deletions
diff --git a/src/osmo-bts-virtual/osmo_mcast_sock.c b/src/osmo-bts-virtual/osmo_mcast_sock.c index 3e565142..c802e02d 100644 --- a/src/osmo-bts-virtual/osmo_mcast_sock.c +++ b/src/osmo-bts-virtual/osmo_mcast_sock.c @@ -3,6 +3,7 @@ #include <netdb.h> #include <osmocom/core/socket.h> #include <osmocom/core/select.h> +#include <osmocom/core/osmo_io.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -10,102 +11,133 @@ #include <unistd.h> #include "osmo_mcast_sock.h" +static void noop_write_cb(struct osmo_io_fd *iofd, int res, struct msgb *msg) +{ + /* nothing */ +} + +static const struct osmo_io_ops srv_ioops = { + /* no read call-back as we don't read from the socket */ + /* libosmcoore before change-id I0c071a29e508884bac331ada5e510bbfcf440bbf requires write call-back + * even if we don't care about it */ + .write_cb = noop_write_cb, +}; + /* server socket is what we use for transmission. It is not subscribed * to a multicast group or locally bound, but it is just a normal UDP * socket that's connected to the remote mcast group + port */ -int mcast_server_sock_setup(struct osmo_fd *ofd, const char* tx_mcast_group, - uint16_t tx_mcast_port, bool loopback) +static struct osmo_io_fd * +mcast_server_sock_setup(void *ctx, const char *tx_mcast_group, uint16_t tx_mcast_port, bool loopback) { - int rc; + int rc, fd; unsigned int flags = OSMO_SOCK_F_CONNECT | OSMO_SOCK_F_UDP_REUSEADDR; + struct osmo_io_fd *iofd; if (!loopback) flags |= OSMO_SOCK_F_NO_MCAST_LOOP; /* setup mcast server socket */ - rc = osmo_sock_init_ofd(ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, - tx_mcast_group, tx_mcast_port, flags); + rc = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP, tx_mcast_group, tx_mcast_port, flags); if (rc < 0) { perror("Failed to create Multicast Server Socket"); - return rc; + return NULL; } + fd = rc; - return 0; + iofd = osmo_iofd_setup(ctx, rc, "mcast_server_sock", OSMO_IO_FD_MODE_READ_WRITE, &srv_ioops, NULL); + if (!iofd) { + close(fd); + return NULL; + } + + osmo_iofd_register(iofd, -1); + return iofd; +} + +static void mcast_sock_read_cb(struct osmo_io_fd *iofd, int res, struct msgb *msg) +{ + struct mcast_bidir_sock *bidir_sock = osmo_iofd_get_data(iofd); + bidir_sock->read_cb(res, msg, bidir_sock->data); } +const struct osmo_io_ops clnt_ioops = { + .read_cb = mcast_sock_read_cb, + /* no write call-back as we don't write to the socket */ +}; + /* the client socket is what we use for reception. It is a UDP socket * that's bound to the GSMTAP UDP port and subscribed to the respective * multicast group */ -int mcast_client_sock_setup(struct osmo_fd *ofd, const char *mcast_group, uint16_t mcast_port, - int (*fd_rx_cb)(struct osmo_fd *ofd, unsigned int what), - void *osmo_fd_data) +static struct osmo_io_fd * +mcast_client_sock_setup(void *ctx, const char *mcast_group, uint16_t mcast_port, + void (*read_cb)(int rc, struct msgb *msg, void *data)) { - int rc; + int rc, fd; unsigned int flags = OSMO_SOCK_F_BIND | OSMO_SOCK_F_NO_MCAST_ALL | OSMO_SOCK_F_UDP_REUSEADDR; - - osmo_fd_setup(ofd, -1, OSMO_FD_READ, fd_rx_cb, osmo_fd_data, 0); + struct osmo_io_fd *iofd; /* Create mcast client socket */ - rc = osmo_sock_init_ofd(ofd, AF_INET, SOCK_DGRAM, IPPROTO_UDP, - NULL, mcast_port, flags); + rc = osmo_sock_init(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, mcast_port, flags); if (rc < 0) { perror("Could not create mcast client socket"); - return rc; + return NULL; } + fd = rc; /* Configure and join the multicast group */ - rc = osmo_sock_mcast_subscribe(ofd->fd, mcast_group); + rc = osmo_sock_mcast_subscribe(fd, mcast_group); if (rc < 0) { perror("Failed to join to mcast goup"); - osmo_fd_close(ofd); - return rc; + close(fd); + return NULL; + } + + iofd = osmo_iofd_setup(ctx, fd, "mcast_client_sock", OSMO_IO_FD_MODE_READ_WRITE, &clnt_ioops, ctx); + if (!iofd) { + close(fd); + return NULL; } - return 0; + osmo_iofd_register(iofd, -1); + return iofd; } struct mcast_bidir_sock * mcast_bidir_sock_setup(void *ctx, const char *tx_mcast_group, uint16_t tx_mcast_port, const char *rx_mcast_group, uint16_t rx_mcast_port, bool loopback, - int (*fd_rx_cb)(struct osmo_fd *ofd, unsigned int what), - void *osmo_fd_data) + void (*read_cb)(int rc, struct msgb *msg, void *data), + void *data) { struct mcast_bidir_sock *bidir_sock = talloc(ctx, struct mcast_bidir_sock); - int rc; if (!bidir_sock) return NULL; - rc = mcast_client_sock_setup(&bidir_sock->rx_ofd, rx_mcast_group, rx_mcast_port, - fd_rx_cb, osmo_fd_data); - if (rc < 0) { + bidir_sock->read_cb = read_cb; + bidir_sock->data = data; + + bidir_sock->rx_iofd = mcast_client_sock_setup(bidir_sock, rx_mcast_group, rx_mcast_port, read_cb); + if (!bidir_sock->rx_iofd) { talloc_free(bidir_sock); return NULL; } - rc = mcast_server_sock_setup(&bidir_sock->tx_ofd, tx_mcast_group, tx_mcast_port, loopback); - if (rc < 0) { - osmo_fd_close(&bidir_sock->rx_ofd); + bidir_sock->tx_iofd = mcast_server_sock_setup(bidir_sock, tx_mcast_group, tx_mcast_port, loopback); + if (!bidir_sock->tx_iofd) { + osmo_iofd_free(bidir_sock->rx_iofd); talloc_free(bidir_sock); return NULL; } return bidir_sock; - -} - -int mcast_bidir_sock_tx(struct mcast_bidir_sock *bidir_sock, const uint8_t *data, - unsigned int data_len) -{ - return send(bidir_sock->tx_ofd.fd, data, data_len, 0); } -int mcast_bidir_sock_rx(struct mcast_bidir_sock *bidir_sock, uint8_t *buf, unsigned int buf_len) +int mcast_bidir_sock_tx_msg(struct mcast_bidir_sock *bidir_sock, struct msgb *msg) { - return recv(bidir_sock->rx_ofd.fd, buf, buf_len, 0); + return osmo_iofd_write_msgb(bidir_sock->tx_iofd, msg); } void mcast_bidir_sock_close(struct mcast_bidir_sock *bidir_sock) { - osmo_fd_close(&bidir_sock->tx_ofd); - osmo_fd_close(&bidir_sock->rx_ofd); + osmo_iofd_free(bidir_sock->tx_iofd); + osmo_iofd_free(bidir_sock->rx_iofd); talloc_free(bidir_sock); } diff --git a/src/osmo-bts-virtual/osmo_mcast_sock.h b/src/osmo-bts-virtual/osmo_mcast_sock.h index aa2013c6..5f68415b 100644 --- a/src/osmo-bts-virtual/osmo_mcast_sock.h +++ b/src/osmo-bts-virtual/osmo_mcast_sock.h @@ -4,26 +4,20 @@ #include <stdint.h> #include <netinet/in.h> #include <osmocom/core/select.h> +#include <osmocom/core/osmo_io.h> struct mcast_bidir_sock { - struct osmo_fd tx_ofd; - struct osmo_fd rx_ofd; + struct osmo_io_fd *tx_iofd; + struct osmo_io_fd *rx_iofd; + void (*read_cb)(int rc, struct msgb *msg, void *data); + void *data; }; -struct mcast_bidir_sock *mcast_bidir_sock_setup(void *ctx, - const char *tx_mcast_group, uint16_t tx_mcast_port, - const char *rx_mcast_group, uint16_t rx_mcast_port, bool loopback, - int (*fd_rx_cb)(struct osmo_fd *ofd, unsigned int what), - void *osmo_fd_data); +struct mcast_bidir_sock * +mcast_bidir_sock_setup(void *ctx, const char *tx_mcast_group, uint16_t tx_mcast_port, + const char *rx_mcast_group, uint16_t rx_mcast_port, bool loopback, + void (*read_cb)(int rc, struct msgb *msg, void *data), + void *data); -int mcast_server_sock_setup(struct osmo_fd *ofd, const char *tx_mcast_group, - uint16_t tx_mcast_port, bool loopback); - -int mcast_client_sock_setup(struct osmo_fd *ofd, const char *mcast_group, uint16_t mcast_port, - int (*fd_rx_cb)(struct osmo_fd *ofd, unsigned int what), - void *osmo_fd_data); - -int mcast_bidir_sock_tx(struct mcast_bidir_sock *bidir_sock, const uint8_t *data, unsigned int data_len); -int mcast_bidir_sock_rx(struct mcast_bidir_sock *bidir_sock, uint8_t *buf, unsigned int buf_len); +int mcast_bidir_sock_tx_msg(struct mcast_bidir_sock *bidir_sock, struct msgb *msg); void mcast_bidir_sock_close(struct mcast_bidir_sock* bidir_sock); - diff --git a/src/osmo-bts-virtual/scheduler_virtbts.c b/src/osmo-bts-virtual/scheduler_virtbts.c index 1bcec063..87596a79 100644 --- a/src/osmo-bts-virtual/scheduler_virtbts.c +++ b/src/osmo-bts-virtual/scheduler_virtbts.c @@ -102,8 +102,6 @@ static void _tx_to_virt_um(struct l1sched_ts *l1ts, if (rc < 0) LOGL1SB(DL1P, LOGL_ERROR, l1ts, br, "GSMTAP msg could not send to virtual Um: %s\n", strerror(-rc)); - else if (rc == 0) - bts_shutdown(trx->bts, "VirtPHY write socket died\n"); else LOGL1SB(DL1P, LOGL_DEBUG, l1ts, br, "Sending GSMTAP message to virtual Um\n"); diff --git a/src/osmo-bts-virtual/virtual_um.c b/src/osmo-bts-virtual/virtual_um.c index 44747fa6..711e75d3 100644 --- a/src/osmo-bts-virtual/virtual_um.c +++ b/src/osmo-bts-virtual/virtual_um.c @@ -32,33 +32,15 @@ #include <errno.h> /** - * Virtual UM interface file descriptor callback. - * Should be called by select.c when the fd is ready for reading. + * Virtual UM interface file descriptor read callback. */ -static int virt_um_fd_cb(struct osmo_fd *ofd, unsigned int what) +static void virt_um_read_cb(int rc, struct msgb *msg, void *data) { - struct virt_um_inst *vui = ofd->data; + struct virt_um_inst *vui = data; + msg->l1h = msg->data; - if (what & OSMO_FD_READ) { - struct msgb *msg = msgb_alloc(VIRT_UM_MSGB_SIZE, "Virtual UM Rx"); - int rc; - - /* read message from fd into message buffer */ - rc = mcast_bidir_sock_rx(vui->mcast_sock, msgb_data(msg), msgb_tailroom(msg)); - if (rc > 0) { - msgb_put(msg, rc); - msg->l1h = msgb_data(msg); - /* call the l1 callback function for a received msg */ - vui->recv_cb(vui, msg); - } else if (rc == 0) { - vui->recv_cb(vui, NULL); - osmo_fd_close(ofd); - } else - perror("Read from multicast socket"); - - } - - return 0; + /* call the l1 callback function for a received msg */ + vui->recv_cb(vui, msg); } struct virt_um_inst *virt_um_init(void *ctx, char *tx_mcast_group, uint16_t tx_mcast_port, @@ -69,7 +51,7 @@ struct virt_um_inst *virt_um_init(void *ctx, char *tx_mcast_group, uint16_t tx_m int rc; vui->mcast_sock = mcast_bidir_sock_setup(ctx, tx_mcast_group, tx_mcast_port, - rx_mcast_group, rx_mcast_port, 1, virt_um_fd_cb, vui); + rx_mcast_group, rx_mcast_port, 1, virt_um_read_cb, vui); if (!vui->mcast_sock) { perror("Unable to create VirtualUm multicast socket"); talloc_free(vui); @@ -79,7 +61,8 @@ struct virt_um_inst *virt_um_init(void *ctx, char *tx_mcast_group, uint16_t tx_m /* -1 means default, i.e. no TTL explicitly configured in VTY */ if (ttl >= 0) { - rc = osmo_sock_mcast_ttl_set(vui->mcast_sock->tx_ofd.fd, ttl); + int txfd = osmo_iofd_get_fd(vui->mcast_sock->tx_iofd); + rc = osmo_sock_mcast_ttl_set(txfd, ttl); if (rc < 0) { perror("Cannot set TTL of Virtual Um transmit socket"); goto out_close; @@ -87,12 +70,14 @@ struct virt_um_inst *virt_um_init(void *ctx, char *tx_mcast_group, uint16_t tx_m } if (dev_name) { - rc = osmo_sock_mcast_iface_set(vui->mcast_sock->tx_ofd.fd, dev_name); + int txfd = osmo_iofd_get_fd(vui->mcast_sock->tx_iofd); + rc = osmo_sock_mcast_iface_set(txfd, dev_name); if (rc < 0) { perror("Cannot bind multicast tx to given device"); goto out_close; } - rc = osmo_sock_mcast_iface_set(vui->mcast_sock->rx_ofd.fd, dev_name); + int rxfd = osmo_iofd_get_fd(vui->mcast_sock->rx_iofd); + rc = osmo_sock_mcast_iface_set(rxfd, dev_name); if (rc < 0) { perror("Cannot bind multicast rx to given device"); goto out_close; @@ -120,11 +105,11 @@ int virt_um_write_msg(struct virt_um_inst *vui, struct msgb *msg) { int rc; - rc = mcast_bidir_sock_tx(vui->mcast_sock, msgb_data(msg), - msgb_length(msg)); - if (rc < 0) + rc = mcast_bidir_sock_tx_msg(vui->mcast_sock, msg); + if (rc < 0) { + msgb_free(msg); rc = -errno; - msgb_free(msg); + } return rc; } |