Skip to content

Commit

Permalink
Merge "Infrastructure to support aging for L2 entries"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Nov 28, 2016
2 parents 6de9dc4 + 14776a0 commit 12ac83a
Show file tree
Hide file tree
Showing 20 changed files with 759 additions and 263 deletions.
394 changes: 252 additions & 142 deletions dp-core/vr_bridge.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dp-core/vr_flow.c
Expand Up @@ -43,7 +43,7 @@ unsigned char *vr_flow_path;
unsigned int vr_flow_hold_limit = VR_DEF_MAX_FLOW_TABLE_HOLD_COUNT;

#if defined(__linux__) && defined(__KERNEL__)
extern unsigned short vr_flow_major;
extern short vr_flow_major;
#endif

uint32_t vr_hashrnd = 0;
Expand Down
4 changes: 2 additions & 2 deletions dp-core/vr_htable.c
Expand Up @@ -156,7 +156,7 @@ vr_htable_get_hentry_by_index(vr_htable_t htable, unsigned int index)
vr_hentry_t *ent;

ent = __vr_htable_get_hentry_by_index(htable, index);
if(ent && (ent->hentry_flags & VR_HENTRY_FLAG_VALID))
if (ent && (ent->hentry_flags & VR_HENTRY_FLAG_VALID))
return ent;

return NULL;
Expand Down Expand Up @@ -586,7 +586,7 @@ vr_htable_find_hentry(vr_htable_t htable, void *key, unsigned int key_len)
return ent;
}

for(o_ent = ent->hentry_next; o_ent; o_ent = o_ent->hentry_next) {
for (o_ent = ent->hentry_next; o_ent; o_ent = o_ent->hentry_next) {

/* Though in the list, can be under the deletion */
if (!(o_ent->hentry_flags & VR_HENTRY_FLAG_VALID))
Expand Down
24 changes: 15 additions & 9 deletions dp-core/vr_sandesh.c
Expand Up @@ -40,27 +40,27 @@ struct sandesh_object_md sandesh_md[] = {
.obj_len = 4 * sizeof(vr_flow_req),
.obj_type_string = "vr_flow_req",
},
[VR_VRF_ASSIGN_OBJECT_ID] = {
[VR_VRF_ASSIGN_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_vrf_assign_req),
.obj_type_string = "vr_vrf_assign_req",
},
[VR_VRF_STATS_OBJECT_ID] = {
[VR_VRF_STATS_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_vrf_stats_req),
.obj_type_string = "vr_vrf_stats_req",
},
[VR_DROP_STATS_OBJECT_ID] = {
[VR_DROP_STATS_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_drop_stats_req),
.obj_type_string = "vr_drop_stats_req",
},
[VR_RESPONSE_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_response),
.obj_type_string = "vr_response",
},
[VR_VXLAN_OBJECT_ID] = {
[VR_VXLAN_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_vxlan_req),
.obj_type_string = "vr_vxlan_req",
},
[VR_VROUTER_OPS_OBJECT_ID] = {
[VR_VROUTER_OPS_OBJECT_ID] = {
.obj_len = 4 * sizeof(vrouter_ops),
.obj_type_string = "vrouter_ops",
},
Expand All @@ -69,23 +69,29 @@ struct sandesh_object_md sandesh_md[] = {
(VR_FLOW_MAX_CPUS * sizeof(unsigned int))),
.obj_type_string = "vr_flow_table_data",
},
[VR_MEM_STATS_OBJECT_ID] = {
[VR_MEM_STATS_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_mem_stats_req),
.obj_type_string = "vr_mem_stats_req",
},
[VR_QOS_MAP_OBJECT_ID] = {
[VR_QOS_MAP_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_qos_map_req),
.obj_get_size = vr_qos_map_req_get_size,
.obj_type_string = "vr_qos_map_req",
},
[VR_FC_MAP_OBJECT_ID] = {
[VR_FC_MAP_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_fc_map_req),
.obj_type_string = "vr_fc_map_req",
},
[VR_FLOW_RESPONSE_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_flow_response),
.obj_type_string = "vr_flow_response",
.obj_type_string = "vr_flow_response",
},
#if 0
[VR_BRIDGE_TABLE_DATA_OBJECT_ID] = {
.obj_len = 4 * sizeof(vr_bridge_table_data),
.obj_type_string = "vr_bridge_table_data",
},
#endif
};

