vhost: introduce driver features related APIs

Introduce few APIs to set/get/enable/disable driver features.

Signed-off-by: Yuanhan Liu <yuanhan.liu@linux.intel.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
This commit is contained in:
Yuanhan Liu 2017-04-01 15:22:39 +08:00
parent 65388b43f5
commit 5fbb3941da
4 changed files with 159 additions and 2 deletions

View File

@ -53,7 +53,7 @@ vhost library should be able to:
Vhost API Overview Vhost API Overview
------------------ ------------------
The following is an overview of the Vhost API functions: The following is an overview of some key Vhost API functions:
* ``rte_vhost_driver_register(path, flags)`` * ``rte_vhost_driver_register(path, flags)``
@ -110,6 +110,12 @@ The following is an overview of the Vhost API functions:
of those segments, thus the fewer the segments, the quicker we will get of those segments, thus the fewer the segments, the quicker we will get
the mapping. NOTE: we may speed it by using tree searching in future. the mapping. NOTE: we may speed it by using tree searching in future.
* ``rte_vhost_driver_set_features(path, features)``
This function sets the feature bits the vhost-user driver supports. The
vhost-user driver could be vhost-user net, yet it could be something else,
say, vhost-user SCSI.
* ``rte_vhost_driver_session_start()`` * ``rte_vhost_driver_session_start()``
This function starts the vhost session loop to handle vhost messages. It This function starts the vhost session loop to handle vhost messages. It
@ -145,7 +151,7 @@ The following is an overview of the Vhost API functions:
Receives (dequeues) ``count`` packets from guest, and stored them at ``pkts``. Receives (dequeues) ``count`` packets from guest, and stored them at ``pkts``.
* ``rte_vhost_feature_disable/rte_vhost_feature_enable(feature_mask)`` * ``rte_vhost_driver_disable/enable_features(path, features))``
This function disables/enables some features. For example, it can be used to This function disables/enables some features. For example, it can be used to
disable mergeable buffers and TSO features, which both are enabled by disable mergeable buffers and TSO features, which both are enabled by

View File

@ -34,6 +34,10 @@ DPDK_16.07 {
DPDK_17.05 { DPDK_17.05 {
global: global:
rte_vhost_driver_disable_features;
rte_vhost_driver_enable_features;
rte_vhost_driver_get_features;
rte_vhost_driver_set_features;
rte_vhost_get_mtu; rte_vhost_get_mtu;
} DPDK_16.07; } DPDK_16.07;

View File

@ -94,6 +94,61 @@ int rte_vhost_driver_register(const char *path, uint64_t flags);
/* Unregister vhost driver. This is only meaningful to vhost user. */ /* Unregister vhost driver. This is only meaningful to vhost user. */
int rte_vhost_driver_unregister(const char *path); int rte_vhost_driver_unregister(const char *path);
/**
* Set the feature bits the vhost-user driver supports.
*
* @param path
* The vhost-user socket file path
* @param features
* Supported features
* @return
* 0 on success, -1 on failure
*/
int rte_vhost_driver_set_features(const char *path, uint64_t features);
/**
* Enable vhost-user driver features.
*
* Note that
* - the param features should be a subset of the feature bits provided
* by rte_vhost_driver_set_features().
* - it must be invoked before vhost-user negotiation starts.
*
* @param path
* The vhost-user socket file path
* @param features
* Features to enable
* @return
* 0 on success, -1 on failure
*/
int rte_vhost_driver_enable_features(const char *path, uint64_t features);
/**
* Disable vhost-user driver features.
*
* The two notes at rte_vhost_driver_enable_features() also apply here.
*
* @param path
* The vhost-user socket file path
* @param features
* Features to disable
* @return
* 0 on success, -1 on failure
*/
int rte_vhost_driver_disable_features(const char *path, uint64_t features);
/**
* Get the feature bits before feature negotiation.
*
* @param path
* The vhost-user socket file path
* @param features
* A pointer to store the queried feature bits
* @return
* 0 on success, -1 on failure
*/
int rte_vhost_driver_get_features(const char *path, uint64_t *features);
/* Register callbacks. */ /* Register callbacks. */
int rte_vhost_driver_callback_register(struct virtio_net_device_ops const * const); int rte_vhost_driver_callback_register(struct virtio_net_device_ops const * const);
/* Start vhost driver session blocking loop. */ /* Start vhost driver session blocking loop. */

View File

@ -67,6 +67,16 @@ struct vhost_user_socket {
bool is_server; bool is_server;
bool reconnect; bool reconnect;
bool dequeue_zero_copy; bool dequeue_zero_copy;
/*
* The "supported_features" indicates the feature bits the
* vhost driver supports. The "features" indicates the feature
* bits after the rte_vhost_driver_features_disable/enable().
* It is also the final feature bits used for vhost-user
* features negotiation.
*/
uint64_t supported_features;
uint64_t features;
}; };
struct vhost_user_connection { struct vhost_user_connection {
@ -490,6 +500,88 @@ vhost_user_create_client(struct vhost_user_socket *vsocket)
return 0; return 0;
} }
static struct vhost_user_socket *
find_vhost_user_socket(const char *path)
{
int i;
for (i = 0; i < vhost_user.vsocket_cnt; i++) {
struct vhost_user_socket *vsocket = vhost_user.vsockets[i];
if (!strcmp(vsocket->path, path))
return vsocket;
}
return NULL;
}
int
rte_vhost_driver_disable_features(const char *path, uint64_t features)
{
struct vhost_user_socket *vsocket;
pthread_mutex_lock(&vhost_user.mutex);
vsocket = find_vhost_user_socket(path);
if (vsocket)
vsocket->features &= ~features;
pthread_mutex_unlock(&vhost_user.mutex);
return vsocket ? 0 : -1;
}
int
rte_vhost_driver_enable_features(const char *path, uint64_t features)
{
struct vhost_user_socket *vsocket;
pthread_mutex_lock(&vhost_user.mutex);
vsocket = find_vhost_user_socket(path);
if (vsocket) {
if ((vsocket->supported_features & features) != features) {
/*
* trying to enable features the driver doesn't
* support.
*/
pthread_mutex_unlock(&vhost_user.mutex);
return -1;
}
vsocket->features |= features;
}
pthread_mutex_unlock(&vhost_user.mutex);
return vsocket ? 0 : -1;
}
int
rte_vhost_driver_set_features(const char *path, uint64_t features)
{
struct vhost_user_socket *vsocket;
pthread_mutex_lock(&vhost_user.mutex);
vsocket = find_vhost_user_socket(path);
if (vsocket) {
vsocket->supported_features = features;
vsocket->features = features;
}
pthread_mutex_unlock(&vhost_user.mutex);
return vsocket ? 0 : -1;
}
int
rte_vhost_driver_get_features(const char *path, uint64_t *features)
{
struct vhost_user_socket *vsocket;
pthread_mutex_lock(&vhost_user.mutex);
vsocket = find_vhost_user_socket(path);
if (vsocket)
*features = vsocket->features;
pthread_mutex_unlock(&vhost_user.mutex);
return vsocket ? 0 : -1;
}
/* /*
* Register a new vhost-user socket; here we could act as server * Register a new vhost-user socket; here we could act as server
* (the default case), or client (when RTE_VHOST_USER_CLIENT) flag * (the default case), or client (when RTE_VHOST_USER_CLIENT) flag