Skip to content

Commit

Permalink
[host] add ability to double defrag buffers when running out of buffers
Browse files Browse the repository at this point in the history
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
  • Loading branch information
fabbione committed Sep 3, 2021
1 parent edea363 commit c554d8c
Showing 1 changed file with 63 additions and 1 deletion.
64 changes: 63 additions & 1 deletion libknet/threads_rx.c
Expand Up @@ -10,6 +10,7 @@
#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/uio.h>
Expand Down Expand Up @@ -60,17 +61,66 @@ static inline int _timecmp(struct timespec a, struct timespec b)
}

/*
* this functions needs to return an index (0 to 7)
* check if we can double the defrag buffers.
*
* return 0 if we cannot reallocate
* return 1 if we have more buffers
*/

static int _realloc_defrag_buffers(knet_handle_t knet_h, struct knet_host *src_host)
{
struct knet_host_defrag_buf *new_bufs = NULL;
int i;

/*
* max_defrag_bufs is a power of 2
* allocated_defrag_bufs doubles on each iteraction.
* Sooner or later (and hopefully never) allocated with be == to max.
*/
if (src_host->allocated_defrag_bufs < knet_h->max_defrag_bufs) {
new_bufs = realloc(src_host->defrag_bufs,
src_host->allocated_defrag_bufs * 2 * sizeof(struct knet_host_defrag_buf));
if (!new_bufs) {
log_err(knet_h, KNET_SUB_RX, "Unable to increase defrag buffers for host %u: %s",
src_host->host_id, strerror(errno));
return 0;
}

/*
* keep the math simple here between arrays, pointers and what not.
* Init each buffer individually.
*/
for (i = src_host->allocated_defrag_bufs; i < src_host->allocated_defrag_bufs * 2; i++) {
memset(&new_bufs[i], 0, sizeof(struct knet_host_defrag_buf));
}

src_host->allocated_defrag_bufs = src_host->allocated_defrag_bufs * 2;

src_host->defrag_bufs = new_bufs;

log_debug(knet_h, KNET_SUB_RX, "Defrag buffers for host %u increased from %u to: %u",
src_host->host_id, src_host->allocated_defrag_bufs / 2, src_host->allocated_defrag_bufs);

return 1;
}

return 0;
}

/*
* this functions needs to return an index
* to a knet_host_defrag_buf. (-1 on errors)
*/

static int _find_pckt_defrag_buf(knet_handle_t knet_h, struct knet_host *src_host, seq_num_t seq_num)
{
int i, oldest;
uint16_t cur_allocated_defrag_bufs = src_host->allocated_defrag_bufs;

/*
* check if there is a buffer already in use handling the same seq_num
*/

for (i = 0; i < src_host->allocated_defrag_bufs; i++) {
if (src_host->defrag_bufs[i].in_use) {
if (src_host->defrag_bufs[i].pckt_seq == seq_num) {
Expand All @@ -86,6 +136,7 @@ static int _find_pckt_defrag_buf(knet_handle_t knet_h, struct knet_host *src_hos
* buffer. If the pckt has been seen before, the buffer expired (ETIME)
* and there is no point to try to defrag it again.
*/

if (!_seq_num_lookup(knet_h, src_host, seq_num, 1, 0)) {
errno = ETIME;
return -1;
Expand All @@ -94,17 +145,27 @@ static int _find_pckt_defrag_buf(knet_handle_t knet_h, struct knet_host *src_hos
/*
* register the pckt as seen
*/

_seq_num_set(src_host, seq_num, 1);

/*
* see if there is a free buffer
*/

for (i = 0; i < src_host->allocated_defrag_bufs; i++) {
if (!src_host->defrag_bufs[i].in_use) {
return i;
}
}

/*
* check if we can increase num of buffers
*/

if (_realloc_defrag_buffers(knet_h, src_host)) {
return cur_allocated_defrag_bufs + 1;
}

/*
* at this point, there are no free buffers, the pckt is new
* and we need to reclaim a buffer, and we will take the one
Expand All @@ -119,6 +180,7 @@ static int _find_pckt_defrag_buf(knet_handle_t knet_h, struct knet_host *src_hos
}
}
src_host->defrag_bufs[oldest].in_use = 0;

return oldest;
}

Expand Down

0 comments on commit c554d8c

Please sign in to comment.