* [dpdk-dev] [PATCH v6 01/19] vhost: fix messages results handling
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 16:18 ` Ilya Maximets
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 02/19] vhost: fix return code of messages requiring replies Maxime Coquelin
` (17 subsequent siblings)
18 siblings, 1 reply; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Return of message handling has now changed to an enum that can
take non-negative value that is not zero in case a reply is
needed. But the code checking the variable afterwards has not
been updated, leading to success messages handling being
treated as errors.
External post and pre callbacks return type needs also to be
changed to the new enum, so that its handling is consistent.
This is done in this patch alongside with the convertion of
its only user, vhost-crypto backend.
Fixes: 0bff510b5ea6 ("vhost: unify message handling function signature")
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost.h | 19 +++++++-----------
lib/librte_vhost/vhost_crypto.c | 24 +++++++++++------------
lib/librte_vhost/vhost_user.c | 34 +++++++++------------------------
lib/librte_vhost/vhost_user.h | 9 +++++++++
4 files changed, 36 insertions(+), 50 deletions(-)
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 25ffd7614..341b0a147 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -292,17 +292,15 @@ struct guest_page {
* vhost device id
* @param msg
* Message pointer.
- * @param require_reply
- * If the handler requires sending a reply, this varaible shall be written 1,
- * otherwise 0.
* @param skip_master
* If the handler requires skipping the master message handling, this variable
* shall be written 1, otherwise 0.
* @return
- * 0 on success, -1 on failure
+ * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
+ * VH_RESULT_ERR on failure
*/
-typedef int (*vhost_msg_pre_handle)(int vid, void *msg,
- uint32_t *require_reply, uint32_t *skip_master);
+typedef enum vh_result (*vhost_msg_pre_handle)(int vid, void *msg,
+ uint32_t *skip_master);
/**
* function prototype for the vhost backend to handler specific vhost user
@@ -312,14 +310,11 @@ typedef int (*vhost_msg_pre_handle)(int vid, void *msg,
* vhost device id
* @param msg
* Message pointer.
- * @param require_reply
- * If the handler requires sending a reply, this varaible shall be written 1,
- * otherwise 0.
* @return
- * 0 on success, -1 on failure
+ * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
+ * VH_RESULT_ERR on failure
*/
-typedef int (*vhost_msg_post_handle)(int vid, void *msg,
- uint32_t *require_reply);
+typedef enum vh_result (*vhost_msg_post_handle)(int vid, void *msg);
/**
* pre and post vhost user message handlers
diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c
index 57341ef8f..e534e1187 100644
--- a/lib/librte_vhost/vhost_crypto.c
+++ b/lib/librte_vhost/vhost_crypto.c
@@ -425,35 +425,33 @@ vhost_crypto_close_sess(struct vhost_crypto *vcrypto, uint64_t session_id)
return 0;
}
-static int
-vhost_crypto_msg_post_handler(int vid, void *msg, uint32_t *require_reply)
+static enum vh_result
+vhost_crypto_msg_post_handler(int vid, void *msg)
{
struct virtio_net *dev = get_device(vid);
struct vhost_crypto *vcrypto;
VhostUserMsg *vmsg = msg;
- int ret = 0;
+ enum vh_result ret = VH_RESULT_ERR;
- if (dev == NULL || require_reply == NULL) {
+ if (dev == NULL) {
VC_LOG_ERR("Invalid vid %i", vid);
- return -EINVAL;
+ return VH_RESULT_ERR;
}
vcrypto = dev->extern_data;
if (vcrypto == NULL) {
VC_LOG_ERR("Cannot find required data, is it initialized?");
- return -ENOENT;
+ return VH_RESULT_ERR;
}
- *require_reply = 0;
-
if (vmsg->request.master == VHOST_USER_CRYPTO_CREATE_SESS) {
vhost_crypto_create_sess(vcrypto,
&vmsg->payload.crypto_session);
- *require_reply = 1;
- } else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS)
- ret = vhost_crypto_close_sess(vcrypto, vmsg->payload.u64);
- else
- ret = -EINVAL;
+ ret = VH_RESULT_REPLY;
+ } else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS) {
+ if (!vhost_crypto_close_sess(vcrypto, vmsg->payload.u64))
+ ret = VH_RESULT_OK;
+ }
return ret;
}
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 7ef3fb4a4..e8375ca34 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -71,16 +71,6 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
[VHOST_USER_CRYPTO_CLOSE_SESS] = "VHOST_USER_CRYPTO_CLOSE_SESS",
};
-/* The possible results of a message handling function */
-enum vh_result {
- /* Message handling failed */
- VH_RESULT_ERR = -1,
- /* Message handling successful */
- VH_RESULT_OK = 0,
- /* Message handling successful and reply prepared */
- VH_RESULT_REPLY = 1,
-};
-
static uint64_t
get_blk_size(int fd)
{
@@ -1738,14 +1728,11 @@ vhost_user_msg_handler(int vid, int fd)
}
if (dev->extern_ops.pre_msg_handle) {
- uint32_t need_reply;
-
ret = (*dev->extern_ops.pre_msg_handle)(dev->vid,
- (void *)&msg, &need_reply, &skip_master);
- if (ret < 0)
+ (void *)&msg, &skip_master);
+ if (ret == VH_RESULT_ERR)
goto skip_to_reply;
-
- if (need_reply)
+ else if (ret == VH_RESULT_REPLY)
send_vhost_reply(fd, &msg);
if (skip_master)
@@ -1783,15 +1770,12 @@ vhost_user_msg_handler(int vid, int fd)
}
skip_to_post_handle:
- if (!ret && dev->extern_ops.post_msg_handle) {
- uint32_t need_reply;
-
+ if (ret != VH_RESULT_ERR && dev->extern_ops.post_msg_handle) {
ret = (*dev->extern_ops.post_msg_handle)(
- dev->vid, (void *)&msg, &need_reply);
- if (ret < 0)
+ dev->vid, (void *)&msg);
+ if (ret == VH_RESULT_ERR)
goto skip_to_reply;
-
- if (need_reply)
+ else if (ret == VH_RESULT_REPLY)
send_vhost_reply(fd, &msg);
}
@@ -1800,10 +1784,10 @@ vhost_user_msg_handler(int vid, int fd)
vhost_user_unlock_all_queue_pairs(dev);
if (msg.flags & VHOST_USER_NEED_REPLY) {
- msg.payload.u64 = !!ret;
+ msg.payload.u64 = ret == VH_RESULT_ERR;
msg.size = sizeof(msg.payload.u64);
send_vhost_reply(fd, &msg);
- } else if (ret) {
+ } else if (ret == VH_RESULT_ERR) {
RTE_LOG(ERR, VHOST_CONFIG,
"vhost message handling failed.\n");
return -1;
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index 42166adf2..62654f736 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -139,6 +139,15 @@ typedef struct VhostUserMsg {
/* The version of the protocol we support */
#define VHOST_USER_VERSION 0x1
+/* The possible results of a message handling function */
+enum vh_result {
+ /* Message handling failed */
+ VH_RESULT_ERR = -1,
+ /* Message handling successful */
+ VH_RESULT_OK = 0,
+ /* Message handling successful and reply prepared */
+ VH_RESULT_REPLY = 1,
+};
/* vhost_user.c */
int vhost_user_msg_handler(int vid, int fd);
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 01/19] vhost: fix messages results handling
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 01/19] vhost: fix messages results handling Maxime Coquelin
@ 2018-10-11 16:18 ` Ilya Maximets
2018-10-12 9:03 ` Maxime Coquelin
0 siblings, 1 reply; 30+ messages in thread
From: Ilya Maximets @ 2018-10-11 16:18 UTC (permalink / raw)
To: Maxime Coquelin, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable
On 11.10.2018 12:24, Maxime Coquelin wrote:
> Return of message handling has now changed to an enum that can
> take non-negative value that is not zero in case a reply is
> needed. But the code checking the variable afterwards has not
> been updated, leading to success messages handling being
> treated as errors.
>
> External post and pre callbacks return type needs also to be
> changed to the new enum, so that its handling is consistent.
> This is done in this patch alongside with the convertion of
> its only user, vhost-crypto backend.
>
> Fixes: 0bff510b5ea6 ("vhost: unify message handling function signature")
>
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
> lib/librte_vhost/vhost.h | 19 +++++++-----------
> lib/librte_vhost/vhost_crypto.c | 24 +++++++++++------------
> lib/librte_vhost/vhost_user.c | 34 +++++++++------------------------
> lib/librte_vhost/vhost_user.h | 9 +++++++++
> 4 files changed, 36 insertions(+), 50 deletions(-)
>
> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
> index 25ffd7614..341b0a147 100644
> --- a/lib/librte_vhost/vhost.h
> +++ b/lib/librte_vhost/vhost.h
> @@ -292,17 +292,15 @@ struct guest_page {
> * vhost device id
> * @param msg
> * Message pointer.
> - * @param require_reply
> - * If the handler requires sending a reply, this varaible shall be written 1,
> - * otherwise 0.
> * @param skip_master
> * If the handler requires skipping the master message handling, this variable
> * shall be written 1, otherwise 0.
> * @return
> - * 0 on success, -1 on failure
> + * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
> + * VH_RESULT_ERR on failure
> */
> -typedef int (*vhost_msg_pre_handle)(int vid, void *msg,
> - uint32_t *require_reply, uint32_t *skip_master);
> +typedef enum vh_result (*vhost_msg_pre_handle)(int vid, void *msg,
> + uint32_t *skip_master);
>
> /**
> * function prototype for the vhost backend to handler specific vhost user
> @@ -312,14 +310,11 @@ typedef int (*vhost_msg_pre_handle)(int vid, void *msg,
> * vhost device id
> * @param msg
> * Message pointer.
> - * @param require_reply
> - * If the handler requires sending a reply, this varaible shall be written 1,
> - * otherwise 0.
> * @return
> - * 0 on success, -1 on failure
> + * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
> + * VH_RESULT_ERR on failure
> */
> -typedef int (*vhost_msg_post_handle)(int vid, void *msg,
> - uint32_t *require_reply);
> +typedef enum vh_result (*vhost_msg_post_handle)(int vid, void *msg);
I think that function prototypes and the enum definition should be
in the same header, because headers are not including each other directly.
Not sure in which one, but it seems that handlers are vhost-user specific.
Are they? If so, meybe we could move the prototypes to vhost_user.h.
>
> /**
> * pre and post vhost user message handlers
> diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c
> index 57341ef8f..e534e1187 100644
> --- a/lib/librte_vhost/vhost_crypto.c
> +++ b/lib/librte_vhost/vhost_crypto.c
> @@ -425,35 +425,33 @@ vhost_crypto_close_sess(struct vhost_crypto *vcrypto, uint64_t session_id)
> return 0;
> }
>
> -static int
> -vhost_crypto_msg_post_handler(int vid, void *msg, uint32_t *require_reply)
> +static enum vh_result
> +vhost_crypto_msg_post_handler(int vid, void *msg)
> {
> struct virtio_net *dev = get_device(vid);
> struct vhost_crypto *vcrypto;
> VhostUserMsg *vmsg = msg;
> - int ret = 0;
> + enum vh_result ret = VH_RESULT_ERR;
>
> - if (dev == NULL || require_reply == NULL) {
> + if (dev == NULL) {
> VC_LOG_ERR("Invalid vid %i", vid);
> - return -EINVAL;
> + return VH_RESULT_ERR;
> }
>
> vcrypto = dev->extern_data;
> if (vcrypto == NULL) {
> VC_LOG_ERR("Cannot find required data, is it initialized?");
> - return -ENOENT;
> + return VH_RESULT_ERR;
> }
>
> - *require_reply = 0;
> -
> if (vmsg->request.master == VHOST_USER_CRYPTO_CREATE_SESS) {
> vhost_crypto_create_sess(vcrypto,
> &vmsg->payload.crypto_session);
> - *require_reply = 1;
> - } else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS)
> - ret = vhost_crypto_close_sess(vcrypto, vmsg->payload.u64);
> - else
> - ret = -EINVAL;
> + ret = VH_RESULT_REPLY;
Maybe we need to print error message here? Seems that we're loosing
the information about error type.
> + } else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS) {
> + if (!vhost_crypto_close_sess(vcrypto, vmsg->payload.u64))
> + ret = VH_RESULT_OK;
> + }
>
> return ret;
> }
> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
> index 7ef3fb4a4..e8375ca34 100644
> --- a/lib/librte_vhost/vhost_user.c
> +++ b/lib/librte_vhost/vhost_user.c
> @@ -71,16 +71,6 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
> [VHOST_USER_CRYPTO_CLOSE_SESS] = "VHOST_USER_CRYPTO_CLOSE_SESS",
> };
>
> -/* The possible results of a message handling function */
> -enum vh_result {
> - /* Message handling failed */
> - VH_RESULT_ERR = -1,
> - /* Message handling successful */
> - VH_RESULT_OK = 0,
> - /* Message handling successful and reply prepared */
> - VH_RESULT_REPLY = 1,
> -};
> -
> static uint64_t
> get_blk_size(int fd)
> {
> @@ -1738,14 +1728,11 @@ vhost_user_msg_handler(int vid, int fd)
> }
>
> if (dev->extern_ops.pre_msg_handle) {
> - uint32_t need_reply;
> -
> ret = (*dev->extern_ops.pre_msg_handle)(dev->vid,
> - (void *)&msg, &need_reply, &skip_master);
> - if (ret < 0)
> + (void *)&msg, &skip_master);
> + if (ret == VH_RESULT_ERR)
> goto skip_to_reply;
> -
> - if (need_reply)
> + else if (ret == VH_RESULT_REPLY)
> send_vhost_reply(fd, &msg);
>
> if (skip_master)
> @@ -1783,15 +1770,12 @@ vhost_user_msg_handler(int vid, int fd)
> }
>
> skip_to_post_handle:
> - if (!ret && dev->extern_ops.post_msg_handle) {
> - uint32_t need_reply;
> -
> + if (ret != VH_RESULT_ERR && dev->extern_ops.post_msg_handle) {
> ret = (*dev->extern_ops.post_msg_handle)(
> - dev->vid, (void *)&msg, &need_reply);
> - if (ret < 0)
> + dev->vid, (void *)&msg);
> + if (ret == VH_RESULT_ERR)
> goto skip_to_reply;
> -
> - if (need_reply)
> + else if (ret == VH_RESULT_REPLY)
> send_vhost_reply(fd, &msg);
> }
>
> @@ -1800,10 +1784,10 @@ vhost_user_msg_handler(int vid, int fd)
> vhost_user_unlock_all_queue_pairs(dev);
>
> if (msg.flags & VHOST_USER_NEED_REPLY) {
> - msg.payload.u64 = !!ret;
> + msg.payload.u64 = ret == VH_RESULT_ERR;
> msg.size = sizeof(msg.payload.u64);
> send_vhost_reply(fd, &msg);
> - } else if (ret) {
> + } else if (ret == VH_RESULT_ERR) {
> RTE_LOG(ERR, VHOST_CONFIG,
> "vhost message handling failed.\n");
> return -1;
> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
> index 42166adf2..62654f736 100644
> --- a/lib/librte_vhost/vhost_user.h
> +++ b/lib/librte_vhost/vhost_user.h
> @@ -139,6 +139,15 @@ typedef struct VhostUserMsg {
> /* The version of the protocol we support */
> #define VHOST_USER_VERSION 0x1
>
> +/* The possible results of a message handling function */
> +enum vh_result {
> + /* Message handling failed */
> + VH_RESULT_ERR = -1,
> + /* Message handling successful */
> + VH_RESULT_OK = 0,
> + /* Message handling successful and reply prepared */
> + VH_RESULT_REPLY = 1,
> +};
>
> /* vhost_user.c */
> int vhost_user_msg_handler(int vid, int fd);
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 01/19] vhost: fix messages results handling
2018-10-11 16:18 ` Ilya Maximets
@ 2018-10-12 9:03 ` Maxime Coquelin
2018-10-12 9:55 ` Maxime Coquelin
0 siblings, 1 reply; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-12 9:03 UTC (permalink / raw)
To: Ilya Maximets, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable
On 10/11/2018 06:18 PM, Ilya Maximets wrote:
> On 11.10.2018 12:24, Maxime Coquelin wrote:
>> Return of message handling has now changed to an enum that can
>> take non-negative value that is not zero in case a reply is
>> needed. But the code checking the variable afterwards has not
>> been updated, leading to success messages handling being
>> treated as errors.
>>
>> External post and pre callbacks return type needs also to be
>> changed to the new enum, so that its handling is consistent.
>> This is done in this patch alongside with the convertion of
>> its only user, vhost-crypto backend.
>>
>> Fixes: 0bff510b5ea6 ("vhost: unify message handling function signature")
>>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>> lib/librte_vhost/vhost.h | 19 +++++++-----------
>> lib/librte_vhost/vhost_crypto.c | 24 +++++++++++------------
>> lib/librte_vhost/vhost_user.c | 34 +++++++++------------------------
>> lib/librte_vhost/vhost_user.h | 9 +++++++++
>> 4 files changed, 36 insertions(+), 50 deletions(-)
>>
>> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
>> index 25ffd7614..341b0a147 100644
>> --- a/lib/librte_vhost/vhost.h
>> +++ b/lib/librte_vhost/vhost.h
>> @@ -292,17 +292,15 @@ struct guest_page {
>> * vhost device id
>> * @param msg
>> * Message pointer.
>> - * @param require_reply
>> - * If the handler requires sending a reply, this varaible shall be written 1,
>> - * otherwise 0.
>> * @param skip_master
>> * If the handler requires skipping the master message handling, this variable
>> * shall be written 1, otherwise 0.
>> * @return
>> - * 0 on success, -1 on failure
>> + * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
>> + * VH_RESULT_ERR on failure
>> */
>> -typedef int (*vhost_msg_pre_handle)(int vid, void *msg,
>> - uint32_t *require_reply, uint32_t *skip_master);
>> +typedef enum vh_result (*vhost_msg_pre_handle)(int vid, void *msg,
>> + uint32_t *skip_master);
>>
>> /**
>> * function prototype for the vhost backend to handler specific vhost user
>> @@ -312,14 +310,11 @@ typedef int (*vhost_msg_pre_handle)(int vid, void *msg,
>> * vhost device id
>> * @param msg
>> * Message pointer.
>> - * @param require_reply
>> - * If the handler requires sending a reply, this varaible shall be written 1,
>> - * otherwise 0.
>> * @return
>> - * 0 on success, -1 on failure
>> + * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
>> + * VH_RESULT_ERR on failure
>> */
>> -typedef int (*vhost_msg_post_handle)(int vid, void *msg,
>> - uint32_t *require_reply);
>> +typedef enum vh_result (*vhost_msg_post_handle)(int vid, void *msg);
>
> I think that function prototypes and the enum definition should be
> in the same header, because headers are not including each other directly.
> Not sure in which one, but it seems that handlers are vhost-user specific.
> Are they? If so, meybe we could move the prototypes to vhost_user.h.
Makes sense, I will move the definitions to vhost-user.h
>>
>> /**
>> * pre and post vhost user message handlers
>> diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c
>> index 57341ef8f..e534e1187 100644
>> --- a/lib/librte_vhost/vhost_crypto.c
>> +++ b/lib/librte_vhost/vhost_crypto.c
>> @@ -425,35 +425,33 @@ vhost_crypto_close_sess(struct vhost_crypto *vcrypto, uint64_t session_id)
>> return 0;
>> }
>>
>> -static int
>> -vhost_crypto_msg_post_handler(int vid, void *msg, uint32_t *require_reply)
>> +static enum vh_result
>> +vhost_crypto_msg_post_handler(int vid, void *msg)
>> {
>> struct virtio_net *dev = get_device(vid);
>> struct vhost_crypto *vcrypto;
>> VhostUserMsg *vmsg = msg;
>> - int ret = 0;
>> + enum vh_result ret = VH_RESULT_ERR;
>>
>> - if (dev == NULL || require_reply == NULL) {
>> + if (dev == NULL) {
>> VC_LOG_ERR("Invalid vid %i", vid);
>> - return -EINVAL;
>> + return VH_RESULT_ERR;
>> }
>>
>> vcrypto = dev->extern_data;
>> if (vcrypto == NULL) {
>> VC_LOG_ERR("Cannot find required data, is it initialized?");
>> - return -ENOENT;
>> + return VH_RESULT_ERR;
>> }
>>
>> - *require_reply = 0;
>> -
>> if (vmsg->request.master == VHOST_USER_CRYPTO_CREATE_SESS) {
>> vhost_crypto_create_sess(vcrypto,
>> &vmsg->payload.crypto_session);
>> - *require_reply = 1;
>> - } else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS)
>> - ret = vhost_crypto_close_sess(vcrypto, vmsg->payload.u64);
>> - else
>> - ret = -EINVAL;
>> + ret = VH_RESULT_REPLY;
>
> Maybe we need to print error message here? Seems that we're loosing
> the information about error type.
Yes, I can add a message here.
>> + } else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS) {
>> + if (!vhost_crypto_close_sess(vcrypto, vmsg->payload.u64))
>> + ret = VH_RESULT_OK;
>> + }
>>
>> return ret;
>> }
>> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
>> index 7ef3fb4a4..e8375ca34 100644
>> --- a/lib/librte_vhost/vhost_user.c
>> +++ b/lib/librte_vhost/vhost_user.c
>> @@ -71,16 +71,6 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
>> [VHOST_USER_CRYPTO_CLOSE_SESS] = "VHOST_USER_CRYPTO_CLOSE_SESS",
>> };
>>
>> -/* The possible results of a message handling function */
>> -enum vh_result {
>> - /* Message handling failed */
>> - VH_RESULT_ERR = -1,
>> - /* Message handling successful */
>> - VH_RESULT_OK = 0,
>> - /* Message handling successful and reply prepared */
>> - VH_RESULT_REPLY = 1,
>> -};
>> -
>> static uint64_t
>> get_blk_size(int fd)
>> {
>> @@ -1738,14 +1728,11 @@ vhost_user_msg_handler(int vid, int fd)
>> }
>>
>> if (dev->extern_ops.pre_msg_handle) {
>> - uint32_t need_reply;
>> -
>> ret = (*dev->extern_ops.pre_msg_handle)(dev->vid,
>> - (void *)&msg, &need_reply, &skip_master);
>> - if (ret < 0)
>> + (void *)&msg, &skip_master);
>> + if (ret == VH_RESULT_ERR)
>> goto skip_to_reply;
>> -
>> - if (need_reply)
>> + else if (ret == VH_RESULT_REPLY)
>> send_vhost_reply(fd, &msg);
>>
>> if (skip_master)
>> @@ -1783,15 +1770,12 @@ vhost_user_msg_handler(int vid, int fd)
>> }
>>
>> skip_to_post_handle:
>> - if (!ret && dev->extern_ops.post_msg_handle) {
>> - uint32_t need_reply;
>> -
>> + if (ret != VH_RESULT_ERR && dev->extern_ops.post_msg_handle) {
>> ret = (*dev->extern_ops.post_msg_handle)(
>> - dev->vid, (void *)&msg, &need_reply);
>> - if (ret < 0)
>> + dev->vid, (void *)&msg);
>> + if (ret == VH_RESULT_ERR)
>> goto skip_to_reply;
>> -
>> - if (need_reply)
>> + else if (ret == VH_RESULT_REPLY)
>> send_vhost_reply(fd, &msg);
>> }
>>
>> @@ -1800,10 +1784,10 @@ vhost_user_msg_handler(int vid, int fd)
>> vhost_user_unlock_all_queue_pairs(dev);
>>
>> if (msg.flags & VHOST_USER_NEED_REPLY) {
>> - msg.payload.u64 = !!ret;
>> + msg.payload.u64 = ret == VH_RESULT_ERR;
>> msg.size = sizeof(msg.payload.u64);
>> send_vhost_reply(fd, &msg);
>> - } else if (ret) {
>> + } else if (ret == VH_RESULT_ERR) {
>> RTE_LOG(ERR, VHOST_CONFIG,
>> "vhost message handling failed.\n");
>> return -1;
>> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
>> index 42166adf2..62654f736 100644
>> --- a/lib/librte_vhost/vhost_user.h
>> +++ b/lib/librte_vhost/vhost_user.h
>> @@ -139,6 +139,15 @@ typedef struct VhostUserMsg {
>> /* The version of the protocol we support */
>> #define VHOST_USER_VERSION 0x1
>>
>> +/* The possible results of a message handling function */
>> +enum vh_result {
>> + /* Message handling failed */
>> + VH_RESULT_ERR = -1,
>> + /* Message handling successful */
>> + VH_RESULT_OK = 0,
>> + /* Message handling successful and reply prepared */
>> + VH_RESULT_REPLY = 1,
>> +};
>>
>> /* vhost_user.c */
>> int vhost_user_msg_handler(int vid, int fd);
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 01/19] vhost: fix messages results handling
2018-10-12 9:03 ` Maxime Coquelin
@ 2018-10-12 9:55 ` Maxime Coquelin
0 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-12 9:55 UTC (permalink / raw)
To: Ilya Maximets, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable
On 10/12/2018 11:03 AM, Maxime Coquelin wrote:
>
>
> On 10/11/2018 06:18 PM, Ilya Maximets wrote:
>> On 11.10.2018 12:24, Maxime Coquelin wrote:
>>> Return of message handling has now changed to an enum that can
>>> take non-negative value that is not zero in case a reply is
>>> needed. But the code checking the variable afterwards has not
>>> been updated, leading to success messages handling being
>>> treated as errors.
>>>
>>> External post and pre callbacks return type needs also to be
>>> changed to the new enum, so that its handling is consistent.
>>> This is done in this patch alongside with the convertion of
>>> its only user, vhost-crypto backend.
>>>
>>> Fixes: 0bff510b5ea6 ("vhost: unify message handling function signature")
>>>
>>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>>> ---
>>> lib/librte_vhost/vhost.h | 19 +++++++-----------
>>> lib/librte_vhost/vhost_crypto.c | 24 +++++++++++------------
>>> lib/librte_vhost/vhost_user.c | 34 +++++++++------------------------
>>> lib/librte_vhost/vhost_user.h | 9 +++++++++
>>> 4 files changed, 36 insertions(+), 50 deletions(-)
>>>
>>> diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
>>> index 25ffd7614..341b0a147 100644
>>> --- a/lib/librte_vhost/vhost.h
>>> +++ b/lib/librte_vhost/vhost.h
>>> @@ -292,17 +292,15 @@ struct guest_page {
>>> * vhost device id
>>> * @param msg
>>> * Message pointer.
>>> - * @param require_reply
>>> - * If the handler requires sending a reply, this varaible shall be
>>> written 1,
>>> - * otherwise 0.
>>> * @param skip_master
>>> * If the handler requires skipping the master message handling,
>>> this variable
>>> * shall be written 1, otherwise 0.
>>> * @return
>>> - * 0 on success, -1 on failure
>>> + * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
>>> + * VH_RESULT_ERR on failure
>>> */
>>> -typedef int (*vhost_msg_pre_handle)(int vid, void *msg,
>>> - uint32_t *require_reply, uint32_t *skip_master);
>>> +typedef enum vh_result (*vhost_msg_pre_handle)(int vid, void *msg,
>>> + uint32_t *skip_master);
>>> /**
>>> * function prototype for the vhost backend to handler specific
>>> vhost user
>>> @@ -312,14 +310,11 @@ typedef int (*vhost_msg_pre_handle)(int vid,
>>> void *msg,
>>> * vhost device id
>>> * @param msg
>>> * Message pointer.
>>> - * @param require_reply
>>> - * If the handler requires sending a reply, this varaible shall be
>>> written 1,
>>> - * otherwise 0.
>>> * @return
>>> - * 0 on success, -1 on failure
>>> + * VH_RESULT_OK on success, VH_RESULT_REPLY on success with reply,
>>> + * VH_RESULT_ERR on failure
>>> */
>>> -typedef int (*vhost_msg_post_handle)(int vid, void *msg,
>>> - uint32_t *require_reply);
>>> +typedef enum vh_result (*vhost_msg_post_handle)(int vid, void *msg);
>>
>> I think that function prototypes and the enum definition should be
>> in the same header, because headers are not including each other
>> directly.
>> Not sure in which one, but it seems that handlers are vhost-user
>> specific.
>> Are they? If so, meybe we could move the prototypes to vhost_user.h.
>
> Makes sense, I will move the definitions to vhost-user.h
So, makes sense, but does not build... as vhost_user_extern_ops struct
is used in struct virtio_net.
I will move the enum definition in vhost.h for the time being,
but we might want to do some rework in the future.
>>> /**
>>> * pre and post vhost user message handlers
>>> diff --git a/lib/librte_vhost/vhost_crypto.c
>>> b/lib/librte_vhost/vhost_crypto.c
>>> index 57341ef8f..e534e1187 100644
>>> --- a/lib/librte_vhost/vhost_crypto.c
>>> +++ b/lib/librte_vhost/vhost_crypto.c
>>> @@ -425,35 +425,33 @@ vhost_crypto_close_sess(struct vhost_crypto
>>> *vcrypto, uint64_t session_id)
>>> return 0;
>>> }
>>> -static int
>>> -vhost_crypto_msg_post_handler(int vid, void *msg, uint32_t
>>> *require_reply)
>>> +static enum vh_result
>>> +vhost_crypto_msg_post_handler(int vid, void *msg)
>>> {
>>> struct virtio_net *dev = get_device(vid);
>>> struct vhost_crypto *vcrypto;
>>> VhostUserMsg *vmsg = msg;
>>> - int ret = 0;
>>> + enum vh_result ret = VH_RESULT_ERR;
>>> - if (dev == NULL || require_reply == NULL) {
>>> + if (dev == NULL) {
>>> VC_LOG_ERR("Invalid vid %i", vid);
>>> - return -EINVAL;
>>> + return VH_RESULT_ERR;
>>> }
>>> vcrypto = dev->extern_data;
>>> if (vcrypto == NULL) {
>>> VC_LOG_ERR("Cannot find required data, is it initialized?");
>>> - return -ENOENT;
>>> + return VH_RESULT_ERR;
>>> }
>>> - *require_reply = 0;
>>> -
>>> if (vmsg->request.master == VHOST_USER_CRYPTO_CREATE_SESS) {
>>> vhost_crypto_create_sess(vcrypto,
>>> &vmsg->payload.crypto_session);
>>> - *require_reply = 1;
>>> - } else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS)
>>> - ret = vhost_crypto_close_sess(vcrypto, vmsg->payload.u64);
>>> - else
>>> - ret = -EINVAL;
>>> + ret = VH_RESULT_REPLY;
>>
>> Maybe we need to print error message here? Seems that we're loosing
>> the information about error type.
>
> Yes, I can add a message here.
Actually, looking again at the details, we should not return an error
here.
Indeed, when the external backend register a post handling callback, it
gets called for every message, even the ones that don't have to be
handled by the external backend.
So I propose to just return VH_RESULT_OK here in case the message is not
handled by the handler.
>
>>> + } else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS) {
>>> + if (!vhost_crypto_close_sess(vcrypto, vmsg->payload.u64))
>>> + ret = VH_RESULT_OK;
>>> + }
>>> return ret;
>>> }
>>> diff --git a/lib/librte_vhost/vhost_user.c
>>> b/lib/librte_vhost/vhost_user.c
>>> index 7ef3fb4a4..e8375ca34 100644
>>> --- a/lib/librte_vhost/vhost_user.c
>>> +++ b/lib/librte_vhost/vhost_user.c
>>> @@ -71,16 +71,6 @@ static const char
>>> *vhost_message_str[VHOST_USER_MAX] = {
>>> [VHOST_USER_CRYPTO_CLOSE_SESS] = "VHOST_USER_CRYPTO_CLOSE_SESS",
>>> };
>>> -/* The possible results of a message handling function */
>>> -enum vh_result {
>>> - /* Message handling failed */
>>> - VH_RESULT_ERR = -1,
>>> - /* Message handling successful */
>>> - VH_RESULT_OK = 0,
>>> - /* Message handling successful and reply prepared */
>>> - VH_RESULT_REPLY = 1,
>>> -};
>>> -
>>> static uint64_t
>>> get_blk_size(int fd)
>>> {
>>> @@ -1738,14 +1728,11 @@ vhost_user_msg_handler(int vid, int fd)
>>> }
>>> if (dev->extern_ops.pre_msg_handle) {
>>> - uint32_t need_reply;
>>> -
>>> ret = (*dev->extern_ops.pre_msg_handle)(dev->vid,
>>> - (void *)&msg, &need_reply, &skip_master);
>>> - if (ret < 0)
>>> + (void *)&msg, &skip_master);
>>> + if (ret == VH_RESULT_ERR)
>>> goto skip_to_reply;
>>> -
>>> - if (need_reply)
>>> + else if (ret == VH_RESULT_REPLY)
>>> send_vhost_reply(fd, &msg);
>>> if (skip_master)
>>> @@ -1783,15 +1770,12 @@ vhost_user_msg_handler(int vid, int fd)
>>> }
>>> skip_to_post_handle:
>>> - if (!ret && dev->extern_ops.post_msg_handle) {
>>> - uint32_t need_reply;
>>> -
>>> + if (ret != VH_RESULT_ERR && dev->extern_ops.post_msg_handle) {
>>> ret = (*dev->extern_ops.post_msg_handle)(
>>> - dev->vid, (void *)&msg, &need_reply);
>>> - if (ret < 0)
>>> + dev->vid, (void *)&msg);
>>> + if (ret == VH_RESULT_ERR)
>>> goto skip_to_reply;
>>> -
>>> - if (need_reply)
>>> + else if (ret == VH_RESULT_REPLY)
>>> send_vhost_reply(fd, &msg);
>>> }
>>> @@ -1800,10 +1784,10 @@ vhost_user_msg_handler(int vid, int fd)
>>> vhost_user_unlock_all_queue_pairs(dev);
>>> if (msg.flags & VHOST_USER_NEED_REPLY) {
>>> - msg.payload.u64 = !!ret;
>>> + msg.payload.u64 = ret == VH_RESULT_ERR;
>>> msg.size = sizeof(msg.payload.u64);
>>> send_vhost_reply(fd, &msg);
>>> - } else if (ret) {
>>> + } else if (ret == VH_RESULT_ERR) {
>>> RTE_LOG(ERR, VHOST_CONFIG,
>>> "vhost message handling failed.\n");
>>> return -1;
>>> diff --git a/lib/librte_vhost/vhost_user.h
>>> b/lib/librte_vhost/vhost_user.h
>>> index 42166adf2..62654f736 100644
>>> --- a/lib/librte_vhost/vhost_user.h
>>> +++ b/lib/librte_vhost/vhost_user.h
>>> @@ -139,6 +139,15 @@ typedef struct VhostUserMsg {
>>> /* The version of the protocol we support */
>>> #define VHOST_USER_VERSION 0x1
>>> +/* The possible results of a message handling function */
>>> +enum vh_result {
>>> + /* Message handling failed */
>>> + VH_RESULT_ERR = -1,
>>> + /* Message handling successful */
>>> + VH_RESULT_OK = 0,
>>> + /* Message handling successful and reply prepared */
>>> + VH_RESULT_REPLY = 1,
>>> +};
>>> /* vhost_user.c */
>>> int vhost_user_msg_handler(int vid, int fd);
>>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 02/19] vhost: fix return code of messages requiring replies
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 01/19] vhost: fix messages results handling Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 03/19] vhost: clarify reply-ack in case a reply was already sent Maxime Coquelin
` (16 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
VHOST_USER_GET_PROTOCOL_FEATURES, VHOST_USER_GET_VRING_BASE
and VHOST_USER_SET_LOG_BASE require replies, so their handlers
should return VH_RESULT_REPLY, not VH_RESULT_OK.
Fixes: 0bff510b5ea6 ("vhost: unify message handling function signature")
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Ilya Maximets <i.maximets@samsung.com>
Reviewed-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/vhost_user.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index e8375ca34..09a90a20b 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -1151,7 +1151,7 @@ vhost_user_get_vring_base(struct virtio_net **pdev,
msg->size = sizeof(msg->payload.state);
- return VH_RESULT_OK;
+ return VH_RESULT_REPLY;
}
/*
@@ -1208,7 +1208,7 @@ vhost_user_get_protocol_features(struct virtio_net **pdev,
msg->payload.u64 = protocol_features;
msg->size = sizeof(msg->payload.u64);
- return VH_RESULT_OK;
+ return VH_RESULT_REPLY;
}
static int
@@ -1288,7 +1288,7 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg)
msg->size = sizeof(msg->payload.u64);
- return VH_RESULT_OK;
+ return VH_RESULT_REPLY;
}
static int vhost_user_set_log_fd(struct virtio_net **pdev __rte_unused,
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 03/19] vhost: clarify reply-ack in case a reply was already sent
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 01/19] vhost: fix messages results handling Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 02/19] vhost: fix return code of messages requiring replies Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 04/19] vhost: fix payload size of reply Maxime Coquelin
` (15 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
For messages that require a reply, a second ack should not be
sent when reply-ack protocol feature is negotiated, even if
the corresponding flag is set in the message.
The code is compliant with the spec but it isn't clear it is,
so this patch adds a comment to make it explicit.
Suggested-by: Ilya Maximets <i.maximets@samsung.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Ilya Maximets <i.maximets@samsung.com>
Reviewed-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/vhost_user.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 09a90a20b..a7729990d 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -1783,6 +1783,11 @@ vhost_user_msg_handler(int vid, int fd)
if (unlock_required)
vhost_user_unlock_all_queue_pairs(dev);
+ /*
+ * If the request required a reply that was already sent,
+ * this optional reply-ack won't be sent as the
+ * VHOST_USER_NEED_REPLY was cleared in send_vhost_reply().
+ */
if (msg.flags & VHOST_USER_NEED_REPLY) {
msg.payload.u64 = ret == VH_RESULT_ERR;
msg.size = sizeof(msg.payload.u64);
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 04/19] vhost: fix payload size of reply
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (2 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 03/19] vhost: clarify reply-ack in case a reply was already sent Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 05/19] vhost: fix error handling when mem table gets updated Maxime Coquelin
` (14 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
QEMU doesn't expect any payload for the reply of
VHOST_USER_SET_LOG_BASE request, so don't send any.
Note that the Vhost-user specification isn't clear about
it and would need to be fixed.
Fixes: 54f9e32305d4 ("vhost: handle dirty pages logging request")
Cc: stable@dpdk.org
Reported-by: Ilya Maximets <i.maximets@samsung.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Ilya Maximets <i.maximets@samsung.com>
---
lib/librte_vhost/vhost_user.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index a7729990d..1ef02c943 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -1286,7 +1286,11 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg)
dev->log_base = dev->log_addr + off;
dev->log_size = size;
- msg->size = sizeof(msg->payload.u64);
+ /*
+ * The spec is not clear about it (yet), but QEMU doesn't expect
+ * any payload in the reply.
+ */
+ msg->size = 0;
return VH_RESULT_REPLY;
}
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 05/19] vhost: fix error handling when mem table gets updated
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (3 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 04/19] vhost: fix payload size of reply Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 06/19] vhost: define postcopy protocol flag Maxime Coquelin
` (13 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
When the memory table gets updated, the rings addresses need
to be translated again. If it fails, we need to exit cleanly
by unmapping memory regions.
Fixes: d5022533c20a ("vhost: retranslate vring addr when memory table changes")
Cc: stable@dpdk.org
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Ilya Maximets <i.maximets@samsung.com>
---
lib/librte_vhost/vhost_user.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 1ef02c943..83d3e6321 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -953,8 +953,10 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg)
vring_invalidate(dev, vq);
dev = translate_ring_addresses(dev, i);
- if (!dev)
- return VH_RESULT_ERR;
+ if (!dev) {
+ dev = *pdev;
+ goto err_mmap;
+ }
*pdev = dev;
}
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 06/19] vhost: define postcopy protocol flag
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (4 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 05/19] vhost: fix error handling when mem table gets updated Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it Maxime Coquelin
` (12 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Ilya Maximets <i.maximets@samsung.com>
Reviewed-by: Tiwei Bie <tiwei.bie@intel.com>
---
lib/librte_vhost/rte_vhost.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index b02673d4a..9292c89c5 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -58,6 +58,10 @@ extern "C" {
#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7
#endif
+#ifndef VHOST_USER_PROTOCOL_F_PAGEFAULT
+#define VHOST_USER_PROTOCOL_F_PAGEFAULT 8
+#endif
+
#ifndef VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD
#define VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD 10
#endif
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (5 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 06/19] vhost: define postcopy protocol flag Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 15:59 ` Ilya Maximets
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 08/19] vhost: pass socket fd to message handling callbacks Maxime Coquelin
` (11 subsequent siblings)
18 siblings, 1 reply; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
As soon as some ancillary data (fds) are received, it is copied
without checking its length.
This patch adds the number of fds received to the message,
which is set in read_vhost_message().
This is preliminary work to support sending fds to Qemu.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/socket.c | 25 ++++++++++++++++++++-----
lib/librte_vhost/vhost_user.c | 2 +-
lib/librte_vhost/vhost_user.h | 4 +++-
3 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index d63031747..3b0287a26 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -94,18 +94,24 @@ static struct vhost_user vhost_user = {
.mutex = PTHREAD_MUTEX_INITIALIZER,
};
-/* return bytes# of read on success or negative val on failure. */
+/*
+ * return bytes# of read on success or negative val on failure. Update fdnum
+ * with number of fds read.
+ */
int
-read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
+read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
+ int *fd_num)
{
struct iovec iov;
struct msghdr msgh;
- size_t fdsize = fd_num * sizeof(int);
- char control[CMSG_SPACE(fdsize)];
+ char control[CMSG_SPACE(max_fds * sizeof(int))];
struct cmsghdr *cmsg;
int got_fds = 0;
+ int *tmp_fds;
int ret;
+ *fd_num = 0;
+
memset(&msgh, 0, sizeof(msgh));
iov.iov_base = buf;
iov.iov_len = buflen;
@@ -131,13 +137,22 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
if ((cmsg->cmsg_level == SOL_SOCKET) &&
(cmsg->cmsg_type == SCM_RIGHTS)) {
got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
+ if (got_fds > max_fds) {
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "Received msg contains more fds than supported\n");
+ tmp_fds = (int *)CMSG_DATA(cmsg);
+ while (got_fds--)
+ close(tmp_fds[got_fds]);
+ return -1;
+ }
+ *fd_num = got_fds;
memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int));
break;
}
}
/* Clear out unused file descriptors */
- while (got_fds < fd_num)
+ while (got_fds < max_fds)
fds[got_fds++] = -1;
return ret;
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 83d3e6321..c1c5f35ff 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -1509,7 +1509,7 @@ read_vhost_message(int sockfd, struct VhostUserMsg *msg)
int ret;
ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,
- msg->fds, VHOST_MEMORY_MAX_NREGIONS);
+ msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);
if (ret <= 0)
return ret;
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index 62654f736..9a91d496b 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -132,6 +132,7 @@ typedef struct VhostUserMsg {
VhostUserVringArea area;
} payload;
int fds[VHOST_MEMORY_MAX_NREGIONS];
+ int fd_num;
} __attribute((packed)) VhostUserMsg;
#define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
@@ -155,7 +156,8 @@ int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
int vhost_user_host_notifier_ctrl(int vid, bool enable);
/* socket.c */
-int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
+int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
+ int *fd_num);
int send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
#endif
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it Maxime Coquelin
@ 2018-10-11 15:59 ` Ilya Maximets
2018-10-12 8:43 ` Maxime Coquelin
0 siblings, 1 reply; 30+ messages in thread
From: Ilya Maximets @ 2018-10-11 15:59 UTC (permalink / raw)
To: Maxime Coquelin, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable
On 11.10.2018 12:24, Maxime Coquelin wrote:
> As soon as some ancillary data (fds) are received, it is copied
> without checking its length.
>
> This patch adds the number of fds received to the message,
> which is set in read_vhost_message().
>
> This is preliminary work to support sending fds to Qemu.
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> ---
> lib/librte_vhost/socket.c | 25 ++++++++++++++++++++-----
> lib/librte_vhost/vhost_user.c | 2 +-
> lib/librte_vhost/vhost_user.h | 4 +++-
> 3 files changed, 24 insertions(+), 7 deletions(-)
>
> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
> index d63031747..3b0287a26 100644
> --- a/lib/librte_vhost/socket.c
> +++ b/lib/librte_vhost/socket.c
> @@ -94,18 +94,24 @@ static struct vhost_user vhost_user = {
> .mutex = PTHREAD_MUTEX_INITIALIZER,
> };
>
> -/* return bytes# of read on success or negative val on failure. */
> +/*
> + * return bytes# of read on success or negative val on failure. Update fdnum
> + * with number of fds read.
> + */
> int
> -read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
> +read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
> + int *fd_num)
> {
> struct iovec iov;
> struct msghdr msgh;
> - size_t fdsize = fd_num * sizeof(int);
> - char control[CMSG_SPACE(fdsize)];
> + char control[CMSG_SPACE(max_fds * sizeof(int))];
> struct cmsghdr *cmsg;
> int got_fds = 0;
> + int *tmp_fds;
> int ret;
>
> + *fd_num = 0;
> +
> memset(&msgh, 0, sizeof(msgh));
> iov.iov_base = buf;
> iov.iov_len = buflen;
> @@ -131,13 +137,22 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
> if ((cmsg->cmsg_level == SOL_SOCKET) &&
> (cmsg->cmsg_type == SCM_RIGHTS)) {
> got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
> + if (got_fds > max_fds) {
Hmm. I just noticed that 'msg_controllen' is set to receive
not more than max_fds descriptors. So, this case should not
be possible. We will receive MSG_CTRUNC and return before
the loop.
> + RTE_LOG(ERR, VHOST_CONFIG,
> + "Received msg contains more fds than supported\n");
> + tmp_fds = (int *)CMSG_DATA(cmsg);
> + while (got_fds--)
> + close(tmp_fds[got_fds]);
> + return -1;
> + }
> + *fd_num = got_fds;
> memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int));
> break;
> }
> }
>
> /* Clear out unused file descriptors */
> - while (got_fds < fd_num)
> + while (got_fds < max_fds)
> fds[got_fds++] = -1;
>
> return ret;
> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
> index 83d3e6321..c1c5f35ff 100644
> --- a/lib/librte_vhost/vhost_user.c
> +++ b/lib/librte_vhost/vhost_user.c
> @@ -1509,7 +1509,7 @@ read_vhost_message(int sockfd, struct VhostUserMsg *msg)
> int ret;
>
> ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,
> - msg->fds, VHOST_MEMORY_MAX_NREGIONS);
> + msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);
> if (ret <= 0)
> return ret;
>
> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
> index 62654f736..9a91d496b 100644
> --- a/lib/librte_vhost/vhost_user.h
> +++ b/lib/librte_vhost/vhost_user.h
> @@ -132,6 +132,7 @@ typedef struct VhostUserMsg {
> VhostUserVringArea area;
> } payload;
> int fds[VHOST_MEMORY_MAX_NREGIONS];
> + int fd_num;
> } __attribute((packed)) VhostUserMsg;
>
> #define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
> @@ -155,7 +156,8 @@ int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
> int vhost_user_host_notifier_ctrl(int vid, bool enable);
>
> /* socket.c */
> -int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
> +int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
> + int *fd_num);
> int send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
>
> #endif
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it
2018-10-11 15:59 ` Ilya Maximets
@ 2018-10-12 8:43 ` Maxime Coquelin
2018-10-12 8:45 ` Maxime Coquelin
0 siblings, 1 reply; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-12 8:43 UTC (permalink / raw)
To: Ilya Maximets, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero, dgilbert
Cc: stable
On 10/11/2018 05:59 PM, Ilya Maximets wrote:
> On 11.10.2018 12:24, Maxime Coquelin wrote:
>> As soon as some ancillary data (fds) are received, it is copied
>> without checking its length.
>>
>> This patch adds the number of fds received to the message,
>> which is set in read_vhost_message().
>>
>> This is preliminary work to support sending fds to Qemu.
>>
>> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>> ---
>> lib/librte_vhost/socket.c | 25 ++++++++++++++++++++-----
>> lib/librte_vhost/vhost_user.c | 2 +-
>> lib/librte_vhost/vhost_user.h | 4 +++-
>> 3 files changed, 24 insertions(+), 7 deletions(-)
>>
>> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
>> index d63031747..3b0287a26 100644
>> --- a/lib/librte_vhost/socket.c
>> +++ b/lib/librte_vhost/socket.c
>> @@ -94,18 +94,24 @@ static struct vhost_user vhost_user = {
>> .mutex = PTHREAD_MUTEX_INITIALIZER,
>> };
>>
>> -/* return bytes# of read on success or negative val on failure. */
>> +/*
>> + * return bytes# of read on success or negative val on failure. Update fdnum
>> + * with number of fds read.
>> + */
>> int
>> -read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
>> +read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
>> + int *fd_num)
>> {
>> struct iovec iov;
>> struct msghdr msgh;
>> - size_t fdsize = fd_num * sizeof(int);
>> - char control[CMSG_SPACE(fdsize)];
>> + char control[CMSG_SPACE(max_fds * sizeof(int))];
>> struct cmsghdr *cmsg;
>> int got_fds = 0;
>> + int *tmp_fds;
>> int ret;
>>
>> + *fd_num = 0;
>> +
>> memset(&msgh, 0, sizeof(msgh));
>> iov.iov_base = buf;
>> iov.iov_len = buflen;
>> @@ -131,13 +137,22 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
>> if ((cmsg->cmsg_level == SOL_SOCKET) &&
>> (cmsg->cmsg_type == SCM_RIGHTS)) {
>> got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
>> + if (got_fds > max_fds) {
>
> Hmm. I just noticed that 'msg_controllen' is set to receive
> not more than max_fds descriptors. So, this case should not
> be possible. We will receive MSG_CTRUNC and return before
> the loop.
Maybe it is better to remove check for MSG_CTRUN.
IIUC, if MSG_CTRUNC happens, we may have to close anyway the ones
received.
Do you agree?
>> + RTE_LOG(ERR, VHOST_CONFIG,
>> + "Received msg contains more fds than supported\n");
>> + tmp_fds = (int *)CMSG_DATA(cmsg);
>> + while (got_fds--)
>> + close(tmp_fds[got_fds]);
>> + return -1;
>> + }
>> + *fd_num = got_fds;
>> memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int));
>> break;
>> }
>> }
>>
>> /* Clear out unused file descriptors */
>> - while (got_fds < fd_num)
>> + while (got_fds < max_fds)
>> fds[got_fds++] = -1;
>>
>> return ret;
>> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
>> index 83d3e6321..c1c5f35ff 100644
>> --- a/lib/librte_vhost/vhost_user.c
>> +++ b/lib/librte_vhost/vhost_user.c
>> @@ -1509,7 +1509,7 @@ read_vhost_message(int sockfd, struct VhostUserMsg *msg)
>> int ret;
>>
>> ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,
>> - msg->fds, VHOST_MEMORY_MAX_NREGIONS);
>> + msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);
>> if (ret <= 0)
>> return ret;
>>
>> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
>> index 62654f736..9a91d496b 100644
>> --- a/lib/librte_vhost/vhost_user.h
>> +++ b/lib/librte_vhost/vhost_user.h
>> @@ -132,6 +132,7 @@ typedef struct VhostUserMsg {
>> VhostUserVringArea area;
>> } payload;
>> int fds[VHOST_MEMORY_MAX_NREGIONS];
>> + int fd_num;
>> } __attribute((packed)) VhostUserMsg;
>>
>> #define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
>> @@ -155,7 +156,8 @@ int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
>> int vhost_user_host_notifier_ctrl(int vid, bool enable);
>>
>> /* socket.c */
>> -int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
>> +int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
>> + int *fd_num);
>> int send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
>>
>> #endif
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it
2018-10-12 8:43 ` Maxime Coquelin
@ 2018-10-12 8:45 ` Maxime Coquelin
2018-10-12 8:57 ` Maxime Coquelin
0 siblings, 1 reply; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-12 8:45 UTC (permalink / raw)
To: Ilya Maximets, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero, dgilbert
Cc: stable
On 10/12/2018 10:43 AM, Maxime Coquelin wrote:
>
>
> On 10/11/2018 05:59 PM, Ilya Maximets wrote:
>> On 11.10.2018 12:24, Maxime Coquelin wrote:
>>> As soon as some ancillary data (fds) are received, it is copied
>>> without checking its length.
>>>
>>> This patch adds the number of fds received to the message,
>>> which is set in read_vhost_message().
>>>
>>> This is preliminary work to support sending fds to Qemu.
>>>
>>> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
>>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>>> ---
>>> lib/librte_vhost/socket.c | 25 ++++++++++++++++++++-----
>>> lib/librte_vhost/vhost_user.c | 2 +-
>>> lib/librte_vhost/vhost_user.h | 4 +++-
>>> 3 files changed, 24 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
>>> index d63031747..3b0287a26 100644
>>> --- a/lib/librte_vhost/socket.c
>>> +++ b/lib/librte_vhost/socket.c
>>> @@ -94,18 +94,24 @@ static struct vhost_user vhost_user = {
>>> .mutex = PTHREAD_MUTEX_INITIALIZER,
>>> };
>>> -/* return bytes# of read on success or negative val on failure. */
>>> +/*
>>> + * return bytes# of read on success or negative val on failure.
>>> Update fdnum
>>> + * with number of fds read.
>>> + */
>>> int
>>> -read_fd_message(int sockfd, char *buf, int buflen, int *fds, int
>>> fd_num)
>>> +read_fd_message(int sockfd, char *buf, int buflen, int *fds, int
>>> max_fds,
>>> + int *fd_num)
>>> {
>>> struct iovec iov;
>>> struct msghdr msgh;
>>> - size_t fdsize = fd_num * sizeof(int);
>>> - char control[CMSG_SPACE(fdsize)];
>>> + char control[CMSG_SPACE(max_fds * sizeof(int))];
>>> struct cmsghdr *cmsg;
>>> int got_fds = 0;
>>> + int *tmp_fds;
>>> int ret;
>>> + *fd_num = 0;
>>> +
>>> memset(&msgh, 0, sizeof(msgh));
>>> iov.iov_base = buf;
>>> iov.iov_len = buflen;
>>> @@ -131,13 +137,22 @@ read_fd_message(int sockfd, char *buf, int
>>> buflen, int *fds, int fd_num)
>>> if ((cmsg->cmsg_level == SOL_SOCKET) &&
>>> (cmsg->cmsg_type == SCM_RIGHTS)) {
>>> got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
>>> + if (got_fds > max_fds) {
>>
>> Hmm. I just noticed that 'msg_controllen' is set to receive
>> not more than max_fds descriptors. So, this case should not
>> be possible. We will receive MSG_CTRUNC and return before
>> the loop.
>
> Maybe it is better to remove check for MSG_CTRUNC.
s/remove/rework/
> IIUC, if MSG_CTRUNC happens, we may have to close anyway the ones
> received.
>
> Do you agree? >>> + RTE_LOG(ERR, VHOST_CONFIG,
>>> + "Received msg contains more fds than supported\n");
>>> + tmp_fds = (int *)CMSG_DATA(cmsg);
>>> + while (got_fds--)
>>> + close(tmp_fds[got_fds]);
>>> + return -1;
>>> + }
>>> + *fd_num = got_fds;
>>> memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int));
>>> break;
>>> }
>>> }
>>> /* Clear out unused file descriptors */
>>> - while (got_fds < fd_num)
>>> + while (got_fds < max_fds)
>>> fds[got_fds++] = -1;
>>> return ret;
>>> diff --git a/lib/librte_vhost/vhost_user.c
>>> b/lib/librte_vhost/vhost_user.c
>>> index 83d3e6321..c1c5f35ff 100644
>>> --- a/lib/librte_vhost/vhost_user.c
>>> +++ b/lib/librte_vhost/vhost_user.c
>>> @@ -1509,7 +1509,7 @@ read_vhost_message(int sockfd, struct
>>> VhostUserMsg *msg)
>>> int ret;
>>> ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,
>>> - msg->fds, VHOST_MEMORY_MAX_NREGIONS);
>>> + msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);
>>> if (ret <= 0)
>>> return ret;
>>> diff --git a/lib/librte_vhost/vhost_user.h
>>> b/lib/librte_vhost/vhost_user.h
>>> index 62654f736..9a91d496b 100644
>>> --- a/lib/librte_vhost/vhost_user.h
>>> +++ b/lib/librte_vhost/vhost_user.h
>>> @@ -132,6 +132,7 @@ typedef struct VhostUserMsg {
>>> VhostUserVringArea area;
>>> } payload;
>>> int fds[VHOST_MEMORY_MAX_NREGIONS];
>>> + int fd_num;
>>> } __attribute((packed)) VhostUserMsg;
>>> #define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
>>> @@ -155,7 +156,8 @@ int vhost_user_iotlb_miss(struct virtio_net *dev,
>>> uint64_t iova, uint8_t perm);
>>> int vhost_user_host_notifier_ctrl(int vid, bool enable);
>>> /* socket.c */
>>> -int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int
>>> fd_num);
>>> +int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int
>>> max_fds,
>>> + int *fd_num);
>>> int send_fd_message(int sockfd, char *buf, int buflen, int *fds,
>>> int fd_num);
>>> #endif
>>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it
2018-10-12 8:45 ` Maxime Coquelin
@ 2018-10-12 8:57 ` Maxime Coquelin
2018-10-12 9:53 ` Ilya Maximets
0 siblings, 1 reply; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-12 8:57 UTC (permalink / raw)
To: Ilya Maximets, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero, dgilbert
Cc: stable
On 10/12/2018 10:45 AM, Maxime Coquelin wrote:
>
>
> On 10/12/2018 10:43 AM, Maxime Coquelin wrote:
>>
>>
>> On 10/11/2018 05:59 PM, Ilya Maximets wrote:
>>> On 11.10.2018 12:24, Maxime Coquelin wrote:
>>>> As soon as some ancillary data (fds) are received, it is copied
>>>> without checking its length.
>>>>
>>>> This patch adds the number of fds received to the message,
>>>> which is set in read_vhost_message().
>>>>
>>>> This is preliminary work to support sending fds to Qemu.
>>>>
>>>> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
>>>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>>>> ---
>>>> lib/librte_vhost/socket.c | 25 ++++++++++++++++++++-----
>>>> lib/librte_vhost/vhost_user.c | 2 +-
>>>> lib/librte_vhost/vhost_user.h | 4 +++-
>>>> 3 files changed, 24 insertions(+), 7 deletions(-)
>>>>
>>>> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
>>>> index d63031747..3b0287a26 100644
>>>> --- a/lib/librte_vhost/socket.c
>>>> +++ b/lib/librte_vhost/socket.c
>>>> @@ -94,18 +94,24 @@ static struct vhost_user vhost_user = {
>>>> .mutex = PTHREAD_MUTEX_INITIALIZER,
>>>> };
>>>> -/* return bytes# of read on success or negative val on failure. */
>>>> +/*
>>>> + * return bytes# of read on success or negative val on failure.
>>>> Update fdnum
>>>> + * with number of fds read.
>>>> + */
>>>> int
>>>> -read_fd_message(int sockfd, char *buf, int buflen, int *fds, int
>>>> fd_num)
>>>> +read_fd_message(int sockfd, char *buf, int buflen, int *fds, int
>>>> max_fds,
>>>> + int *fd_num)
>>>> {
>>>> struct iovec iov;
>>>> struct msghdr msgh;
>>>> - size_t fdsize = fd_num * sizeof(int);
>>>> - char control[CMSG_SPACE(fdsize)];
>>>> + char control[CMSG_SPACE(max_fds * sizeof(int))];
>>>> struct cmsghdr *cmsg;
>>>> int got_fds = 0;
>>>> + int *tmp_fds;
>>>> int ret;
>>>> + *fd_num = 0;
>>>> +
>>>> memset(&msgh, 0, sizeof(msgh));
>>>> iov.iov_base = buf;
>>>> iov.iov_len = buflen;
>>>> @@ -131,13 +137,22 @@ read_fd_message(int sockfd, char *buf, int
>>>> buflen, int *fds, int fd_num)
>>>> if ((cmsg->cmsg_level == SOL_SOCKET) &&
>>>> (cmsg->cmsg_type == SCM_RIGHTS)) {
>>>> got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
>>>> + if (got_fds > max_fds) {
>>>
>>> Hmm. I just noticed that 'msg_controllen' is set to receive
>>> not more than max_fds descriptors. So, this case should not
>>> be possible. We will receive MSG_CTRUNC and return before
>>> the loop.
>>
>> Maybe it is better to remove check for MSG_CTRUNC.
> s/remove/rework/
>
>> IIUC, if MSG_CTRUNC happens, we may have to close anyway the ones
>> received.
>>
>> Do you agree?
So it seems that other use of MSG_CTRUNC in DPDK and QEMU does care
to close the ones that would have been received and just return an
error.
I propose to do the same for now, an remove the got_fds > max_fds part.
>>> + RTE_LOG(ERR, VHOST_CONFIG,
>>>> + "Received msg contains more fds than
>>>> supported\n");
>>>> + tmp_fds = (int *)CMSG_DATA(cmsg);
>>>> + while (got_fds--)
>>>> + close(tmp_fds[got_fds]);
>>>> + return -1;
>>>> + }
>>>> + *fd_num = got_fds;
>>>> memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int));
>>>> break;
>>>> }
>>>> }
>>>> /* Clear out unused file descriptors */
>>>> - while (got_fds < fd_num)
>>>> + while (got_fds < max_fds)
>>>> fds[got_fds++] = -1;
>>>> return ret;
>>>> diff --git a/lib/librte_vhost/vhost_user.c
>>>> b/lib/librte_vhost/vhost_user.c
>>>> index 83d3e6321..c1c5f35ff 100644
>>>> --- a/lib/librte_vhost/vhost_user.c
>>>> +++ b/lib/librte_vhost/vhost_user.c
>>>> @@ -1509,7 +1509,7 @@ read_vhost_message(int sockfd, struct
>>>> VhostUserMsg *msg)
>>>> int ret;
>>>> ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,
>>>> - msg->fds, VHOST_MEMORY_MAX_NREGIONS);
>>>> + msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);
>>>> if (ret <= 0)
>>>> return ret;
>>>> diff --git a/lib/librte_vhost/vhost_user.h
>>>> b/lib/librte_vhost/vhost_user.h
>>>> index 62654f736..9a91d496b 100644
>>>> --- a/lib/librte_vhost/vhost_user.h
>>>> +++ b/lib/librte_vhost/vhost_user.h
>>>> @@ -132,6 +132,7 @@ typedef struct VhostUserMsg {
>>>> VhostUserVringArea area;
>>>> } payload;
>>>> int fds[VHOST_MEMORY_MAX_NREGIONS];
>>>> + int fd_num;
>>>> } __attribute((packed)) VhostUserMsg;
>>>> #define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
>>>> @@ -155,7 +156,8 @@ int vhost_user_iotlb_miss(struct virtio_net
>>>> *dev, uint64_t iova, uint8_t perm);
>>>> int vhost_user_host_notifier_ctrl(int vid, bool enable);
>>>> /* socket.c */
>>>> -int read_fd_message(int sockfd, char *buf, int buflen, int *fds,
>>>> int fd_num);
>>>> +int read_fd_message(int sockfd, char *buf, int buflen, int *fds,
>>>> int max_fds,
>>>> + int *fd_num);
>>>> int send_fd_message(int sockfd, char *buf, int buflen, int *fds,
>>>> int fd_num);
>>>> #endif
>>>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it
2018-10-12 8:57 ` Maxime Coquelin
@ 2018-10-12 9:53 ` Ilya Maximets
2018-10-12 9:52 ` Maxime Coquelin
0 siblings, 1 reply; 30+ messages in thread
From: Ilya Maximets @ 2018-10-12 9:53 UTC (permalink / raw)
To: Maxime Coquelin, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero, dgilbert
Cc: stable
On 12.10.2018 11:57, Maxime Coquelin wrote:
>
>
> On 10/12/2018 10:45 AM, Maxime Coquelin wrote:
>>
>>
>> On 10/12/2018 10:43 AM, Maxime Coquelin wrote:
>>>
>>>
>>> On 10/11/2018 05:59 PM, Ilya Maximets wrote:
>>>> On 11.10.2018 12:24, Maxime Coquelin wrote:
>>>>> As soon as some ancillary data (fds) are received, it is copied
>>>>> without checking its length.
>>>>>
>>>>> This patch adds the number of fds received to the message,
>>>>> which is set in read_vhost_message().
>>>>>
>>>>> This is preliminary work to support sending fds to Qemu.
>>>>>
>>>>> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
>>>>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>>>>> ---
>>>>> lib/librte_vhost/socket.c | 25 ++++++++++++++++++++-----
>>>>> lib/librte_vhost/vhost_user.c | 2 +-
>>>>> lib/librte_vhost/vhost_user.h | 4 +++-
>>>>> 3 files changed, 24 insertions(+), 7 deletions(-)
>>>>>
>>>>> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
>>>>> index d63031747..3b0287a26 100644
>>>>> --- a/lib/librte_vhost/socket.c
>>>>> +++ b/lib/librte_vhost/socket.c
>>>>> @@ -94,18 +94,24 @@ static struct vhost_user vhost_user = {
>>>>> .mutex = PTHREAD_MUTEX_INITIALIZER,
>>>>> };
>>>>> -/* return bytes# of read on success or negative val on failure. */
>>>>> +/*
>>>>> + * return bytes# of read on success or negative val on failure. Update fdnum
>>>>> + * with number of fds read.
>>>>> + */
>>>>> int
>>>>> -read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
>>>>> +read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
>>>>> + int *fd_num)
>>>>> {
>>>>> struct iovec iov;
>>>>> struct msghdr msgh;
>>>>> - size_t fdsize = fd_num * sizeof(int);
>>>>> - char control[CMSG_SPACE(fdsize)];
>>>>> + char control[CMSG_SPACE(max_fds * sizeof(int))];
>>>>> struct cmsghdr *cmsg;
>>>>> int got_fds = 0;
>>>>> + int *tmp_fds;
>>>>> int ret;
>>>>> + *fd_num = 0;
>>>>> +
>>>>> memset(&msgh, 0, sizeof(msgh));
>>>>> iov.iov_base = buf;
>>>>> iov.iov_len = buflen;
>>>>> @@ -131,13 +137,22 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
>>>>> if ((cmsg->cmsg_level == SOL_SOCKET) &&
>>>>> (cmsg->cmsg_type == SCM_RIGHTS)) {
>>>>> got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
>>>>> + if (got_fds > max_fds) {
>>>>
>>>> Hmm. I just noticed that 'msg_controllen' is set to receive
>>>> not more than max_fds descriptors. So, this case should not
>>>> be possible. We will receive MSG_CTRUNC and return before
>>>> the loop.
>>>
>>> Maybe it is better to remove check for MSG_CTRUNC.
>> s/remove/rework/
>>
>>> IIUC, if MSG_CTRUNC happens, we may have to close anyway the ones
>>> received.
>>>
>>> Do you agree?
>
> So it seems that other use of MSG_CTRUNC in DPDK and QEMU does care
> to close the ones that would have been received and just return an
> error.
Did you mean 'does not care'?
'read_msg()' in lib/librte_eal/common/eal_common_proc.c just returns -1
and 'slave_read()' in hw/virtio/vhost-user.c does not close fds, because
'fdsize' is not set at the time of checking the flag.
>
> I propose to do the same for now, an remove the got_fds > max_fds part.
>
>>>> + RTE_LOG(ERR, VHOST_CONFIG,
>>>>> + "Received msg contains more fds than supported\n");
>>>>> + tmp_fds = (int *)CMSG_DATA(cmsg);
>>>>> + while (got_fds--)
>>>>> + close(tmp_fds[got_fds]);
>>>>> + return -1;
>>>>> + }
>>>>> + *fd_num = got_fds;
>>>>> memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int));
>>>>> break;
>>>>> }
>>>>> }
>>>>> /* Clear out unused file descriptors */
>>>>> - while (got_fds < fd_num)
>>>>> + while (got_fds < max_fds)
>>>>> fds[got_fds++] = -1;
>>>>> return ret;
>>>>> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
>>>>> index 83d3e6321..c1c5f35ff 100644
>>>>> --- a/lib/librte_vhost/vhost_user.c
>>>>> +++ b/lib/librte_vhost/vhost_user.c
>>>>> @@ -1509,7 +1509,7 @@ read_vhost_message(int sockfd, struct VhostUserMsg *msg)
>>>>> int ret;
>>>>> ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,
>>>>> - msg->fds, VHOST_MEMORY_MAX_NREGIONS);
>>>>> + msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);
>>>>> if (ret <= 0)
>>>>> return ret;
>>>>> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
>>>>> index 62654f736..9a91d496b 100644
>>>>> --- a/lib/librte_vhost/vhost_user.h
>>>>> +++ b/lib/librte_vhost/vhost_user.h
>>>>> @@ -132,6 +132,7 @@ typedef struct VhostUserMsg {
>>>>> VhostUserVringArea area;
>>>>> } payload;
>>>>> int fds[VHOST_MEMORY_MAX_NREGIONS];
>>>>> + int fd_num;
>>>>> } __attribute((packed)) VhostUserMsg;
>>>>> #define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
>>>>> @@ -155,7 +156,8 @@ int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
>>>>> int vhost_user_host_notifier_ctrl(int vid, bool enable);
>>>>> /* socket.c */
>>>>> -int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
>>>>> +int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
>>>>> + int *fd_num);
>>>>> int send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
>>>>> #endif
>>>>>
>
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it
2018-10-12 9:53 ` Ilya Maximets
@ 2018-10-12 9:52 ` Maxime Coquelin
2018-10-12 10:04 ` Ilya Maximets
0 siblings, 1 reply; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-12 9:52 UTC (permalink / raw)
To: Ilya Maximets, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero, dgilbert
Cc: stable
On 10/12/2018 11:53 AM, Ilya Maximets wrote:
> On 12.10.2018 11:57, Maxime Coquelin wrote:
>>
>>
>> On 10/12/2018 10:45 AM, Maxime Coquelin wrote:
>>>
>>>
>>> On 10/12/2018 10:43 AM, Maxime Coquelin wrote:
>>>>
>>>>
>>>> On 10/11/2018 05:59 PM, Ilya Maximets wrote:
>>>>> On 11.10.2018 12:24, Maxime Coquelin wrote:
>>>>>> As soon as some ancillary data (fds) are received, it is copied
>>>>>> without checking its length.
>>>>>>
>>>>>> This patch adds the number of fds received to the message,
>>>>>> which is set in read_vhost_message().
>>>>>>
>>>>>> This is preliminary work to support sending fds to Qemu.
>>>>>>
>>>>>> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
>>>>>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>>>>>> ---
>>>>>> lib/librte_vhost/socket.c | 25 ++++++++++++++++++++-----
>>>>>> lib/librte_vhost/vhost_user.c | 2 +-
>>>>>> lib/librte_vhost/vhost_user.h | 4 +++-
>>>>>> 3 files changed, 24 insertions(+), 7 deletions(-)
>>>>>>
>>>>>> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
>>>>>> index d63031747..3b0287a26 100644
>>>>>> --- a/lib/librte_vhost/socket.c
>>>>>> +++ b/lib/librte_vhost/socket.c
>>>>>> @@ -94,18 +94,24 @@ static struct vhost_user vhost_user = {
>>>>>> .mutex = PTHREAD_MUTEX_INITIALIZER,
>>>>>> };
>>>>>> -/* return bytes# of read on success or negative val on failure. */
>>>>>> +/*
>>>>>> + * return bytes# of read on success or negative val on failure. Update fdnum
>>>>>> + * with number of fds read.
>>>>>> + */
>>>>>> int
>>>>>> -read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
>>>>>> +read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
>>>>>> + int *fd_num)
>>>>>> {
>>>>>> struct iovec iov;
>>>>>> struct msghdr msgh;
>>>>>> - size_t fdsize = fd_num * sizeof(int);
>>>>>> - char control[CMSG_SPACE(fdsize)];
>>>>>> + char control[CMSG_SPACE(max_fds * sizeof(int))];
>>>>>> struct cmsghdr *cmsg;
>>>>>> int got_fds = 0;
>>>>>> + int *tmp_fds;
>>>>>> int ret;
>>>>>> + *fd_num = 0;
>>>>>> +
>>>>>> memset(&msgh, 0, sizeof(msgh));
>>>>>> iov.iov_base = buf;
>>>>>> iov.iov_len = buflen;
>>>>>> @@ -131,13 +137,22 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
>>>>>> if ((cmsg->cmsg_level == SOL_SOCKET) &&
>>>>>> (cmsg->cmsg_type == SCM_RIGHTS)) {
>>>>>> got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
>>>>>> + if (got_fds > max_fds) {
>>>>>
>>>>> Hmm. I just noticed that 'msg_controllen' is set to receive
>>>>> not more than max_fds descriptors. So, this case should not
>>>>> be possible. We will receive MSG_CTRUNC and return before
>>>>> the loop.
>>>>
>>>> Maybe it is better to remove check for MSG_CTRUNC.
>>> s/remove/rework/
>>>
>>>> IIUC, if MSG_CTRUNC happens, we may have to close anyway the ones
>>>> received.
>>>>
>>>> Do you agree?
>>
>> So it seems that other use of MSG_CTRUNC in DPDK and QEMU does care
>> to close the ones that would have been received and just return an
>> error.
>
> Did you mean 'does not care'?
Yes, I meant "does not care", sorry.
> 'read_msg()' in lib/librte_eal/common/eal_common_proc.c just returns -1
> and 'slave_read()' in hw/virtio/vhost-user.c does not close fds, because
> 'fdsize' is not set at the time of checking the flag.
>
>>
>> I propose to do the same for now, an remove the got_fds > max_fds part.
>>
>>>>> + RTE_LOG(ERR, VHOST_CONFIG,
>>>>>> + "Received msg contains more fds than supported\n");
>>>>>> + tmp_fds = (int *)CMSG_DATA(cmsg);
>>>>>> + while (got_fds--)
>>>>>> + close(tmp_fds[got_fds]);
>>>>>> + return -1;
>>>>>> + }
>>>>>> + *fd_num = got_fds;
>>>>>> memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int));
>>>>>> break;
>>>>>> }
>>>>>> }
>>>>>> /* Clear out unused file descriptors */
>>>>>> - while (got_fds < fd_num)
>>>>>> + while (got_fds < max_fds)
>>>>>> fds[got_fds++] = -1;
>>>>>> return ret;
>>>>>> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
>>>>>> index 83d3e6321..c1c5f35ff 100644
>>>>>> --- a/lib/librte_vhost/vhost_user.c
>>>>>> +++ b/lib/librte_vhost/vhost_user.c
>>>>>> @@ -1509,7 +1509,7 @@ read_vhost_message(int sockfd, struct VhostUserMsg *msg)
>>>>>> int ret;
>>>>>> ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,
>>>>>> - msg->fds, VHOST_MEMORY_MAX_NREGIONS);
>>>>>> + msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);
>>>>>> if (ret <= 0)
>>>>>> return ret;
>>>>>> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
>>>>>> index 62654f736..9a91d496b 100644
>>>>>> --- a/lib/librte_vhost/vhost_user.h
>>>>>> +++ b/lib/librte_vhost/vhost_user.h
>>>>>> @@ -132,6 +132,7 @@ typedef struct VhostUserMsg {
>>>>>> VhostUserVringArea area;
>>>>>> } payload;
>>>>>> int fds[VHOST_MEMORY_MAX_NREGIONS];
>>>>>> + int fd_num;
>>>>>> } __attribute((packed)) VhostUserMsg;
>>>>>> #define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
>>>>>> @@ -155,7 +156,8 @@ int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
>>>>>> int vhost_user_host_notifier_ctrl(int vid, bool enable);
>>>>>> /* socket.c */
>>>>>> -int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
>>>>>> +int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
>>>>>> + int *fd_num);
>>>>>> int send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
>>>>>> #endif
>>>>>>
>>
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it
2018-10-12 9:52 ` Maxime Coquelin
@ 2018-10-12 10:04 ` Ilya Maximets
0 siblings, 0 replies; 30+ messages in thread
From: Ilya Maximets @ 2018-10-12 10:04 UTC (permalink / raw)
To: Maxime Coquelin, dev, tiwei.bie, zhihong.wang, jfreimann,
nicknickolaev, bruce.richardson, alejandro.lucero, dgilbert
Cc: stable
On 12.10.2018 12:52, Maxime Coquelin wrote:
>
>
> On 10/12/2018 11:53 AM, Ilya Maximets wrote:
>> On 12.10.2018 11:57, Maxime Coquelin wrote:
>>>
>>>
>>> On 10/12/2018 10:45 AM, Maxime Coquelin wrote:
>>>>
>>>>
>>>> On 10/12/2018 10:43 AM, Maxime Coquelin wrote:
>>>>>
>>>>>
>>>>> On 10/11/2018 05:59 PM, Ilya Maximets wrote:
>>>>>> On 11.10.2018 12:24, Maxime Coquelin wrote:
>>>>>>> As soon as some ancillary data (fds) are received, it is copied
>>>>>>> without checking its length.
>>>>>>>
>>>>>>> This patch adds the number of fds received to the message,
>>>>>>> which is set in read_vhost_message().
>>>>>>>
>>>>>>> This is preliminary work to support sending fds to Qemu.
>>>>>>>
>>>>>>> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
>>>>>>> Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>>>>>>> ---
>>>>>>> lib/librte_vhost/socket.c | 25 ++++++++++++++++++++-----
>>>>>>> lib/librte_vhost/vhost_user.c | 2 +-
>>>>>>> lib/librte_vhost/vhost_user.h | 4 +++-
>>>>>>> 3 files changed, 24 insertions(+), 7 deletions(-)
>>>>>>>
>>>>>>> diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
>>>>>>> index d63031747..3b0287a26 100644
>>>>>>> --- a/lib/librte_vhost/socket.c
>>>>>>> +++ b/lib/librte_vhost/socket.c
>>>>>>> @@ -94,18 +94,24 @@ static struct vhost_user vhost_user = {
>>>>>>> .mutex = PTHREAD_MUTEX_INITIALIZER,
>>>>>>> };
>>>>>>> -/* return bytes# of read on success or negative val on failure. */
>>>>>>> +/*
>>>>>>> + * return bytes# of read on success or negative val on failure. Update fdnum
>>>>>>> + * with number of fds read.
>>>>>>> + */
>>>>>>> int
>>>>>>> -read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
>>>>>>> +read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
>>>>>>> + int *fd_num)
>>>>>>> {
>>>>>>> struct iovec iov;
>>>>>>> struct msghdr msgh;
>>>>>>> - size_t fdsize = fd_num * sizeof(int);
>>>>>>> - char control[CMSG_SPACE(fdsize)];
>>>>>>> + char control[CMSG_SPACE(max_fds * sizeof(int))];
>>>>>>> struct cmsghdr *cmsg;
>>>>>>> int got_fds = 0;
>>>>>>> + int *tmp_fds;
>>>>>>> int ret;
>>>>>>> + *fd_num = 0;
>>>>>>> +
>>>>>>> memset(&msgh, 0, sizeof(msgh));
>>>>>>> iov.iov_base = buf;
>>>>>>> iov.iov_len = buflen;
>>>>>>> @@ -131,13 +137,22 @@ read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num)
>>>>>>> if ((cmsg->cmsg_level == SOL_SOCKET) &&
>>>>>>> (cmsg->cmsg_type == SCM_RIGHTS)) {
>>>>>>> got_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
>>>>>>> + if (got_fds > max_fds) {
>>>>>>
>>>>>> Hmm. I just noticed that 'msg_controllen' is set to receive
>>>>>> not more than max_fds descriptors. So, this case should not
>>>>>> be possible. We will receive MSG_CTRUNC and return before
>>>>>> the loop.
>>>>>
>>>>> Maybe it is better to remove check for MSG_CTRUNC.
>>>> s/remove/rework/
>>>>
>>>>> IIUC, if MSG_CTRUNC happens, we may have to close anyway the ones
>>>>> received.
>>>>>
>>>>> Do you agree?
>>>
>>> So it seems that other use of MSG_CTRUNC in DPDK and QEMU does care
>>> to close the ones that would have been received and just return an
>>> error.
>>
>> Did you mean 'does not care'?
>
> Yes, I meant "does not care", sorry.
ok.
>
>> 'read_msg()' in lib/librte_eal/common/eal_common_proc.c just returns -1
>> and 'slave_read()' in hw/virtio/vhost-user.c does not close fds, because
>> 'fdsize' is not set at the time of checking the flag.
>>
>>>
>>> I propose to do the same for now, an remove the got_fds > max_fds part.
Agree.
>>>
>>>>>> + RTE_LOG(ERR, VHOST_CONFIG,
>>>>>>> + "Received msg contains more fds than supported\n");
>>>>>>> + tmp_fds = (int *)CMSG_DATA(cmsg);
>>>>>>> + while (got_fds--)
>>>>>>> + close(tmp_fds[got_fds]);
>>>>>>> + return -1;
>>>>>>> + }
>>>>>>> + *fd_num = got_fds;
>>>>>>> memcpy(fds, CMSG_DATA(cmsg), got_fds * sizeof(int));
>>>>>>> break;
>>>>>>> }
>>>>>>> }
>>>>>>> /* Clear out unused file descriptors */
>>>>>>> - while (got_fds < fd_num)
>>>>>>> + while (got_fds < max_fds)
>>>>>>> fds[got_fds++] = -1;
>>>>>>> return ret;
>>>>>>> diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
>>>>>>> index 83d3e6321..c1c5f35ff 100644
>>>>>>> --- a/lib/librte_vhost/vhost_user.c
>>>>>>> +++ b/lib/librte_vhost/vhost_user.c
>>>>>>> @@ -1509,7 +1509,7 @@ read_vhost_message(int sockfd, struct VhostUserMsg *msg)
>>>>>>> int ret;
>>>>>>> ret = read_fd_message(sockfd, (char *)msg, VHOST_USER_HDR_SIZE,
>>>>>>> - msg->fds, VHOST_MEMORY_MAX_NREGIONS);
>>>>>>> + msg->fds, VHOST_MEMORY_MAX_NREGIONS, &msg->fd_num);
>>>>>>> if (ret <= 0)
>>>>>>> return ret;
>>>>>>> diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
>>>>>>> index 62654f736..9a91d496b 100644
>>>>>>> --- a/lib/librte_vhost/vhost_user.h
>>>>>>> +++ b/lib/librte_vhost/vhost_user.h
>>>>>>> @@ -132,6 +132,7 @@ typedef struct VhostUserMsg {
>>>>>>> VhostUserVringArea area;
>>>>>>> } payload;
>>>>>>> int fds[VHOST_MEMORY_MAX_NREGIONS];
>>>>>>> + int fd_num;
>>>>>>> } __attribute((packed)) VhostUserMsg;
>>>>>>> #define VHOST_USER_HDR_SIZE offsetof(VhostUserMsg, payload.u64)
>>>>>>> @@ -155,7 +156,8 @@ int vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm);
>>>>>>> int vhost_user_host_notifier_ctrl(int vid, bool enable);
>>>>>>> /* socket.c */
>>>>>>> -int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
>>>>>>> +int read_fd_message(int sockfd, char *buf, int buflen, int *fds, int max_fds,
>>>>>>> + int *fd_num);
>>>>>>> int send_fd_message(int sockfd, char *buf, int buflen, int *fds, int fd_num);
>>>>>>> #endif
>>>>>>>
>>>
>>>
>
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 08/19] vhost: pass socket fd to message handling callbacks
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (6 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 07/19] vhost: add number of fds to vhost-user messages and use it Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 09/19] vhost: enable fds passing when sending vhost-user messages Maxime Coquelin
` (10 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
This is not used for now, but will be needed for the
special handling of VHOST_USER_SET_MEM_TABLE message
once postcopy will be supported.
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost_user.c | 71 +++++++++++++++++++++++------------
1 file changed, 47 insertions(+), 24 deletions(-)
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index c1c5f35ff..bce2395a3 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -128,14 +128,16 @@ vhost_backend_cleanup(struct virtio_net *dev)
*/
static int
vhost_user_set_owner(struct virtio_net **pdev __rte_unused,
- struct VhostUserMsg *msg __rte_unused)
+ struct VhostUserMsg *msg __rte_unused,
+ int main_fd __rte_unused)
{
return VH_RESULT_OK;
}
static int
vhost_user_reset_owner(struct virtio_net **pdev,
- struct VhostUserMsg *msg __rte_unused)
+ struct VhostUserMsg *msg __rte_unused,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
vhost_destroy_device_notify(dev);
@@ -149,7 +151,8 @@ vhost_user_reset_owner(struct virtio_net **pdev,
* The features that we support are requested.
*/
static int
-vhost_user_get_features(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_get_features(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
uint64_t features = 0;
@@ -166,7 +169,8 @@ vhost_user_get_features(struct virtio_net **pdev, struct VhostUserMsg *msg)
* The queue number that we support are requested.
*/
static int
-vhost_user_get_queue_num(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_get_queue_num(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
uint32_t queue_num = 0;
@@ -183,7 +187,8 @@ vhost_user_get_queue_num(struct virtio_net **pdev, struct VhostUserMsg *msg)
* We receive the negotiated features supported by us and the virtio device.
*/
static int
-vhost_user_set_features(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_set_features(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
uint64_t features = msg->payload.u64;
@@ -265,7 +270,8 @@ vhost_user_set_features(struct virtio_net **pdev, struct VhostUserMsg *msg)
*/
static int
vhost_user_set_vring_num(struct virtio_net **pdev,
- struct VhostUserMsg *msg)
+ struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
struct vhost_virtqueue *vq = dev->virtqueue[msg->payload.state.index];
@@ -627,7 +633,8 @@ translate_ring_addresses(struct virtio_net *dev, int vq_index)
* This function then converts these to our address space.
*/
static int
-vhost_user_set_vring_addr(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_set_vring_addr(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
struct vhost_virtqueue *vq;
@@ -664,7 +671,8 @@ vhost_user_set_vring_addr(struct virtio_net **pdev, struct VhostUserMsg *msg)
*/
static int
vhost_user_set_vring_base(struct virtio_net **pdev,
- struct VhostUserMsg *msg)
+ struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
dev->virtqueue[msg->payload.state.index]->last_used_idx =
@@ -797,7 +805,8 @@ vhost_memory_changed(struct VhostUserMemory *new,
}
static int
-vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
struct VhostUserMemory memory = msg->payload.memory;
@@ -1013,7 +1022,8 @@ virtio_is_ready(struct virtio_net *dev)
}
static int
-vhost_user_set_vring_call(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_set_vring_call(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
struct vhost_vring_file file;
@@ -1037,7 +1047,8 @@ vhost_user_set_vring_call(struct virtio_net **pdev, struct VhostUserMsg *msg)
}
static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused,
- struct VhostUserMsg *msg)
+ struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
if (!(msg->payload.u64 & VHOST_USER_VRING_NOFD_MASK))
close(msg->fds[0]);
@@ -1047,7 +1058,8 @@ static int vhost_user_set_vring_err(struct virtio_net **pdev __rte_unused,
}
static int
-vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_set_vring_kick(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
struct vhost_vring_file file;
@@ -1106,7 +1118,8 @@ free_zmbufs(struct vhost_virtqueue *vq)
*/
static int
vhost_user_get_vring_base(struct virtio_net **pdev,
- struct VhostUserMsg *msg)
+ struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
struct vhost_virtqueue *vq = dev->virtqueue[msg->payload.state.index];
@@ -1162,7 +1175,8 @@ vhost_user_get_vring_base(struct virtio_net **pdev,
*/
static int
vhost_user_set_vring_enable(struct virtio_net **pdev,
- struct VhostUserMsg *msg)
+ struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
int enable = (int)msg->payload.state.num;
@@ -1190,7 +1204,8 @@ vhost_user_set_vring_enable(struct virtio_net **pdev,
static int
vhost_user_get_protocol_features(struct virtio_net **pdev,
- struct VhostUserMsg *msg)
+ struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
uint64_t features, protocol_features;
@@ -1215,7 +1230,8 @@ vhost_user_get_protocol_features(struct virtio_net **pdev,
static int
vhost_user_set_protocol_features(struct virtio_net **pdev,
- struct VhostUserMsg *msg)
+ struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
uint64_t protocol_features = msg->payload.u64;
@@ -1232,7 +1248,8 @@ vhost_user_set_protocol_features(struct virtio_net **pdev,
}
static int
-vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
int fd = msg->fds[0];
@@ -1298,7 +1315,8 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg)
}
static int vhost_user_set_log_fd(struct virtio_net **pdev __rte_unused,
- struct VhostUserMsg *msg)
+ struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
close(msg->fds[0]);
RTE_LOG(INFO, VHOST_CONFIG, "not implemented.\n");
@@ -1315,7 +1333,8 @@ static int vhost_user_set_log_fd(struct virtio_net **pdev __rte_unused,
* a flag 'broadcast_rarp' to let rte_vhost_dequeue_burst() inject it.
*/
static int
-vhost_user_send_rarp(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_send_rarp(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
uint8_t *mac = (uint8_t *)&msg->payload.u64;
@@ -1345,7 +1364,8 @@ vhost_user_send_rarp(struct virtio_net **pdev, struct VhostUserMsg *msg)
}
static int
-vhost_user_net_set_mtu(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_net_set_mtu(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
if (msg->payload.u64 < VIRTIO_MIN_MTU ||
@@ -1362,7 +1382,8 @@ vhost_user_net_set_mtu(struct virtio_net **pdev, struct VhostUserMsg *msg)
}
static int
-vhost_user_set_req_fd(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_set_req_fd(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
int fd = msg->fds[0];
@@ -1429,7 +1450,8 @@ is_vring_iotlb_invalidate(struct vhost_virtqueue *vq,
}
static int
-vhost_user_iotlb_msg(struct virtio_net **pdev, struct VhostUserMsg *msg)
+vhost_user_iotlb_msg(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
struct vhost_iotlb_msg *imsg = &msg->payload.iotlb;
@@ -1474,7 +1496,8 @@ vhost_user_iotlb_msg(struct virtio_net **pdev, struct VhostUserMsg *msg)
}
typedef int (*vhost_message_handler_t)(struct virtio_net **pdev,
- struct VhostUserMsg *msg);
+ struct VhostUserMsg *msg,
+ int main_fd);
static vhost_message_handler_t vhost_message_handlers[VHOST_USER_MAX] = {
[VHOST_USER_NONE] = NULL,
[VHOST_USER_GET_FEATURES] = vhost_user_get_features,
@@ -1749,7 +1772,7 @@ vhost_user_msg_handler(int vid, int fd)
if (request > VHOST_USER_NONE && request < VHOST_USER_MAX) {
if (!vhost_message_handlers[request])
goto skip_to_post_handle;
- ret = vhost_message_handlers[request](&dev, &msg);
+ ret = vhost_message_handlers[request](&dev, &msg, fd);
switch (ret) {
case VH_RESULT_ERR:
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 09/19] vhost: enable fds passing when sending vhost-user messages
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (7 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 08/19] vhost: pass socket fd to message handling callbacks Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 10/19] vhost: add config flag for postcopy feature Maxime Coquelin
` (9 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Passing userfault fds to Qemu will be required for postcopy
live-migration feature.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost_crypto.c | 1 +
lib/librte_vhost/vhost_user.c | 27 +++++++++++++++------------
2 files changed, 16 insertions(+), 12 deletions(-)
diff --git a/lib/librte_vhost/vhost_crypto.c b/lib/librte_vhost/vhost_crypto.c
index e534e1187..efdedac05 100644
--- a/lib/librte_vhost/vhost_crypto.c
+++ b/lib/librte_vhost/vhost_crypto.c
@@ -447,6 +447,7 @@ vhost_crypto_msg_post_handler(int vid, void *msg)
if (vmsg->request.master == VHOST_USER_CRYPTO_CREATE_SESS) {
vhost_crypto_create_sess(vcrypto,
&vmsg->payload.crypto_session);
+ vmsg->fd_num = 0;
ret = VH_RESULT_REPLY;
} else if (vmsg->request.master == VHOST_USER_CRYPTO_CLOSE_SESS) {
if (!vhost_crypto_close_sess(vcrypto, vmsg->payload.u64))
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index bce2395a3..99adcedfa 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -161,6 +161,7 @@ vhost_user_get_features(struct virtio_net **pdev, struct VhostUserMsg *msg,
msg->payload.u64 = features;
msg->size = sizeof(msg->payload.u64);
+ msg->fd_num = 0;
return VH_RESULT_REPLY;
}
@@ -179,6 +180,7 @@ vhost_user_get_queue_num(struct virtio_net **pdev, struct VhostUserMsg *msg,
msg->payload.u64 = (uint64_t)queue_num;
msg->size = sizeof(msg->payload.u64);
+ msg->fd_num = 0;
return VH_RESULT_REPLY;
}
@@ -1165,6 +1167,7 @@ vhost_user_get_vring_base(struct virtio_net **pdev,
vq->batch_copy_elems = NULL;
msg->size = sizeof(msg->payload.state);
+ msg->fd_num = 0;
return VH_RESULT_REPLY;
}
@@ -1224,6 +1227,7 @@ vhost_user_get_protocol_features(struct virtio_net **pdev,
msg->payload.u64 = protocol_features;
msg->size = sizeof(msg->payload.u64);
+ msg->fd_num = 0;
return VH_RESULT_REPLY;
}
@@ -1310,6 +1314,7 @@ vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg,
* any payload in the reply.
*/
msg->size = 0;
+ msg->fd_num = 0;
return VH_RESULT_REPLY;
}
@@ -1556,13 +1561,13 @@ read_vhost_message(int sockfd, struct VhostUserMsg *msg)
}
static int
-send_vhost_message(int sockfd, struct VhostUserMsg *msg, int *fds, int fd_num)
+send_vhost_message(int sockfd, struct VhostUserMsg *msg)
{
if (!msg)
return 0;
return send_fd_message(sockfd, (char *)msg,
- VHOST_USER_HDR_SIZE + msg->size, fds, fd_num);
+ VHOST_USER_HDR_SIZE + msg->size, msg->fds, msg->fd_num);
}
static int
@@ -1576,19 +1581,18 @@ send_vhost_reply(int sockfd, struct VhostUserMsg *msg)
msg->flags |= VHOST_USER_VERSION;
msg->flags |= VHOST_USER_REPLY_MASK;
- return send_vhost_message(sockfd, msg, NULL, 0);
+ return send_vhost_message(sockfd, msg);
}
static int
-send_vhost_slave_message(struct virtio_net *dev, struct VhostUserMsg *msg,
- int *fds, int fd_num)
+send_vhost_slave_message(struct virtio_net *dev, struct VhostUserMsg *msg)
{
int ret;
if (msg->flags & VHOST_USER_NEED_REPLY)
rte_spinlock_lock(&dev->slave_req_lock);
- ret = send_vhost_message(dev->slave_req_fd, msg, fds, fd_num);
+ ret = send_vhost_message(dev->slave_req_fd, msg);
if (ret < 0 && (msg->flags & VHOST_USER_NEED_REPLY))
rte_spinlock_unlock(&dev->slave_req_lock);
@@ -1820,6 +1824,7 @@ vhost_user_msg_handler(int vid, int fd)
if (msg.flags & VHOST_USER_NEED_REPLY) {
msg.payload.u64 = ret == VH_RESULT_ERR;
msg.size = sizeof(msg.payload.u64);
+ msg.fd_num = 0;
send_vhost_reply(fd, &msg);
} else if (ret == VH_RESULT_ERR) {
RTE_LOG(ERR, VHOST_CONFIG,
@@ -1903,7 +1908,7 @@ vhost_user_iotlb_miss(struct virtio_net *dev, uint64_t iova, uint8_t perm)
},
};
- ret = send_vhost_message(dev->slave_req_fd, &msg, NULL, 0);
+ ret = send_vhost_message(dev->slave_req_fd, &msg);
if (ret < 0) {
RTE_LOG(ERR, VHOST_CONFIG,
"Failed to send IOTLB miss message (%d)\n",
@@ -1919,8 +1924,6 @@ static int vhost_user_slave_set_vring_host_notifier(struct virtio_net *dev,
uint64_t offset,
uint64_t size)
{
- int *fdp = NULL;
- size_t fd_num = 0;
int ret;
struct VhostUserMsg msg = {
.request.slave = VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG,
@@ -1936,11 +1939,11 @@ static int vhost_user_slave_set_vring_host_notifier(struct virtio_net *dev,
if (fd < 0)
msg.payload.area.u64 |= VHOST_USER_VRING_NOFD_MASK;
else {
- fdp = &fd;
- fd_num = 1;
+ msg.fds[0] = fd;
+ msg.fd_num = 1;
}
- ret = send_vhost_slave_message(dev, &msg, fdp, fd_num);
+ ret = send_vhost_slave_message(dev, &msg);
if (ret < 0) {
RTE_LOG(ERR, VHOST_CONFIG,
"Failed to set host notifier (%d)\n", ret);
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 10/19] vhost: add config flag for postcopy feature
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (8 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 09/19] vhost: enable fds passing when sending vhost-user messages Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 11/19] vhost: introduce postcopy's advise message Maxime Coquelin
` (8 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Postcopy live-migration features relies on userfaultfd,
which was only introduced in kernel v4.3.
This patch introduces a new define to allow building vhost
library on kernels not supporting userfaultfd.
With legacy build system, user has to explicitly set
CONFIG_RTE_LIBRTE_VHOST_POSTCOPY to 'y'.
With Meson build system, RTE_LIBRTE_VHOST_POSTCOPY gets
automatically defined if userfaultfd kernel header is
present.
Suggested-by: Ilya Maximets <i.maximets@samsung.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Ilya Maximets <i.maximets@samsung.com>
---
config/common_linuxapp | 1 +
lib/librte_vhost/meson.build | 2 ++
2 files changed, 3 insertions(+)
diff --git a/config/common_linuxapp b/config/common_linuxapp
index 485e1467d..424100a75 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -14,6 +14,7 @@ CONFIG_RTE_LIBRTE_KNI=y
CONFIG_RTE_LIBRTE_PMD_KNI=y
CONFIG_RTE_LIBRTE_VHOST=y
CONFIG_RTE_LIBRTE_VHOST_NUMA=y
+CONFIG_RTE_LIBRTE_VHOST_POSTCOPY=n
CONFIG_RTE_LIBRTE_PMD_VHOST=y
CONFIG_RTE_LIBRTE_IFC_PMD=y
CONFIG_RTE_LIBRTE_PMD_AF_PACKET=y
diff --git a/lib/librte_vhost/meson.build b/lib/librte_vhost/meson.build
index 9d25b4d88..e33e6fc16 100644
--- a/lib/librte_vhost/meson.build
+++ b/lib/librte_vhost/meson.build
@@ -7,6 +7,8 @@ endif
if has_libnuma == 1
dpdk_conf.set10('RTE_LIBRTE_VHOST_NUMA', true)
endif
+dpdk_conf.set('RTE_LIBRTE_VHOST_POSTCOPY',
+ cc.has_header('linux/userfaultfd.h'))
version = 4
allow_experimental_apis = true
cflags += '-fno-strict-aliasing'
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 11/19] vhost: introduce postcopy's advise message
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (9 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 10/19] vhost: add config flag for postcopy feature Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 12/19] vhost: add support for postcopy's listen message Maxime Coquelin
` (7 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
This patch opens a userfaultfd and sends it back to Qemu's
VHOST_USER_POSTCOPY_ADVISE request.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost.h | 2 ++
lib/librte_vhost/vhost_user.c | 50 +++++++++++++++++++++++++++++++++++
lib/librte_vhost/vhost_user.h | 3 ++-
3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 341b0a147..4c591a410 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -358,6 +358,8 @@ struct virtio_net {
int slave_req_fd;
rte_spinlock_t slave_req_lock;
+ int postcopy_ufd;
+
/*
* Device id to identify a specific backend device.
* It's set to -1 for the default software implementation.
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 99adcedfa..970ad5896 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -24,13 +24,19 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/syscall.h>
#include <assert.h>
#ifdef RTE_LIBRTE_VHOST_NUMA
#include <numaif.h>
#endif
+#ifdef RTE_LIBRTE_VHOST_POSTCOPY
+#include <linux/userfaultfd.h>
+#endif
#include <rte_common.h>
#include <rte_malloc.h>
@@ -69,6 +75,7 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
[VHOST_USER_IOTLB_MSG] = "VHOST_USER_IOTLB_MSG",
[VHOST_USER_CRYPTO_CREATE_SESS] = "VHOST_USER_CRYPTO_CREATE_SESS",
[VHOST_USER_CRYPTO_CLOSE_SESS] = "VHOST_USER_CRYPTO_CLOSE_SESS",
+ [VHOST_USER_POSTCOPY_ADVISE] = "VHOST_USER_POSTCOPY_ADVISE",
};
static uint64_t
@@ -120,6 +127,11 @@ vhost_backend_cleanup(struct virtio_net *dev)
close(dev->slave_req_fd);
dev->slave_req_fd = -1;
}
+
+ if (dev->postcopy_ufd >= 0) {
+ close(dev->postcopy_ufd);
+ dev->postcopy_ufd = -1;
+ }
}
/*
@@ -1500,6 +1512,43 @@ vhost_user_iotlb_msg(struct virtio_net **pdev, struct VhostUserMsg *msg,
return VH_RESULT_OK;
}
+static int
+vhost_user_set_postcopy_advise(struct virtio_net **pdev,
+ struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
+{
+ struct virtio_net *dev = *pdev;
+#ifdef RTE_LIBRTE_VHOST_POSTCOPY
+ struct uffdio_api api_struct;
+
+ dev->postcopy_ufd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
+
+ if (dev->postcopy_ufd == -1) {
+ RTE_LOG(ERR, VHOST_CONFIG, "Userfaultfd not available: %s\n",
+ strerror(errno));
+ return VH_RESULT_ERR;
+ }
+ api_struct.api = UFFD_API;
+ api_struct.features = 0;
+ if (ioctl(dev->postcopy_ufd, UFFDIO_API, &api_struct)) {
+ RTE_LOG(ERR, VHOST_CONFIG, "UFFDIO_API ioctl failure: %s\n",
+ strerror(errno));
+ close(dev->postcopy_ufd);
+ dev->postcopy_ufd = -1;
+ return VH_RESULT_ERR;
+ }
+ msg->fds[0] = dev->postcopy_ufd;
+ msg->fd_num = 1;
+
+ return VH_RESULT_REPLY;
+#else
+ dev->postcopy_ufd = -1;
+ msg->fd_num = 0;
+
+ return VH_RESULT_ERR;
+#endif
+}
+
typedef int (*vhost_message_handler_t)(struct virtio_net **pdev,
struct VhostUserMsg *msg,
int main_fd);
@@ -1527,6 +1576,7 @@ static vhost_message_handler_t vhost_message_handlers[VHOST_USER_MAX] = {
[VHOST_USER_NET_SET_MTU] = vhost_user_net_set_mtu,
[VHOST_USER_SET_SLAVE_REQ_FD] = vhost_user_set_req_fd,
[VHOST_USER_IOTLB_MSG] = vhost_user_iotlb_msg,
+ [VHOST_USER_POSTCOPY_ADVISE] = vhost_user_set_postcopy_advise,
};
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index 9a91d496b..04295d9a6 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -50,7 +50,8 @@ typedef enum VhostUserRequest {
VHOST_USER_IOTLB_MSG = 22,
VHOST_USER_CRYPTO_CREATE_SESS = 26,
VHOST_USER_CRYPTO_CLOSE_SESS = 27,
- VHOST_USER_MAX = 28
+ VHOST_USER_POSTCOPY_ADVISE = 28,
+ VHOST_USER_MAX = 29
} VhostUserRequest;
typedef enum VhostUserSlaveRequest {
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 12/19] vhost: add support for postcopy's listen message
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (10 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 11/19] vhost: introduce postcopy's advise message Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 13/19] vhost: register new regions with userfaultfd Maxime Coquelin
` (6 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost.h | 1 +
lib/librte_vhost/vhost_user.c | 21 +++++++++++++++++++++
lib/librte_vhost/vhost_user.h | 3 ++-
3 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 4c591a410..702be37ff 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -359,6 +359,7 @@ struct virtio_net {
rte_spinlock_t slave_req_lock;
int postcopy_ufd;
+ int postcopy_listening;
/*
* Device id to identify a specific backend device.
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 970ad5896..051589297 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -76,6 +76,7 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
[VHOST_USER_CRYPTO_CREATE_SESS] = "VHOST_USER_CRYPTO_CREATE_SESS",
[VHOST_USER_CRYPTO_CLOSE_SESS] = "VHOST_USER_CRYPTO_CLOSE_SESS",
[VHOST_USER_POSTCOPY_ADVISE] = "VHOST_USER_POSTCOPY_ADVISE",
+ [VHOST_USER_POSTCOPY_LISTEN] = "VHOST_USER_POSTCOPY_LISTEN",
};
static uint64_t
@@ -132,6 +133,8 @@ vhost_backend_cleanup(struct virtio_net *dev)
close(dev->postcopy_ufd);
dev->postcopy_ufd = -1;
}
+
+ dev->postcopy_listening = 0;
}
/*
@@ -1549,6 +1552,23 @@ vhost_user_set_postcopy_advise(struct virtio_net **pdev,
#endif
}
+static int
+vhost_user_set_postcopy_listen(struct virtio_net **pdev,
+ struct VhostUserMsg *msg __rte_unused,
+ int main_fd __rte_unused)
+{
+ struct virtio_net *dev = *pdev;
+
+ if (dev->mem && dev->mem->nregions) {
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "Regions already registered at postcopy-listen\n");
+ return VH_RESULT_ERR;
+ }
+ dev->postcopy_listening = 1;
+
+ return VH_RESULT_OK;
+}
+
typedef int (*vhost_message_handler_t)(struct virtio_net **pdev,
struct VhostUserMsg *msg,
int main_fd);
@@ -1577,6 +1597,7 @@ static vhost_message_handler_t vhost_message_handlers[VHOST_USER_MAX] = {
[VHOST_USER_SET_SLAVE_REQ_FD] = vhost_user_set_req_fd,
[VHOST_USER_IOTLB_MSG] = vhost_user_iotlb_msg,
[VHOST_USER_POSTCOPY_ADVISE] = vhost_user_set_postcopy_advise,
+ [VHOST_USER_POSTCOPY_LISTEN] = vhost_user_set_postcopy_listen,
};
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index 04295d9a6..9c5cde639 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -51,7 +51,8 @@ typedef enum VhostUserRequest {
VHOST_USER_CRYPTO_CREATE_SESS = 26,
VHOST_USER_CRYPTO_CLOSE_SESS = 27,
VHOST_USER_POSTCOPY_ADVISE = 28,
- VHOST_USER_MAX = 29
+ VHOST_USER_POSTCOPY_LISTEN = 29,
+ VHOST_USER_MAX = 30
} VhostUserRequest;
typedef enum VhostUserSlaveRequest {
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 13/19] vhost: register new regions with userfaultfd
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (11 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 12/19] vhost: add support for postcopy's listen message Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 14/19] vhost: avoid useless VhostUserMemory copy Maxime Coquelin
` (5 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost_user.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 051589297..91c301ae2 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -965,6 +965,32 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg,
mmap_size,
alignment,
mmap_offset);
+
+ if (dev->postcopy_listening) {
+#ifdef RTE_LIBRTE_VHOST_POSTCOPY
+ struct uffdio_register reg_struct;
+
+ reg_struct.range.start = (uint64_t)(uintptr_t)mmap_addr;
+ reg_struct.range.len = mmap_size;
+ reg_struct.mode = UFFDIO_REGISTER_MODE_MISSING;
+
+ if (ioctl(dev->postcopy_ufd, UFFDIO_REGISTER,
+ ®_struct)) {
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "Failed to register ufd for region %d: (ufd = %d) %s\n",
+ i, dev->postcopy_ufd,
+ strerror(errno));
+ goto err_mmap;
+ }
+ RTE_LOG(INFO, VHOST_CONFIG,
+ "\t userfaultfd registered for range : %llx - %llx\n",
+ reg_struct.range.start,
+ reg_struct.range.start +
+ reg_struct.range.len - 1);
+#else
+ goto err_mmap;
+#endif
+ }
}
for (i = 0; i < dev->nr_vring; i++) {
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 14/19] vhost: avoid useless VhostUserMemory copy
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (12 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 13/19] vhost: register new regions with userfaultfd Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 15/19] vhost: send userfault range addresses back to qemu Maxime Coquelin
` (4 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
The VHOST_USER_SET_MEM_TABLE payload is copied when handled,
whereas it could directly be referenced.
This is not very important, but next, we'll need to update the
payload and send it back to Qemu.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Acked-by: Ilya Maximets <i.maximets@samsung.com>
---
lib/librte_vhost/vhost_user.c | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 91c301ae2..d17c3b0ec 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -826,7 +826,7 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg,
int main_fd __rte_unused)
{
struct virtio_net *dev = *pdev;
- struct VhostUserMemory memory = msg->payload.memory;
+ struct VhostUserMemory *memory = &msg->payload.memory;
struct rte_vhost_mem_region *reg;
void *mmap_addr;
uint64_t mmap_size;
@@ -836,17 +836,17 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg,
int populate;
int fd;
- if (memory.nregions > VHOST_MEMORY_MAX_NREGIONS) {
+ if (memory->nregions > VHOST_MEMORY_MAX_NREGIONS) {
RTE_LOG(ERR, VHOST_CONFIG,
- "too many memory regions (%u)\n", memory.nregions);
+ "too many memory regions (%u)\n", memory->nregions);
return VH_RESULT_ERR;
}
- if (dev->mem && !vhost_memory_changed(&memory, dev->mem)) {
+ if (dev->mem && !vhost_memory_changed(memory, dev->mem)) {
RTE_LOG(INFO, VHOST_CONFIG,
"(%d) memory regions not changed\n", dev->vid);
- for (i = 0; i < memory.nregions; i++)
+ for (i = 0; i < memory->nregions; i++)
close(msg->fds[i]);
return VH_RESULT_OK;
@@ -878,25 +878,25 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg,
}
dev->mem = rte_zmalloc("vhost-mem-table", sizeof(struct rte_vhost_memory) +
- sizeof(struct rte_vhost_mem_region) * memory.nregions, 0);
+ sizeof(struct rte_vhost_mem_region) * memory->nregions, 0);
if (dev->mem == NULL) {
RTE_LOG(ERR, VHOST_CONFIG,
"(%d) failed to allocate memory for dev->mem\n",
dev->vid);
return VH_RESULT_ERR;
}
- dev->mem->nregions = memory.nregions;
+ dev->mem->nregions = memory->nregions;
- for (i = 0; i < memory.nregions; i++) {
+ for (i = 0; i < memory->nregions; i++) {
fd = msg->fds[i];
reg = &dev->mem->regions[i];
- reg->guest_phys_addr = memory.regions[i].guest_phys_addr;
- reg->guest_user_addr = memory.regions[i].userspace_addr;
- reg->size = memory.regions[i].memory_size;
+ reg->guest_phys_addr = memory->regions[i].guest_phys_addr;
+ reg->guest_user_addr = memory->regions[i].userspace_addr;
+ reg->size = memory->regions[i].memory_size;
reg->fd = fd;
- mmap_offset = memory.regions[i].mmap_offset;
+ mmap_offset = memory->regions[i].mmap_offset;
/* Check for memory_size + mmap_offset overflow */
if (mmap_offset >= -reg->size) {
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 15/19] vhost: send userfault range addresses back to qemu
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (13 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 14/19] vhost: avoid useless VhostUserMemory copy Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 16/19] vhost: add support to postcopy's end request Maxime Coquelin
` (3 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost_user.c | 47 ++++++++++++++++++++++++++++++++---
1 file changed, 44 insertions(+), 3 deletions(-)
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index d17c3b0ec..8890abbe8 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -79,6 +79,9 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
[VHOST_USER_POSTCOPY_LISTEN] = "VHOST_USER_POSTCOPY_LISTEN",
};
+static int send_vhost_reply(int sockfd, struct VhostUserMsg *msg);
+static int read_vhost_message(int sockfd, struct VhostUserMsg *msg);
+
static uint64_t
get_blk_size(int fd)
{
@@ -823,7 +826,7 @@ vhost_memory_changed(struct VhostUserMemory *new,
static int
vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg,
- int main_fd __rte_unused)
+ int main_fd)
{
struct virtio_net *dev = *pdev;
struct VhostUserMemory *memory = &msg->payload.memory;
@@ -967,11 +970,49 @@ vhost_user_set_mem_table(struct virtio_net **pdev, struct VhostUserMsg *msg,
mmap_offset);
if (dev->postcopy_listening) {
+ /*
+ * We haven't a better way right now than sharing
+ * DPDK's virtual address with Qemu, so that Qemu can
+ * retrieve the region offset when handling userfaults.
+ */
+ memory->regions[i].userspace_addr =
+ reg->host_user_addr;
+ }
+ }
+ if (dev->postcopy_listening) {
+ /* Send the addresses back to qemu */
+ msg->fd_num = 0;
+ send_vhost_reply(main_fd, msg);
+
+ /* Wait for qemu to acknolwedge it's got the addresses
+ * we've got to wait before we're allowed to generate faults.
+ */
+ VhostUserMsg ack_msg;
+ if (read_vhost_message(main_fd, &ack_msg) <= 0) {
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "Failed to read qemu ack on postcopy set-mem-table\n");
+ goto err_mmap;
+ }
+ if (ack_msg.request.master != VHOST_USER_SET_MEM_TABLE) {
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "Bad qemu ack on postcopy set-mem-table (%d)\n",
+ ack_msg.request.master);
+ goto err_mmap;
+ }
+
+ /* Now userfault register and we can use the memory */
+ for (i = 0; i < memory->nregions; i++) {
#ifdef RTE_LIBRTE_VHOST_POSTCOPY
+ reg = &dev->mem->regions[i];
struct uffdio_register reg_struct;
- reg_struct.range.start = (uint64_t)(uintptr_t)mmap_addr;
- reg_struct.range.len = mmap_size;
+ /*
+ * Let's register all the mmap'ed area to ensure
+ * alignment on page boundary.
+ */
+ reg_struct.range.start =
+ (uint64_t)(uintptr_t)reg->mmap_addr;
+ reg_struct.range.len = reg->mmap_size;
reg_struct.mode = UFFDIO_REGISTER_MODE_MISSING;
if (ioctl(dev->postcopy_ufd, UFFDIO_REGISTER,
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 16/19] vhost: add support to postcopy's end request
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (14 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 15/19] vhost: send userfault range addresses back to qemu Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 17/19] vhost: restrict postcopy live-migration enablement Maxime Coquelin
` (2 subsequent siblings)
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
The master sends this message before stopping handling
userfaults, so that the backend closes the userfaultfd.
The master waits for the slave to acknowledge the request
with an empty 64bits payload for synchronization purpose.
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost_user.c | 21 +++++++++++++++++++++
lib/librte_vhost/vhost_user.h | 3 ++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 8890abbe8..0560f2f96 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -77,6 +77,7 @@ static const char *vhost_message_str[VHOST_USER_MAX] = {
[VHOST_USER_CRYPTO_CLOSE_SESS] = "VHOST_USER_CRYPTO_CLOSE_SESS",
[VHOST_USER_POSTCOPY_ADVISE] = "VHOST_USER_POSTCOPY_ADVISE",
[VHOST_USER_POSTCOPY_LISTEN] = "VHOST_USER_POSTCOPY_LISTEN",
+ [VHOST_USER_POSTCOPY_END] = "VHOST_USER_POSTCOPY_END",
};
static int send_vhost_reply(int sockfd, struct VhostUserMsg *msg);
@@ -1636,6 +1637,25 @@ vhost_user_set_postcopy_listen(struct virtio_net **pdev,
return VH_RESULT_OK;
}
+static int
+vhost_user_postcopy_end(struct virtio_net **pdev, struct VhostUserMsg *msg,
+ int main_fd __rte_unused)
+{
+ struct virtio_net *dev = *pdev;
+
+ dev->postcopy_listening = 0;
+ if (dev->postcopy_ufd >= 0) {
+ close(dev->postcopy_ufd);
+ dev->postcopy_ufd = -1;
+ }
+
+ msg->payload.u64 = 0;
+ msg->size = sizeof(msg->payload.u64);
+ msg->fd_num = 0;
+
+ return VH_RESULT_REPLY;
+}
+
typedef int (*vhost_message_handler_t)(struct virtio_net **pdev,
struct VhostUserMsg *msg,
int main_fd);
@@ -1665,6 +1685,7 @@ static vhost_message_handler_t vhost_message_handlers[VHOST_USER_MAX] = {
[VHOST_USER_IOTLB_MSG] = vhost_user_iotlb_msg,
[VHOST_USER_POSTCOPY_ADVISE] = vhost_user_set_postcopy_advise,
[VHOST_USER_POSTCOPY_LISTEN] = vhost_user_set_postcopy_listen,
+ [VHOST_USER_POSTCOPY_END] = vhost_user_postcopy_end,
};
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index 9c5cde639..aa8374ee2 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -52,7 +52,8 @@ typedef enum VhostUserRequest {
VHOST_USER_CRYPTO_CLOSE_SESS = 27,
VHOST_USER_POSTCOPY_ADVISE = 28,
VHOST_USER_POSTCOPY_LISTEN = 29,
- VHOST_USER_MAX = 30
+ VHOST_USER_POSTCOPY_END = 30,
+ VHOST_USER_MAX = 31
} VhostUserRequest;
typedef enum VhostUserSlaveRequest {
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 17/19] vhost: restrict postcopy live-migration enablement
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (15 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 16/19] vhost: add support to postcopy's end request Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 18/19] net/vhost: add parameter to enable postcopy support Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 19/19] vhost: enable postcopy protocol feature Maxime Coquelin
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Postcopy live-migration feature requires the application to
not populate the guest memory. As the vhost library cannot
prevent the application to that (e.g. preventing the
application to call mlockall()), the feature is disabled by
default.
The application should only enable the feature if it does not
force the guest memory to be populated.
In case the user passes the RTE_VHOST_USER_POSTCOPY_SUPPORT
flag at registration but the feature was not compiled,
registration fails.
For the same reason, postcopy and dequeue zero copy features
are not compatible, so don't advertize postcopy support if
dequeue zero copy is requested.
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
doc/guides/prog_guide/vhost_lib.rst | 8 ++++++++
lib/librte_vhost/rte_vhost.h | 1 +
lib/librte_vhost/socket.c | 30 ++++++++++++++++++++++++++---
lib/librte_vhost/vhost_user.c | 6 +++++-
4 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/doc/guides/prog_guide/vhost_lib.rst b/doc/guides/prog_guide/vhost_lib.rst
index 77af4d775..c77df338f 100644
--- a/doc/guides/prog_guide/vhost_lib.rst
+++ b/doc/guides/prog_guide/vhost_lib.rst
@@ -106,6 +106,14 @@ The following is an overview of some key Vhost API functions:
Enabling this flag with these Qemu version results in Qemu being blocked
when multiple queue pairs are declared.
+ - ``RTE_VHOST_USER_POSTCOPY_SUPPORT``
+
+ Postcopy live-migration support will be enabled when this flag is set.
+ It is disabled by default.
+
+ Enabling this flag should only be done when the calling application does
+ not pre-fault the guest shared memory, otherwise migration would fail.
+
* ``rte_vhost_driver_set_features(path, features)``
This function sets the feature bits the vhost-user driver supports. The
diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 9292c89c5..d280ac420 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -28,6 +28,7 @@ extern "C" {
#define RTE_VHOST_USER_NO_RECONNECT (1ULL << 1)
#define RTE_VHOST_USER_DEQUEUE_ZERO_COPY (1ULL << 2)
#define RTE_VHOST_USER_IOMMU_SUPPORT (1ULL << 3)
+#define RTE_VHOST_USER_POSTCOPY_SUPPORT (1ULL << 4)
/** Protocol features. */
#ifndef VHOST_USER_PROTOCOL_F_MQ
diff --git a/lib/librte_vhost/socket.c b/lib/librte_vhost/socket.c
index 3b0287a26..4c804b34a 100644
--- a/lib/librte_vhost/socket.c
+++ b/lib/librte_vhost/socket.c
@@ -51,6 +51,8 @@ struct vhost_user_socket {
uint64_t supported_features;
uint64_t features;
+ uint64_t protocol_features;
+
/*
* Device id to identify a specific backend device.
* It's set to -1 for the default software implementation.
@@ -735,7 +737,7 @@ rte_vhost_driver_get_protocol_features(const char *path,
did = vsocket->vdpa_dev_id;
vdpa_dev = rte_vdpa_get_device(did);
if (!vdpa_dev || !vdpa_dev->ops->get_protocol_features) {
- *protocol_features = VHOST_USER_PROTOCOL_FEATURES;
+ *protocol_features = vsocket->protocol_features;
goto unlock_exit;
}
@@ -748,7 +750,7 @@ rte_vhost_driver_get_protocol_features(const char *path,
goto unlock_exit;
}
- *protocol_features = VHOST_USER_PROTOCOL_FEATURES
+ *protocol_features = vsocket->protocol_features
& vdpa_protocol_features;
unlock_exit:
@@ -867,11 +869,21 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
vsocket->use_builtin_virtio_net = true;
vsocket->supported_features = VIRTIO_NET_SUPPORTED_FEATURES;
vsocket->features = VIRTIO_NET_SUPPORTED_FEATURES;
+ vsocket->protocol_features = VHOST_USER_PROTOCOL_FEATURES;
- /* Dequeue zero copy can't assure descriptors returned in order */
+ /*
+ * Dequeue zero copy can't assure descriptors returned in order.
+ * Also, it requires that the guest memory is populated, which is
+ * not compatible with postcopy.
+ */
if (vsocket->dequeue_zero_copy) {
vsocket->supported_features &= ~(1ULL << VIRTIO_F_IN_ORDER);
vsocket->features &= ~(1ULL << VIRTIO_F_IN_ORDER);
+
+ RTE_LOG(INFO, VHOST_CONFIG,
+ "Dequeue zero copy requested, disabling postcopy support\n");
+ vsocket->protocol_features &=
+ ~(1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT);
}
if (!(flags & RTE_VHOST_USER_IOMMU_SUPPORT)) {
@@ -879,6 +891,18 @@ rte_vhost_driver_register(const char *path, uint64_t flags)
vsocket->features &= ~(1ULL << VIRTIO_F_IOMMU_PLATFORM);
}
+ if (!(flags & RTE_VHOST_USER_POSTCOPY_SUPPORT)) {
+ vsocket->protocol_features &=
+ ~(1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT);
+ } else {
+#ifndef RTE_LIBRTE_VHOST_POSTCOPY
+ RTE_LOG(ERR, VHOST_CONFIG,
+ "Postcopy requested but not compiled\n");
+ ret = -1;
+ goto out_mutex;
+#endif
+ }
+
if ((flags & RTE_VHOST_USER_CLIENT) != 0) {
vsocket->reconnect = !(flags & RTE_VHOST_USER_NO_RECONNECT);
if (vsocket->reconnect && reconn_tid == 0) {
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 0560f2f96..508228a3c 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -1322,7 +1322,11 @@ vhost_user_set_protocol_features(struct virtio_net **pdev,
{
struct virtio_net *dev = *pdev;
uint64_t protocol_features = msg->payload.u64;
- if (protocol_features & ~VHOST_USER_PROTOCOL_FEATURES) {
+ uint64_t slave_protocol_features = 0;
+
+ rte_vhost_driver_get_protocol_features(dev->ifname,
+ &slave_protocol_features);
+ if (protocol_features & ~slave_protocol_features) {
RTE_LOG(ERR, VHOST_CONFIG,
"(%d) received invalid protocol features.\n",
dev->vid);
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 18/19] net/vhost: add parameter to enable postcopy support
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (16 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 17/19] vhost: restrict postcopy live-migration enablement Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 19/19] vhost: enable postcopy protocol feature Maxime Coquelin
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Introduce a new postcopy-support parameter to Vhost PMD that
passes the RTE_VHOST_USER_POSTCOPY_SUPPORT flag at vhost
device register time.
Flag should only be set if application does not prefault guest
memory using, for example, mlockall() syscall.
Default value is 0, meaning that postcopy support is disabled
unless specified explicitly.
Example to enable postcopy support for a given device:
--vdev 'net_vhost0,iface=/tmp/vhost-user1,postcopy-support=1'
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
doc/guides/nics/vhost.rst | 5 +++++
drivers/net/vhost/rte_eth_vhost.c | 13 +++++++++++++
2 files changed, 18 insertions(+)
diff --git a/doc/guides/nics/vhost.rst b/doc/guides/nics/vhost.rst
index 4f7ae8990..23f2e87aa 100644
--- a/doc/guides/nics/vhost.rst
+++ b/doc/guides/nics/vhost.rst
@@ -71,6 +71,11 @@ The user can specify below arguments in `--vdev` option.
It is used to enable iommu support in vhost library.
(Default: 0 (disabled))
+#. ``postcopy-support``:
+
+ It is used to enable postcopy live-migration support in vhost library.
+ (Default: 0 (disabled))
+
Vhost PMD event handling
------------------------
diff --git a/drivers/net/vhost/rte_eth_vhost.c b/drivers/net/vhost/rte_eth_vhost.c
index aa6052221..1330f06ba 100644
--- a/drivers/net/vhost/rte_eth_vhost.c
+++ b/drivers/net/vhost/rte_eth_vhost.c
@@ -30,6 +30,7 @@ enum {VIRTIO_RXQ, VIRTIO_TXQ, VIRTIO_QNUM};
#define ETH_VHOST_CLIENT_ARG "client"
#define ETH_VHOST_DEQUEUE_ZERO_COPY "dequeue-zero-copy"
#define ETH_VHOST_IOMMU_SUPPORT "iommu-support"
+#define ETH_VHOST_POSTCOPY_SUPPORT "postcopy-support"
#define VHOST_MAX_PKT_BURST 32
static const char *valid_arguments[] = {
@@ -38,6 +39,7 @@ static const char *valid_arguments[] = {
ETH_VHOST_CLIENT_ARG,
ETH_VHOST_DEQUEUE_ZERO_COPY,
ETH_VHOST_IOMMU_SUPPORT,
+ ETH_VHOST_POSTCOPY_SUPPORT,
NULL
};
@@ -1339,6 +1341,7 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
int client_mode = 0;
int dequeue_zero_copy = 0;
int iommu_support = 0;
+ int postcopy_support = 0;
struct rte_eth_dev *eth_dev;
const char *name = rte_vdev_device_name(dev);
@@ -1411,6 +1414,16 @@ rte_pmd_vhost_probe(struct rte_vdev_device *dev)
flags |= RTE_VHOST_USER_IOMMU_SUPPORT;
}
+ if (rte_kvargs_count(kvlist, ETH_VHOST_POSTCOPY_SUPPORT) == 1) {
+ ret = rte_kvargs_process(kvlist, ETH_VHOST_POSTCOPY_SUPPORT,
+ &open_int, &postcopy_support);
+ if (ret < 0)
+ goto out_free;
+
+ if (postcopy_support)
+ flags |= RTE_VHOST_USER_POSTCOPY_SUPPORT;
+ }
+
if (dev->device.numa_node == SOCKET_ID_ANY)
dev->device.numa_node = rte_socket_id();
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread
* [dpdk-dev] [PATCH v6 19/19] vhost: enable postcopy protocol feature
2018-10-11 9:24 [dpdk-dev] [PATCH v6 00/19] vhost: add postcopy live-migration support Maxime Coquelin
` (17 preceding siblings ...)
2018-10-11 9:24 ` [dpdk-dev] [PATCH v6 18/19] net/vhost: add parameter to enable postcopy support Maxime Coquelin
@ 2018-10-11 9:24 ` Maxime Coquelin
18 siblings, 0 replies; 30+ messages in thread
From: Maxime Coquelin @ 2018-10-11 9:24 UTC (permalink / raw)
To: dev, tiwei.bie, zhihong.wang, jfreimann, nicknickolaev,
i.maximets, bruce.richardson, alejandro.lucero
Cc: dgilbert, stable, Maxime Coquelin
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
lib/librte_vhost/vhost_user.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/librte_vhost/vhost_user.h b/lib/librte_vhost/vhost_user.h
index aa8374ee2..14dccdedf 100644
--- a/lib/librte_vhost/vhost_user.h
+++ b/lib/librte_vhost/vhost_user.h
@@ -22,7 +22,8 @@
(1ULL << VHOST_USER_PROTOCOL_F_SLAVE_REQ) | \
(1ULL << VHOST_USER_PROTOCOL_F_CRYPTO_SESSION) | \
(1ULL << VHOST_USER_PROTOCOL_F_SLAVE_SEND_FD) | \
- (1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER))
+ (1ULL << VHOST_USER_PROTOCOL_F_HOST_NOTIFIER) | \
+ (1ULL << VHOST_USER_PROTOCOL_F_PAGEFAULT))
typedef enum VhostUserRequest {
VHOST_USER_NONE = 0,
--
2.17.1
^ permalink raw reply [flat|nested] 30+ messages in thread