SLiRP: Introduce a new queue for packets received immediately transmssion - those are now collected into said queue and processed immediately after, improves SLiRP operation.

This commit is contained in:
OBattler
2025-02-19 11:12:49 +01:00
parent 6328d51108
commit 655a007579
3 changed files with 90 additions and 19 deletions

View File

@@ -57,7 +57,7 @@
/* Queue size must be a power of 2 */
#define NET_QUEUE_LEN 16
#define NET_QUEUE_LEN_MASK (NET_QUEUE_LEN - 1)
#define NET_QUEUE_COUNT 3
#define NET_QUEUE_COUNT 4
#define NET_CARD_MAX 4
#define NET_HOST_INTF_MAX 64
@@ -84,9 +84,10 @@ enum {
};
enum {
NET_QUEUE_RX = 0,
NET_QUEUE_TX_VM = 1,
NET_QUEUE_TX_HOST = 2
NET_QUEUE_RX = 0,
NET_QUEUE_TX_VM = 1,
NET_QUEUE_TX_HOST = 2,
NET_QUEUE_RX_ON_TX = 3
};
typedef struct netcard_conf_t {
@@ -199,7 +200,10 @@ extern const device_t *network_card_getdevice(int);
extern int network_tx_pop(netcard_t *card, netpkt_t *out_pkt);
extern int network_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size);
extern int network_rx_put(netcard_t *card, uint8_t *bufp, int len);
extern int network_rx_on_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size);
extern int network_rx_on_tx_put(netcard_t *card, uint8_t *bufp, int len);
extern int network_rx_put_pkt(netcard_t *card, netpkt_t *pkt);
extern int network_rx_on_tx_put_pkt(netcard_t *card, netpkt_t *pkt);
#ifdef EMU_DEVICE_H
/* 3Com Etherlink */

View File

@@ -60,16 +60,19 @@ enum {
};
typedef struct net_slirp_t {
Slirp *slirp;
uint8_t mac_addr[6];
netcard_t *card; /* netcard attached to us */
thread_t *poll_tid;
net_evt_t tx_event;
net_evt_t stop_event;
netpkt_t pkt;
netpkt_t pkt_tx_v[SLIRP_PKT_BATCH];
Slirp * slirp;
uint8_t mac_addr[6];
netcard_t * card; /* netcard attached to us */
thread_t * poll_tid;
net_evt_t rx_event;
net_evt_t tx_event;
net_evt_t stop_event;
netpkt_t pkt;
netpkt_t pkt_tx_v[SLIRP_PKT_BATCH];
int during_tx;
int recv_on_tx;
#ifdef _WIN32
HANDLE sock_event;
HANDLE sock_event;
#else
uint32_t pfd_len;
uint32_t pfd_size;
@@ -184,7 +187,11 @@ net_slirp_send_packet(const void *qp, size_t pkt_len, void *opaque)
memcpy(slirp->pkt.data, (uint8_t *) qp, pkt_len);
slirp->pkt.len = pkt_len;
network_rx_put_pkt(slirp->card, &slirp->pkt);
if (slirp->during_tx) {
network_rx_on_tx_put_pkt(slirp->card, &slirp->pkt);
slirp->recv_on_tx = 1;
} else
network_rx_put_pkt(slirp->card, &slirp->pkt);
return pkt_len;
}
@@ -324,6 +331,21 @@ net_slirp_in_available(void *priv)
net_event_set(&slirp->tx_event);
}
static void
net_slirp_rx_deferred_packets(net_slirp_t *slirp)
{
int packets = 0;
if (slirp->recv_on_tx) {
do {
packets = network_rx_on_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH);
for (int i = 0; i < packets; i++)
network_rx_put_pkt(slirp->card, &(slirp->pkt_tx_v[i]));
} while (packets > 0);
slirp->recv_on_tx = 0;
}
}
#ifdef _WIN32
static void
net_slirp_thread(void *priv)
@@ -352,10 +374,13 @@ net_slirp_thread(void *priv)
case NET_EVENT_TX:
{
slirp->during_tx = 1;
int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH);
for (int i = 0; i < packets; i++) {
for (int i = 0; i < packets; i++)
net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len);
}
slirp->during_tx = 0;
net_slirp_rx_deferred_packets(slirp);
}
break;
@@ -398,10 +423,13 @@ net_slirp_thread(void *priv)
if (slirp->pfd[NET_EVENT_TX].revents & POLLIN) {
net_event_clear(&slirp->tx_event);
slirp->during_tx = 1;
int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH);
for (int i = 0; i < packets; i++) {
for (int i = 0; i < packets; i++)
net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len);
}
slirp->during_tx = 0;
net_slirp_rx_deferred_packets(slirp);
}
}
@@ -477,6 +505,7 @@ net_slirp_init(const netcard_t *card, const uint8_t *mac_addr, UNUSED(void *priv
slirp->pkt_tx_v[i].data = calloc(1, NET_MAX_FRAME);
}
slirp->pkt.data = calloc(1, NET_MAX_FRAME);
net_event_init(&slirp->rx_event);
net_event_init(&slirp->tx_event);
net_event_init(&slirp->stop_event);
#ifdef _WIN32
@@ -531,8 +560,9 @@ net_slirp_close(void *priv)
slirp_log("SLiRP: waiting for thread to end...\n");
thread_wait(slirp->poll_tid);
net_event_close(&slirp->tx_event);
net_event_close(&slirp->stop_event);
net_event_close(&slirp->tx_event);
net_event_close(&slirp->rx_event);
slirp_cleanup(slirp->slirp);
for (int i = 0; i < SLIRP_PKT_BATCH; i++) {
free(slirp->pkt_tx_v[i].data);

View File

@@ -643,6 +643,43 @@ network_rx_put(netcard_t *card, uint8_t *bufp, int len)
return ret;
}
int
network_rx_on_tx_popv(netcard_t *card, netpkt_t *pkt_vec, int vec_size)
{
int pkt_count = 0;
netqueue_t *queue = &card->queues[NET_QUEUE_RX_ON_TX];
for (int i = 0; i < vec_size; i++) {
if (!network_queue_get_swap(queue, pkt_vec))
break;
network_dump_packet(pkt_vec);
pkt_count++;
pkt_vec++;
}
return pkt_count;
}
int
network_rx_on_tx_put(netcard_t *card, uint8_t *bufp, int len)
{
int ret = 0;
ret = network_queue_put(&card->queues[NET_QUEUE_RX_ON_TX], bufp, len);
return ret;
}
int
network_rx_on_tx_put_pkt(netcard_t *card, netpkt_t *pkt)
{
int ret = 0;
ret = network_queue_put_swap(&card->queues[NET_QUEUE_RX_ON_TX], pkt);
return ret;
}
int
network_rx_put_pkt(netcard_t *card, netpkt_t *pkt)
{