Optimize packet I/O and timeouts
- Introduce per-thread I/O statistics for packet I/O to reduce performance overhead. - Implement packet_io_yield() for better thread management during I/O operations. - Refactor time wheel management: - Replace timeouts-based cron tasks with (now_ts - last_ts > timeout) for scheduled tasks. - Update the time wheel every 5 ms for improved time management.
This commit is contained in:
@@ -20,7 +20,7 @@ struct dumpfile_io
|
||||
|
||||
pcap_t *pcap;
|
||||
struct lock_free_queue *queue[MAX_THREAD_NUM];
|
||||
struct io_stat stat;
|
||||
struct io_stat stat[MAX_THREAD_NUM];
|
||||
uint64_t io_thread_need_exit;
|
||||
uint64_t io_thread_is_runing;
|
||||
};
|
||||
@@ -193,11 +193,6 @@ void dumpfile_io_free(struct dumpfile_io *handle)
|
||||
}
|
||||
}
|
||||
|
||||
struct io_stat *dumpfile_io_get_stat(struct dumpfile_io *handle)
|
||||
{
|
||||
return &handle->stat;
|
||||
}
|
||||
|
||||
int dumpfile_io_init(struct dumpfile_io *handle, uint16_t thr_idx)
|
||||
{
|
||||
return 0;
|
||||
@@ -206,6 +201,7 @@ int dumpfile_io_init(struct dumpfile_io *handle, uint16_t thr_idx)
|
||||
int dumpfile_io_ingress(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts)
|
||||
{
|
||||
struct lock_free_queue *queue = handle->queue[thr_idx];
|
||||
struct io_stat *stat = &handle->stat[thr_idx];
|
||||
struct pcap_pkt *pcap_pkt = NULL;
|
||||
struct packet *pkt;
|
||||
int nr_parsed = 0;
|
||||
@@ -219,11 +215,11 @@ int dumpfile_io_ingress(struct dumpfile_io *handle, uint16_t thr_idx, struct pac
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.dev_rx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.dev_rx_bytes, pcap_pkt->len);
|
||||
stat->dev_rx_pkts++;
|
||||
stat->dev_rx_bytes += pcap_pkt->len;
|
||||
|
||||
ATOMIC_ADD(&handle->stat.raw_rx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.raw_rx_bytes, pcap_pkt->len);
|
||||
stat->raw_rx_pkts++;
|
||||
stat->raw_rx_bytes += pcap_pkt->len;
|
||||
|
||||
pkt = &pkts[nr_parsed];
|
||||
memset(pkt, 0, sizeof(struct packet));
|
||||
@@ -241,16 +237,18 @@ void dumpfile_io_egress(struct dumpfile_io *handle, uint16_t thr_idx, struct pac
|
||||
{
|
||||
int len;
|
||||
struct packet *pkt = NULL;
|
||||
struct io_stat *stat = &handle->stat[thr_idx];
|
||||
|
||||
for (int i = 0; i < nr_pkts; i++)
|
||||
{
|
||||
pkt = &pkts[i];
|
||||
len = packet_get_len(pkt);
|
||||
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_bytes, len);
|
||||
stat->dev_tx_pkts++;
|
||||
stat->dev_tx_bytes += len;
|
||||
|
||||
ATOMIC_ADD(&handle->stat.raw_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.raw_tx_bytes, len);
|
||||
stat->raw_tx_pkts++;
|
||||
stat->raw_tx_bytes += len;
|
||||
|
||||
struct pcap_pkt *pcap_pkt = (struct pcap_pkt *)packet_get_io_ctx(pkt);
|
||||
if (pcap_pkt)
|
||||
@@ -275,3 +273,13 @@ void dumpfile_io_drop(struct dumpfile_io *handle, uint16_t thr_idx, struct packe
|
||||
packet_free(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
void dumpfile_io_yield(struct dumpfile_io *handle, uint16_t thr_idx, uint64_t timeout_ms)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
struct io_stat *dumpfile_io_stat(struct dumpfile_io *handle, uint16_t thr_idx)
|
||||
{
|
||||
return &handle->stat[thr_idx];
|
||||
}
|
||||
@@ -11,12 +11,13 @@ extern "C"
|
||||
struct dumpfile_io;
|
||||
struct dumpfile_io *dumpfile_io_new(const char *directory, uint8_t nr_threads);
|
||||
void dumpfile_io_free(struct dumpfile_io *handle);
|
||||
struct io_stat *dumpfile_io_get_stat(struct dumpfile_io *handle);
|
||||
|
||||
int dumpfile_io_init(struct dumpfile_io *handle, uint16_t thr_idx);
|
||||
int dumpfile_io_ingress(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
|
||||
void dumpfile_io_egress(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
|
||||
void dumpfile_io_drop(struct dumpfile_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
|
||||
void dumpfile_io_yield(struct dumpfile_io *handle, uint16_t thr_idx, uint64_t timeout_ms);
|
||||
struct io_stat *dumpfile_io_stat(struct dumpfile_io *handle, uint16_t thr_idx);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ struct marsio_io
|
||||
struct mr_vdev *mr_dev;
|
||||
struct mr_sendpath *mr_path;
|
||||
|
||||
struct io_stat stat;
|
||||
struct io_stat stat[MAX_THREAD_NUM];
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
@@ -118,11 +118,6 @@ void marsio_io_free(struct marsio_io *handle)
|
||||
}
|
||||
}
|
||||
|
||||
struct io_stat *marsio_io_get_stat(struct marsio_io *handle)
|
||||
{
|
||||
return &handle->stat;
|
||||
}
|
||||
|
||||
int marsio_io_init(struct marsio_io *handle, uint16_t thr_idx)
|
||||
{
|
||||
if (marsio_thread_init(handle->mr_ins) != 0)
|
||||
@@ -139,6 +134,7 @@ int marsio_io_ingress(struct marsio_io *handle, uint16_t thr_idx, struct packet
|
||||
struct packet *pkt;
|
||||
marsio_buff_t *mbuff;
|
||||
marsio_buff_t *rx_buffs[RX_BURST_MAX];
|
||||
struct io_stat *stat = &handle->stat[thr_idx];
|
||||
int nr_recv;
|
||||
int nr_parsed = 0;
|
||||
int len;
|
||||
@@ -156,16 +152,16 @@ int marsio_io_ingress(struct marsio_io *handle, uint16_t thr_idx, struct packet
|
||||
data = marsio_buff_mtod(mbuff);
|
||||
len = marsio_buff_datalen(mbuff);
|
||||
|
||||
ATOMIC_ADD(&handle->stat.dev_rx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.dev_rx_bytes, len);
|
||||
stat->dev_rx_pkts++;
|
||||
stat->dev_rx_bytes += len;
|
||||
|
||||
if (is_keepalive_packet(data, len))
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.keep_alive_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.keep_alive_bytes, len);
|
||||
stat->keep_alive_pkts++;
|
||||
stat->keep_alive_bytes += len;
|
||||
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_bytes, len);
|
||||
stat->dev_tx_pkts++;
|
||||
stat->dev_tx_bytes += len;
|
||||
|
||||
marsio_send_burst(handle->mr_path, thr_idx, &mbuff, 1);
|
||||
continue;
|
||||
@@ -181,13 +177,13 @@ int marsio_io_ingress(struct marsio_io *handle, uint16_t thr_idx, struct packet
|
||||
if (marsio_buff_is_ctrlbuf(mbuff))
|
||||
{
|
||||
packet_set_ctrl(pkt);
|
||||
ATOMIC_ADD(&handle->stat.ctrl_rx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.ctrl_rx_bytes, len);
|
||||
stat->ctrl_rx_pkts++;
|
||||
stat->ctrl_rx_bytes += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.raw_rx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.raw_rx_bytes, len);
|
||||
stat->raw_rx_pkts++;
|
||||
stat->raw_rx_bytes += len;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,6 +194,7 @@ void marsio_io_egress(struct marsio_io *handle, uint16_t thr_idx, struct packet
|
||||
{
|
||||
struct packet *pkt;
|
||||
marsio_buff_t *mbuff;
|
||||
struct io_stat *stat = &handle->stat[thr_idx];
|
||||
int len;
|
||||
|
||||
for (int i = 0; i < nr_pkts; i++)
|
||||
@@ -205,21 +202,21 @@ void marsio_io_egress(struct marsio_io *handle, uint16_t thr_idx, struct packet
|
||||
pkt = &pkts[i];
|
||||
len = packet_get_len(pkt);
|
||||
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.dev_tx_bytes, len);
|
||||
stat->dev_tx_pkts++;
|
||||
stat->dev_tx_bytes += len;
|
||||
|
||||
mbuff = (marsio_buff_t *)packet_get_io_ctx(pkt);
|
||||
assert(mbuff != NULL);
|
||||
|
||||
if (marsio_buff_is_ctrlbuf(mbuff))
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.ctrl_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.ctrl_tx_bytes, len);
|
||||
stat->ctrl_tx_pkts++;
|
||||
stat->ctrl_tx_bytes += len;
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMIC_ADD(&handle->stat.raw_tx_pkts, 1);
|
||||
ATOMIC_ADD(&handle->stat.raw_tx_bytes, len);
|
||||
stat->raw_tx_pkts++;
|
||||
stat->raw_tx_bytes += len;
|
||||
}
|
||||
|
||||
marsio_send_burst(handle->mr_path, thr_idx, &mbuff, 1);
|
||||
@@ -242,4 +239,18 @@ void marsio_io_drop(struct marsio_io *handle, uint16_t thr_idx, struct packet *p
|
||||
}
|
||||
packet_free(pkt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void marsio_io_yield(struct marsio_io *handle, uint16_t thr_idx, uint64_t timeout_ms)
|
||||
{
|
||||
struct mr_vdev *vdevs[1] = {
|
||||
handle->mr_dev,
|
||||
};
|
||||
|
||||
marsio_poll_wait(handle->mr_ins, vdevs, 1, thr_idx, timeout_ms);
|
||||
}
|
||||
|
||||
struct io_stat *marsio_io_stat(struct marsio_io *handle, uint16_t thr_idx)
|
||||
{
|
||||
return &handle->stat[thr_idx];
|
||||
}
|
||||
|
||||
@@ -11,12 +11,13 @@ extern "C"
|
||||
struct marsio_io;
|
||||
struct marsio_io *marsio_io_new(const char *app_symbol, const char *dev_symbol, uint16_t *cpu_mask, uint8_t nr_threads);
|
||||
void marsio_io_free(struct marsio_io *handle);
|
||||
struct io_stat *marsio_io_get_stat(struct marsio_io *handle);
|
||||
|
||||
int marsio_io_init(struct marsio_io *handle, uint16_t thr_idx);
|
||||
int marsio_io_ingress(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
|
||||
void marsio_io_egress(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
|
||||
void marsio_io_drop(struct marsio_io *handle, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
|
||||
void marsio_io_yield(struct marsio_io *handle, uint16_t thr_idx, uint64_t timeout_ms);
|
||||
struct io_stat *marsio_io_stat(struct marsio_io *handle, uint16_t thr_idx);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ void packet_io_free(struct packet_io *packet_io)
|
||||
{
|
||||
if (packet_io)
|
||||
{
|
||||
if (packet_io->mode == PACKET_IO_MARSIO)
|
||||
if (likely(packet_io->mode == PACKET_IO_MARSIO))
|
||||
{
|
||||
marsio_io_free(packet_io->marsio);
|
||||
}
|
||||
@@ -58,21 +58,9 @@ void packet_io_free(struct packet_io *packet_io)
|
||||
}
|
||||
}
|
||||
|
||||
struct io_stat *packet_io_get_stat(struct packet_io *packet_io)
|
||||
{
|
||||
if (packet_io->mode == PACKET_IO_MARSIO)
|
||||
{
|
||||
return marsio_io_get_stat(packet_io->marsio);
|
||||
}
|
||||
else
|
||||
{
|
||||
return dumpfile_io_get_stat(packet_io->dumpfile);
|
||||
}
|
||||
}
|
||||
|
||||
int packet_io_init(struct packet_io *packet_io, uint16_t thr_idx)
|
||||
{
|
||||
if (packet_io->mode == PACKET_IO_MARSIO)
|
||||
if (likely(packet_io->mode == PACKET_IO_MARSIO))
|
||||
{
|
||||
return marsio_io_init(packet_io->marsio, thr_idx);
|
||||
}
|
||||
@@ -84,7 +72,7 @@ int packet_io_init(struct packet_io *packet_io, uint16_t thr_idx)
|
||||
|
||||
int packet_io_ingress(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts)
|
||||
{
|
||||
if (packet_io->mode == PACKET_IO_MARSIO)
|
||||
if (likely(packet_io->mode == PACKET_IO_MARSIO))
|
||||
{
|
||||
return marsio_io_ingress(packet_io->marsio, thr_idx, pkts, nr_pkts);
|
||||
}
|
||||
@@ -96,7 +84,7 @@ int packet_io_ingress(struct packet_io *packet_io, uint16_t thr_idx, struct pack
|
||||
|
||||
void packet_io_egress(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts)
|
||||
{
|
||||
if (packet_io->mode == PACKET_IO_MARSIO)
|
||||
if (likely(packet_io->mode == PACKET_IO_MARSIO))
|
||||
{
|
||||
marsio_io_egress(packet_io->marsio, thr_idx, pkts, nr_pkts);
|
||||
}
|
||||
@@ -108,7 +96,7 @@ void packet_io_egress(struct packet_io *packet_io, uint16_t thr_idx, struct pack
|
||||
|
||||
void packet_io_drop(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts)
|
||||
{
|
||||
if (packet_io->mode == PACKET_IO_MARSIO)
|
||||
if (likely(packet_io->mode == PACKET_IO_MARSIO))
|
||||
{
|
||||
marsio_io_drop(packet_io->marsio, thr_idx, pkts, nr_pkts);
|
||||
}
|
||||
@@ -117,3 +105,27 @@ void packet_io_drop(struct packet_io *packet_io, uint16_t thr_idx, struct packet
|
||||
dumpfile_io_drop(packet_io->dumpfile, thr_idx, pkts, nr_pkts);
|
||||
}
|
||||
}
|
||||
|
||||
void packet_io_yield(struct packet_io *packet_io, uint16_t thr_idx, uint64_t timeout_ms)
|
||||
{
|
||||
if (likely(packet_io->mode == PACKET_IO_MARSIO))
|
||||
{
|
||||
marsio_io_yield(packet_io->marsio, thr_idx, timeout_ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
dumpfile_io_yield(packet_io->dumpfile, thr_idx, timeout_ms);
|
||||
}
|
||||
}
|
||||
|
||||
struct io_stat *packet_io_stat(struct packet_io *packet_io, uint16_t thr_idx)
|
||||
{
|
||||
if (likely(packet_io->mode == PACKET_IO_MARSIO))
|
||||
{
|
||||
return marsio_io_stat(packet_io->marsio, thr_idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
return dumpfile_io_stat(packet_io->dumpfile, thr_idx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,12 +66,13 @@ struct packet_io_options
|
||||
struct packet_io;
|
||||
struct packet_io *packet_io_new(struct packet_io_options *opts);
|
||||
void packet_io_free(struct packet_io *packet_io);
|
||||
struct io_stat *packet_io_get_stat(struct packet_io *packet_io);
|
||||
|
||||
int packet_io_init(struct packet_io *packet_io, uint16_t thr_idx);
|
||||
int packet_io_ingress(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
|
||||
void packet_io_egress(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
|
||||
void packet_io_drop(struct packet_io *packet_io, uint16_t thr_idx, struct packet *pkts, int nr_pkts);
|
||||
void packet_io_yield(struct packet_io *packet_io, uint16_t thr_idx, uint64_t timeout_ms);
|
||||
struct io_stat *packet_io_stat(struct packet_io *packet_io, uint16_t thr_idx);
|
||||
|
||||
#ifdef __cpluscplus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user