Skip to content

Commit

Permalink
Feature set negotiation
Browse files Browse the repository at this point in the history
Closes-bug: #1746578
Fixed the feature negotiation issue by storing
the feature in persistent store and load when
VM comes up.

Change-Id: I3f41079264f040e1b57a146eda7711b171e302ac
(cherry picked from commit 9800537)
  • Loading branch information
Jeya ganesh babu J committed May 10, 2018
1 parent cbda85a commit f442753
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 4 deletions.
100 changes: 100 additions & 0 deletions dpdk/vr_dpdk_filestore.c
@@ -0,0 +1,100 @@
/*
* vr_dpdk_filestore.c - implements a persistent store
* to store/retrieve the VM feature set.
*
* Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
*/

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include "vr_dpdk.h"
#define FEATURE_STORE_PATH "/var/lib/contrail/vm_feature"

int vr_dpdk_store_persist_feature(char *tapdev_name, unsigned long feature_set)
{
char fname[NAME_MAX];
struct stat fstat;
FILE *fp;

if (stat(FEATURE_STORE_PATH, &fstat) != 0) {
if (mkdir(FEATURE_STORE_PATH, 0755) < 0) {
RTE_LOG(ERR, USOCK, "mkdir failed with error %d\n", errno);
return -1;
}
}

if (snprintf(fname, NAME_MAX, FEATURE_STORE_PATH"/%s", tapdev_name) < 0)
return -1;

RTE_LOG_DP(DEBUG, USOCK, "Write persistent feature %s\n", fname);

fp = fopen(fname, "w");
if (fp == NULL) {
return -1;
}
rewind(fp);
fprintf(fp, "%016lx", feature_set);
fclose(fp);
return 0;
}

int vr_dpdk_load_persist_feature(char *tapdev_name, unsigned long *feature_set)
{
char fname[NAME_MAX];
struct stat fstat;
FILE *fp;

if (stat(FEATURE_STORE_PATH, &fstat) != 0) {
if (mkdir(FEATURE_STORE_PATH, 0755) < 0) {
RTE_LOG(ERR, USOCK, "mkdir failed with error %d\n", errno);
return -1;
}
}

if (snprintf(fname, NAME_MAX, FEATURE_STORE_PATH"/%s", tapdev_name) < 0)
return -1;

RTE_LOG_DP(DEBUG, USOCK, "Read persistent feature %s\n", fname);

if (stat(fname, &fstat) == 0) {
fp = fopen(fname, "r");
if (fp == NULL) {
return -1;
}
rewind(fp);
if(fscanf(fp, "%016lx", feature_set) == EOF) {
if (errno) {
RTE_LOG(ERR, USOCK, "EOF reached with error %d for tapdev %s\n",
errno, tapdev_name);
fclose(fp);
return -1;
}
}
RTE_LOG_DP(DEBUG, USOCK, "Feature Set Read %lx for tapdev %s\n",
*feature_set, tapdev_name);
fclose(fp);
return 0;
} else {
return -1;
}
}

void vr_dpdk_del_persist_feature(char *tapdev_name)
{
char fname[NAME_MAX];
struct stat fstat;

if (snprintf(fname, NAME_MAX, FEATURE_STORE_PATH"/%s", tapdev_name) < 0)
return;

if (stat(fname, &fstat) == 0) {
if(unlink(fname)) {
RTE_LOG(ERR, USOCK, "Error deleting file %d for tapdev %s\n",
errno, tapdev_name);
}
}
}
15 changes: 15 additions & 0 deletions dpdk/vr_dpdk_filestore.h
@@ -0,0 +1,15 @@
/*
* vr_dpdk_filestore.h - header for persistent store
* to store/retrieve the VM feature set.
*
* Copyright (c) 2018 Juniper Networks, Inc. All rights reserved.
*/

#ifndef __VR_DPDK_FILESTORE_H__
#define __VR_DPDK_FILESTORE_H__

int vr_dpdk_store_persist_feature(char *tapdev_name, unsigned long feature_set);
int vr_dpdk_load_persist_feature(char *tapdev_name, unsigned long *feature_set);
void vr_dpdk_del_persist_feature(char *tapdev_name);

#endif /* __VR_DPDK_FILESTORE_H__ */
19 changes: 15 additions & 4 deletions dpdk/vr_uvhost_msg.c
Expand Up @@ -13,6 +13,7 @@
#include "vr_uvhost_client.h"
#include "vr_uvhost_msg.h"
#include "vr_uvhost_util.h"
#include "vr_dpdk_filestore.h"

#include <fcntl.h>
#include <linux/virtio_net.h>
Expand Down Expand Up @@ -355,11 +356,18 @@ vr_uvmh_set_features(vr_uvh_client_t *vru_cl)
{
struct vr_interface *vif;
uint8_t is_gso_vm = 1;
unsigned long stored_features = 0;

if (!vr_dpdk_load_persist_feature(uvhm_client_name(vru_cl),
&stored_features)) {
vru_cl->vruc_msg.u64 |= stored_features;
}

vr_uvhost_log(" SET FEATURES: 0x%"PRIx64"\n",
vru_cl->vruc_msg.u64);

vif = __vrouter_get_interface(vrouter_get(0), vru_cl->vruc_idx);
is_gso_vm = (vru_cl->vruc_msg.u64 & (1ULL << VIRTIO_NET_F_GUEST_TSO4)) |
is_gso_vm = (vru_cl->vruc_msg.u64 & (1ULL << VIRTIO_NET_F_GUEST_TSO4)) |
(vru_cl->vruc_msg.u64 & (1ULL << VIRTIO_NET_F_HOST_TSO4)) |
(vru_cl->vruc_msg.u64 & (1ULL << VIRTIO_NET_F_GUEST_TSO6)) |
(vru_cl->vruc_msg.u64 & (1ULL << VIRTIO_NET_F_HOST_TSO6));
Expand All @@ -369,19 +377,21 @@ vr_uvmh_set_features(vr_uvh_client_t *vru_cl)
*/
if (vif) {
if (!!is_gso_vm) {
vif->vif_flags |= VIF_FLAG_GRO_NEEDED;
vif->vif_flags |= VIF_FLAG_GRO_NEEDED;
} else {
vif->vif_flags &= ~VIF_FLAG_GRO_NEEDED;
vif->vif_flags &= ~VIF_FLAG_GRO_NEEDED;
}
}

if (vru_cl->vruc_msg.u64 & (1ULL << VIRTIO_NET_F_MRG_RXBUF)) {
vif->vif_flags |= VIF_FLAG_MRG_RXBUF;
vr_dpdk_set_vhost_send_func(vru_cl->vruc_idx, 1);
} else {
vif->vif_flags &= ~VIF_FLAG_MRG_RXBUF;
vif->vif_flags &= ~VIF_FLAG_MRG_RXBUF;
vr_dpdk_set_vhost_send_func(vru_cl->vruc_idx, 0);
}
vr_dpdk_store_persist_feature(uvhm_client_name(vru_cl),
vru_cl->vruc_msg.u64);
return 0;
}

Expand Down Expand Up @@ -1228,6 +1238,7 @@ vr_uvh_nl_vif_del_handler(vrnu_vif_del_t *msg)
}
/* Unmmap guest memory. */
uvhm_client_munmap(vru_cl);
vr_dpdk_del_persist_feature(uvhm_client_name(vru_cl));
vr_uvhost_del_client(vru_cl);

return 0;
Expand Down

0 comments on commit f442753

Please sign in to comment.