static unsigned int
Expand Down
13 changes: 12 additions & 1 deletion dpdk/dpdk_vrouter.c
Expand Up @@ -27,6 +27,7 @@
#include "vr_dpdk_virtio.h"
#include "vr_uvhost.h"
#include "vr_bridge.h"
#include "vr_mem.h"
#include "nl_util.h"

#include <rte_errno.h>
Expand Down Expand Up @@ -636,13 +637,23 @@ dpdk_init(void)

version_print();

ret = vr_dpdk_flow_mem_init();
ret = vr_dpdk_table_mem_init(VR_MEM_FLOW_TABLE_OBJECT, vr_flow_entries,
VR_FLOW_TABLE_SIZE, vr_oflow_entries, VR_OFLOW_TABLE_SIZE);
if (ret < 0) {
RTE_LOG(ERR, VROUTER, "Error initializing flow table: %s (%d)\n",
rte_strerror(-ret), -ret);
return ret;
}

ret = vr_dpdk_table_mem_init(VR_MEM_BRIDGE_TABLE_OBJECT, vr_bridge_entries,
VR_BRIDGE_TABLE_SIZE, vr_bridge_oentries,
VR_BRIDGE_OFLOW_TABLE_SIZE);
if (ret < 0) {
RTE_LOG(ERR, VROUTER, "Error initializing bridge table: %s (%d)\n",
rte_strerror(-ret), -ret);
return ret;
}

ret = dpdk_argv_update();
if (ret == -1) {
RTE_LOG(ERR, VROUTER, "Error updating EAL arguments\n");
Expand Down
5 changes: 5 additions & 0 deletions dpdk/vr_dpdk_host.c
Expand Up @@ -1444,9 +1444,14 @@ vr_dpdk_host_init(void)

if (!vrouter_host) {
vrouter_host = vrouter_get_host();

if (vr_dpdk_flow_init()) {
return -1;
}

if (vr_dpdk_bridge_init()) {
return -1;
}
}

/*
Expand Down
95 changes: 69 additions & 26 deletions dpdk/vr_dpdk_flow_mem.c → dpdk/vr_dpdk_table_mem.c
Expand Up @@ -14,6 +14,7 @@

#include "vr_dpdk.h"
#include "vr_btable.h"
#include "vr_mem.h"
#include "nl_util.h"

#include <rte_errno.h>
Expand All @@ -29,9 +30,9 @@ struct vr_hugepage_info {
uint32_t num_pages;
} vr_hugepage_md[HPI_MAX];

extern void *vr_flow_table;
extern void *vr_oflow_table;
extern unsigned char *vr_flow_path;
extern void *vr_flow_table, *vr_oflow_table;
extern void *vr_bridge_table, *vr_bridge_otable;
extern unsigned char *vr_flow_path, *vr_bridge_table_path;

static int
vr_hugepage_info_init(void)
Expand Down Expand Up @@ -135,24 +136,54 @@ vr_hugepage_info_init(void)
return 0;
}


int
vr_dpdk_flow_mem_init(void)
vr_dpdk_table_mem_init(unsigned int table, unsigned int entries,
unsigned long size, unsigned int oentries, unsigned long osize)
{
int ret, i, fd;
size_t size, flow_table_size;
struct vr_hugepage_info *hpi;

void **table_p;
char shm_file[VR_UNIX_PATH_MAX];
char *file_name, *touse_file_name = NULL;
char *shmem_name, *hp_file_name;
unsigned char **path;

struct stat f_stat;
char shm_file[VR_UNIX_PATH_MAX];
struct vr_hugepage_info *hpi;

if (!vr_oflow_entries)
vr_oflow_entries = ((vr_flow_entries / 5) + 1023) & ~1023;
if (!oentries) {
oentries = (entries / 5 + 1023) & ~1023;
osize = (size / entries) * oentries;
}

flow_table_size = VR_FLOW_TABLE_SIZE + VR_OFLOW_TABLE_SIZE;
size += osize;

switch (table) {
case VR_MEM_FLOW_TABLE_OBJECT:
shmem_name = "flow.shmem";
hp_file_name = "flow";
table_p = &vr_dpdk.flow_table;
path = &vr_flow_path;
vr_oflow_entries = oentries;
break;

case VR_MEM_BRIDGE_TABLE_OBJECT:
shmem_name = "bridge.shmem";
hp_file_name = "bridge";
table_p = &vr_dpdk.bridge_table;
path = &vr_bridge_table_path;
vr_bridge_oentries = oentries;
break;

default:
return -EINVAL;
}

if (no_huge_set) {
/* Create a shared memory under the socket directory. */
ret = snprintf(shm_file, sizeof(shm_file), "%s/flow.shmem", vr_socket_dir);
ret = snprintf(shm_file, sizeof(shm_file), "%s/%s",
vr_socket_dir, shmem_name);
if (ret >= sizeof(shm_file)) {
RTE_LOG(ERR, VROUTER, "Error creating shared memory file\n");
return -ENOMEM;
Expand All @@ -170,12 +201,11 @@ vr_dpdk_flow_mem_init(void)
hpi = &vr_hugepage_md[i];
if (!hpi->mnt)
continue;
file_name = malloc(strlen(hpi->mnt) + strlen("/flow") + 1);
sprintf(file_name, "%s/flow", hpi->mnt);
file_name = malloc(strlen(hpi->mnt) + strlen(hp_file_name) + 1);
sprintf(file_name, "%s/%s", hpi->mnt, hp_file_name);
if (stat(file_name, &f_stat) == -1) {
if (!touse_file_name) {
size = hpi->size;
if (size >= flow_table_size) {
if (hpi->size >= size) {
touse_file_name = file_name;
} else {
free(file_name);
Expand All @@ -196,46 +226,59 @@ vr_dpdk_flow_mem_init(void)
touse_file_name, rte_strerror(errno), errno);
return -errno;
}
if (no_huge_set){
ret = ftruncate(fd, flow_table_size);

if (no_huge_set) {
ret = ftruncate(fd, size);
if (ret == -1) {
RTE_LOG(ERR, VROUTER, "Error truncating file %s: %s (%d)\n",
touse_file_name, rte_strerror(errno), errno);
return -errno;
}
}
vr_dpdk.flow_table = mmap(NULL, flow_table_size, PROT_READ | PROT_WRITE,

*table_p = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
/* the file descriptor is no longer needed */
close(fd);
if (vr_dpdk.flow_table == MAP_FAILED) {
if (*table_p == MAP_FAILED) {
RTE_LOG(ERR, VROUTER, "Error mmapping file %s: %s (%d)\n",
touse_file_name, rte_strerror(errno), errno);
return -errno;
}
memset(vr_dpdk.flow_table, 0, flow_table_size);
vr_flow_path = (unsigned char *)touse_file_name;
memset(*table_p, 0, size);
*path = (unsigned char *)touse_file_name;
}

if (!vr_dpdk.flow_table)
return -ENOMEM;
return 0;
}

vr_flow_hold_limit = VR_DPDK_MAX_FLOW_TABLE_HOLD_COUNT;
RTE_LOG(INFO, VROUTER, "Max HOLD flow entries set to %u\n",
vr_flow_hold_limit);
int
vr_dpdk_bridge_init(void)
{
if (!vr_dpdk.bridge_table)
return -1;

vr_bridge_table = vr_dpdk.bridge_table;
vr_bridge_otable = vr_dpdk.bridge_table + VR_BRIDGE_TABLE_SIZE;

return 0;
}

int
vr_dpdk_flow_init(void)
{
if (!vr_dpdk.flow_table)
return -1;

vr_flow_table = vr_dpdk.flow_table;
vr_oflow_table = vr_dpdk.flow_table + VR_FLOW_TABLE_SIZE;

if (!vr_flow_table)
return -1;

vr_flow_hold_limit = VR_DPDK_MAX_FLOW_TABLE_HOLD_COUNT;
RTE_LOG(INFO, VROUTER, "Max HOLD flow entries set to %u\n",
vr_flow_hold_limit);

return 0;
}
4 changes: 4 additions & 0 deletions include/nl_util.h
Expand Up @@ -29,6 +29,9 @@ extern "C" {
#define VR_NETLINK_PROTO_DEFAULT -1
#define VR_NETLINK_PROTO_TEST -2

#define BRIDGE_TABLE_DEV "/dev/vr_bridge"
#define FLOW_TABLE_DEV "/dev/flow"

struct nl_response {
uint8_t *nl_data;
unsigned int nl_type;
Expand Down Expand Up @@ -151,6 +154,7 @@ extern struct nl_client *vr_get_nl_client(int);

extern int vr_response_common_process(vr_response *, bool *);

extern void *vr_table_map(int, unsigned int, char *, size_t);
extern unsigned long vr_sum_drop_stats(vr_drop_stats_req *);
extern void vr_drop_stats_req_destroy(vr_drop_stats_req *);
extern vr_drop_stats_req *vr_drop_stats_req_get_copy(vr_drop_stats_req *);
Expand Down
41 changes: 40 additions & 1 deletion include/vr_bridge.h
Expand Up @@ -5,7 +5,7 @@
#define __VR_BRIDGE_H__

#include "vr_defs.h"
#include "vrouter.h"
#include "vr_htable.h"

#define VR_DEF_BRIDGE_ENTRIES (256 * 1024)

Expand Down Expand Up @@ -41,9 +41,48 @@

#define VR_BE_INVALID_INDEX ((unsigned int)-1)

struct vr_bridge_entry_key {
unsigned char be_mac[VR_ETHER_ALEN];
unsigned short be_vrf_id;
}__attribute__((packed));

struct vr_bridge_entry;

struct vr_dummy_bridge_entry {
vr_hentry_t be_hentry;
struct vr_bridge_entry_key be_key;
struct vr_nexthop *be_nh;
uint64_t be_packets;
uint32_t be_label;
uint32_t be_nh_id;
unsigned short be_flags;
} __attribute__((packed));

#define VR_BRIDGE_ENTRY_PACK (64 - sizeof(struct vr_dummy_bridge_entry))

struct vr_bridge_entry {
vr_hentry_t be_hentry;
struct vr_bridge_entry_key be_key;
struct vr_nexthop *be_nh;
uint64_t be_packets;
uint32_t be_label;
int32_t be_nh_id;
unsigned short be_flags;
unsigned char be_pack[VR_BRIDGE_ENTRY_PACK];
} __attribute__((packed));


extern unsigned int vr_bridge_entries, vr_bridge_oentries;
#define VR_BRIDGE_TABLE_SIZE (vr_bridge_entries *\
sizeof(struct vr_bridge_entry))
#define VR_BRIDGE_OFLOW_TABLE_SIZE (vr_bridge_oentries *\
sizeof(struct vr_bridge_entry))

extern char vr_bcast_mac[];

unsigned int vr_bridge_table_used_oflow_entries(struct vrouter *);
unsigned int vr_bridge_table_used_total_entries(struct vrouter *);
void *vr_bridge_get_va(struct vrouter *, uint64_t);
unsigned int vr_bridge_table_size(struct vrouter *);

#endif

0 comments on commit 12ac83a

Please sign in to comment.