[v3,2/4] power: extend guest channel api for reading

Message ID 20190321105506.6656-3-marcinx.hajkowski@intel.com
State Superseded, archived
Delegated to: Thomas Monjalon
Headers show
Series
  • bidirect guest channel
Related show

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Hajkowski March 21, 2019, 10:55 a.m.
From: Marcin Hajkowski <marcinx.hajkowski@intel.com>

Added new experimental API rte_power_guest_channel_receive_msg
which gives possibility to receive messages send to guest.

Signed-off-by: Marcin Hajkowski <marcinx.hajkowski@intel.com>
---
 lib/librte_power/channel_commands.h    |  5 ++
 lib/librte_power/guest_channel.c       | 65 ++++++++++++++++++++++++++
 lib/librte_power/guest_channel.h       | 35 ++++++++++++++
 lib/librte_power/rte_power_version.map |  1 +
 4 files changed, 106 insertions(+)

Comments

Maxime Coquelin March 22, 2019, 11 a.m. | #1
On 3/21/19 11:55 AM, Hajkowski wrote:
> From: Marcin Hajkowski <marcinx.hajkowski@intel.com>
> 
> Added new experimental API rte_power_guest_channel_receive_msg
> which gives possibility to receive messages send to guest.
> 
> Signed-off-by: Marcin Hajkowski <marcinx.hajkowski@intel.com>
> ---
>   lib/librte_power/channel_commands.h    |  5 ++
>   lib/librte_power/guest_channel.c       | 65 ++++++++++++++++++++++++++
>   lib/librte_power/guest_channel.h       | 35 ++++++++++++++
>   lib/librte_power/rte_power_version.map |  1 +
>   4 files changed, 106 insertions(+)
> 
> diff --git a/lib/librte_power/channel_commands.h b/lib/librte_power/channel_commands.h
> index e7b93a797..33fd53a6d 100644
> --- a/lib/librte_power/channel_commands.h
> +++ b/lib/librte_power/channel_commands.h
> @@ -28,6 +28,11 @@ extern "C" {
>   #define CPU_POWER_SCALE_MIN     4
>   #define CPU_POWER_ENABLE_TURBO  5
>   #define CPU_POWER_DISABLE_TURBO 6
> +
> +/* Generic Power Command Response */
> +#define CPU_POWER_CMD_ACK       1
> +#define CPU_POWER_CMD_NACK      2
> +
>   #define HOURS 24
>   
>   #define MAX_VFS 10
> diff --git a/lib/librte_power/guest_channel.c b/lib/librte_power/guest_channel.c
> index 9cf7d2cb2..3213fa769 100644
> --- a/lib/librte_power/guest_channel.c
> +++ b/lib/librte_power/guest_channel.c
> @@ -10,6 +10,7 @@
>   #include <fcntl.h>
>   #include <string.h>
>   #include <errno.h>
> +#include <poll.h>
>   
>   
>   #include <rte_log.h>
> @@ -19,6 +20,9 @@
>   
>   #define RTE_LOGTYPE_GUEST_CHANNEL RTE_LOGTYPE_USER1
>   
> +/* Timeout for incoming message in milliseconds. */
> +#define TIMEOUT 10
> +
>   static int global_fds[RTE_MAX_LCORE] = { [0 ... RTE_MAX_LCORE-1] = -1 };
>   
>   int
> @@ -125,6 +129,67 @@ int rte_power_guest_channel_send_msg(struct channel_packet *pkt,
>   	return guest_channel_send_msg(pkt, lcore_id);
>   }
>   
> +int power_guest_channel_read_msg(struct channel_packet *pkt,
> +			unsigned int lcore_id)
> +{
> +	int ret;
> +
> +	struct pollfd fds;
> +	fds.fd = global_fds[lcore_id];
> +	fds.events = POLLIN;
> +
> +	ret = poll(&fds, 1, TIMEOUT);
> +	if (ret == 0) {
> +		RTE_LOG(DEBUG, GUEST_CHANNEL, "Timeout occurs during poll function.\n");
> +		return -1;
> +	} else if (ret < 0) {
> +		RTE_LOG(ERR, GUEST_CHANNEL, "Error occurred during poll function: %s\n",
> +				strerror(ret));
> +		return -1;
> +	}
> +
> +	void *buffer = pkt;

I would prefer it to be declared at the beginning of the function,
but at least, declare it just before the while loop.

> +
> +	if (lcore_id >= RTE_MAX_LCORE) {
> +		RTE_LOG(ERR, GUEST_CHANNEL, "Channel(%u) is out of range 0...%d\n",
> +				lcore_id, RTE_MAX_LCORE-1);
> +		return -1;
> +	}
> +
> +	if (global_fds[lcore_id] < 0) {
> +		RTE_LOG(ERR, GUEST_CHANNEL, "Channel is not connected\n");
> +		return -1;
> +	}
> +
> +	int buffer_len = sizeof(*pkt);
> +
> +	while (buffer_len > 0) {
> +		ret = read(global_fds[lcore_id],
> +				buffer, buffer_len);
> +		if (ret < 0) {
> +			if (errno == EINTR)
> +				continue;
> +			return -1;
> +		}
> +		/* No data has been read, this can indicate not
> +		 * consistent buffer_len with actual data size.
> +		 */
> +		if (ret == 0) {
> +			RTE_LOG(ERR, GUEST_CHANNEL, "No more data has been read.\n");
> +			return -1;
> +		}
> +		buffer = (char *)buffer + ret;
> +		buffer_len -= ret;
> +	}
> +
> +	return 0;
> +}
> +
Ananyev, Konstantin March 22, 2019, 11:53 a.m. | #2
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Maxime Coquelin
> Sent: Friday, March 22, 2019 11:00 AM
> To: Hajkowski, MarcinX <marcinx.hajkowski@intel.com>; Hunt, David <david.hunt@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v3 2/4] power: extend guest channel api for reading
> 
> 
> 
> On 3/21/19 11:55 AM, Hajkowski wrote:
> > From: Marcin Hajkowski <marcinx.hajkowski@intel.com>
> >
> > Added new experimental API rte_power_guest_channel_receive_msg
> > which gives possibility to receive messages send to guest.
> >
> > Signed-off-by: Marcin Hajkowski <marcinx.hajkowski@intel.com>
> > ---
> >   lib/librte_power/channel_commands.h    |  5 ++
> >   lib/librte_power/guest_channel.c       | 65 ++++++++++++++++++++++++++
> >   lib/librte_power/guest_channel.h       | 35 ++++++++++++++
> >   lib/librte_power/rte_power_version.map |  1 +
> >   4 files changed, 106 insertions(+)
> >
> > diff --git a/lib/librte_power/channel_commands.h b/lib/librte_power/channel_commands.h
> > index e7b93a797..33fd53a6d 100644
> > --- a/lib/librte_power/channel_commands.h
> > +++ b/lib/librte_power/channel_commands.h
> > @@ -28,6 +28,11 @@ extern "C" {
> >   #define CPU_POWER_SCALE_MIN     4
> >   #define CPU_POWER_ENABLE_TURBO  5
> >   #define CPU_POWER_DISABLE_TURBO 6
> > +
> > +/* Generic Power Command Response */
> > +#define CPU_POWER_CMD_ACK       1
> > +#define CPU_POWER_CMD_NACK      2
> > +
> >   #define HOURS 24
> >
> >   #define MAX_VFS 10
> > diff --git a/lib/librte_power/guest_channel.c b/lib/librte_power/guest_channel.c
> > index 9cf7d2cb2..3213fa769 100644
> > --- a/lib/librte_power/guest_channel.c
> > +++ b/lib/librte_power/guest_channel.c
> > @@ -10,6 +10,7 @@
> >   #include <fcntl.h>
> >   #include <string.h>
> >   #include <errno.h>
> > +#include <poll.h>
> >
> >
> >   #include <rte_log.h>
> > @@ -19,6 +20,9 @@
> >
> >   #define RTE_LOGTYPE_GUEST_CHANNEL RTE_LOGTYPE_USER1
> >
> > +/* Timeout for incoming message in milliseconds. */
> > +#define TIMEOUT 10
> > +
> >   static int global_fds[RTE_MAX_LCORE] = { [0 ... RTE_MAX_LCORE-1] = -1 };
> >
> >   int
> > @@ -125,6 +129,67 @@ int rte_power_guest_channel_send_msg(struct channel_packet *pkt,
> >   	return guest_channel_send_msg(pkt, lcore_id);
> >   }
> >
> > +int power_guest_channel_read_msg(struct channel_packet *pkt,
> > +			unsigned int lcore_id)
> > +{
> > +	int ret;
> > +
> > +	struct pollfd fds;
> > +	fds.fd = global_fds[lcore_id];
> > +	fds.events = POLLIN;
> > +
> > +	ret = poll(&fds, 1, TIMEOUT);
> > +	if (ret == 0) {
> > +		RTE_LOG(DEBUG, GUEST_CHANNEL, "Timeout occurs during poll function.\n");
> > +		return -1;
> > +	} else if (ret < 0) {
> > +		RTE_LOG(ERR, GUEST_CHANNEL, "Error occurred during poll function: %s\n",
> > +				strerror(ret));
> > +		return -1;
> > +	}
> > +
> > +	void *buffer = pkt;
> 
> I would prefer it to be declared at the beginning of the function,

+1 here and in other places.
please follow dpdk coding style convention.

> but at least, declare it just before the while loop.
> 
> > +
> > +	if (lcore_id >= RTE_MAX_LCORE) {
> > +		RTE_LOG(ERR, GUEST_CHANNEL, "Channel(%u) is out of range 0...%d\n",
> > +				lcore_id, RTE_MAX_LCORE-1);
> > +		return -1;
> > +	}
> > +
> > +	if (global_fds[lcore_id] < 0) {
> > +		RTE_LOG(ERR, GUEST_CHANNEL, "Channel is not connected\n");
> > +		return -1;
> > +	}
> > +
> > +	int buffer_len = sizeof(*pkt);
> > +
> > +	while (buffer_len > 0) {
> > +		ret = read(global_fds[lcore_id],
> > +				buffer, buffer_len);
> > +		if (ret < 0) {
> > +			if (errno == EINTR)
> > +				continue;
> > +			return -1;
> > +		}
> > +		/* No data has been read, this can indicate not
> > +		 * consistent buffer_len with actual data size.
> > +		 */
> > +		if (ret == 0) {
> > +			RTE_LOG(ERR, GUEST_CHANNEL, "No more data has been read.\n");
> > +			return -1;
> > +		}
> > +		buffer = (char *)buffer + ret;
> > +		buffer_len -= ret;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
Burakov, Anatoly March 27, 2019, 2:23 p.m. | #3
On 21-Mar-19 10:55 AM, Hajkowski wrote:
> From: Marcin Hajkowski <marcinx.hajkowski@intel.com>
> 
> Added new experimental API rte_power_guest_channel_receive_msg
> which gives possibility to receive messages send to guest.
> 
> Signed-off-by: Marcin Hajkowski <marcinx.hajkowski@intel.com>
> ---
>   lib/librte_power/channel_commands.h    |  5 ++
>   lib/librte_power/guest_channel.c       | 65 ++++++++++++++++++++++++++
>   lib/librte_power/guest_channel.h       | 35 ++++++++++++++
>   lib/librte_power/rte_power_version.map |  1 +
>   4 files changed, 106 insertions(+)
> 
> diff --git a/lib/librte_power/channel_commands.h b/lib/librte_power/channel_commands.h
> index e7b93a797..33fd53a6d 100644
> --- a/lib/librte_power/channel_commands.h
> +++ b/lib/librte_power/channel_commands.h
> @@ -28,6 +28,11 @@ extern "C" {
>   #define CPU_POWER_SCALE_MIN     4
>   #define CPU_POWER_ENABLE_TURBO  5
>   #define CPU_POWER_DISABLE_TURBO 6
> +
> +/* Generic Power Command Response */
> +#define CPU_POWER_CMD_ACK       1
> +#define CPU_POWER_CMD_NACK      2
> +
>   #define HOURS 24
>   
>   #define MAX_VFS 10
> diff --git a/lib/librte_power/guest_channel.c b/lib/librte_power/guest_channel.c
> index 9cf7d2cb2..3213fa769 100644
> --- a/lib/librte_power/guest_channel.c
> +++ b/lib/librte_power/guest_channel.c
> @@ -10,6 +10,7 @@
>   #include <fcntl.h>
>   #include <string.h>
>   #include <errno.h>
> +#include <poll.h>
>   
>   
>   #include <rte_log.h>
> @@ -19,6 +20,9 @@
>   
>   #define RTE_LOGTYPE_GUEST_CHANNEL RTE_LOGTYPE_USER1
>   
> +/* Timeout for incoming message in milliseconds. */
> +#define TIMEOUT 10
> +
>   static int global_fds[RTE_MAX_LCORE] = { [0 ... RTE_MAX_LCORE-1] = -1 };
>   
>   int
> @@ -125,6 +129,67 @@ int rte_power_guest_channel_send_msg(struct channel_packet *pkt,
>   	return guest_channel_send_msg(pkt, lcore_id);
>   }
>   
> +int power_guest_channel_read_msg(struct channel_packet *pkt,
> +			unsigned int lcore_id)
> +{
> +	int ret;
> +
> +	struct pollfd fds;

Nitpick, but we generally prefer having a newline after definitions.

> +	fds.fd = global_fds[lcore_id];
> +	fds.events = POLLIN;
> +
> +	ret = poll(&fds, 1, TIMEOUT);
> +	if (ret == 0) {
> +		RTE_LOG(DEBUG, GUEST_CHANNEL, "Timeout occurs during poll function.\n");

Occurred?

> +		return -1;
> +	} else if (ret < 0) {
> +		RTE_LOG(ERR, GUEST_CHANNEL, "Error occurred during poll function: %s\n",
> +				strerror(ret));
> +		return -1;
> +	}
> +
> +	void *buffer = pkt;

Declarations have to be in the beginning of the function.

> +
> +	if (lcore_id >= RTE_MAX_LCORE) {
> +		RTE_LOG(ERR, GUEST_CHANNEL, "Channel(%u) is out of range 0...%d\n",
> +				lcore_id, RTE_MAX_LCORE-1);
> +		return -1;
> +	}
> +
> +	if (global_fds[lcore_id] < 0) {
> +		RTE_LOG(ERR, GUEST_CHANNEL, "Channel is not connected\n");
> +		return -1;
> +	}
> +
> +	int buffer_len = sizeof(*pkt);

Same, declarations on top.

> +
> +	while (buffer_len > 0) {
> +		ret = read(global_fds[lcore_id],
> +				buffer, buffer_len);
> +		if (ret < 0) {
> +			if (errno == EINTR)
> +				continue;
> +			return -1;
> +		}
> +		/* No data has been read, this can indicate not
> +		 * consistent buffer_len with actual data size.
> +		 */
> +		if (ret == 0) {
> +			RTE_LOG(ERR, GUEST_CHANNEL, "No more data has been read.\n");
> +			return -1;
> +		}

If i remember correctly, this cannot happen with a blocking fifo read 
unless the fifo was closed either by us or by the other end. Perhaps the 
error message should be reworded to reflect that? E.g. something like 
"Expected more data, but fifo is closed"?

Patch

diff --git a/lib/librte_power/channel_commands.h b/lib/librte_power/channel_commands.h
index e7b93a797..33fd53a6d 100644
--- a/lib/librte_power/channel_commands.h
+++ b/lib/librte_power/channel_commands.h
@@ -28,6 +28,11 @@  extern "C" {
 #define CPU_POWER_SCALE_MIN     4
 #define CPU_POWER_ENABLE_TURBO  5
 #define CPU_POWER_DISABLE_TURBO 6
+
+/* Generic Power Command Response */
+#define CPU_POWER_CMD_ACK       1
+#define CPU_POWER_CMD_NACK      2
+
 #define HOURS 24
 
 #define MAX_VFS 10
diff --git a/lib/librte_power/guest_channel.c b/lib/librte_power/guest_channel.c
index 9cf7d2cb2..3213fa769 100644
--- a/lib/librte_power/guest_channel.c
+++ b/lib/librte_power/guest_channel.c
@@ -10,6 +10,7 @@ 
 #include <fcntl.h>
 #include <string.h>
 #include <errno.h>
+#include <poll.h>
 
 
 #include <rte_log.h>
@@ -19,6 +20,9 @@ 
 
 #define RTE_LOGTYPE_GUEST_CHANNEL RTE_LOGTYPE_USER1
 
+/* Timeout for incoming message in milliseconds. */
+#define TIMEOUT 10
+
 static int global_fds[RTE_MAX_LCORE] = { [0 ... RTE_MAX_LCORE-1] = -1 };
 
 int
@@ -125,6 +129,67 @@  int rte_power_guest_channel_send_msg(struct channel_packet *pkt,
 	return guest_channel_send_msg(pkt, lcore_id);
 }
 
+int power_guest_channel_read_msg(struct channel_packet *pkt,
+			unsigned int lcore_id)
+{
+	int ret;
+
+	struct pollfd fds;
+	fds.fd = global_fds[lcore_id];
+	fds.events = POLLIN;
+
+	ret = poll(&fds, 1, TIMEOUT);
+	if (ret == 0) {
+		RTE_LOG(DEBUG, GUEST_CHANNEL, "Timeout occurs during poll function.\n");
+		return -1;
+	} else if (ret < 0) {
+		RTE_LOG(ERR, GUEST_CHANNEL, "Error occurred during poll function: %s\n",
+				strerror(ret));
+		return -1;
+	}
+
+	void *buffer = pkt;
+
+	if (lcore_id >= RTE_MAX_LCORE) {
+		RTE_LOG(ERR, GUEST_CHANNEL, "Channel(%u) is out of range 0...%d\n",
+				lcore_id, RTE_MAX_LCORE-1);
+		return -1;
+	}
+
+	if (global_fds[lcore_id] < 0) {
+		RTE_LOG(ERR, GUEST_CHANNEL, "Channel is not connected\n");
+		return -1;
+	}
+
+	int buffer_len = sizeof(*pkt);
+
+	while (buffer_len > 0) {
+		ret = read(global_fds[lcore_id],
+				buffer, buffer_len);
+		if (ret < 0) {
+			if (errno == EINTR)
+				continue;
+			return -1;
+		}
+		/* No data has been read, this can indicate not
+		 * consistent buffer_len with actual data size.
+		 */
+		if (ret == 0) {
+			RTE_LOG(ERR, GUEST_CHANNEL, "No more data has been read.\n");
+			return -1;
+		}
+		buffer = (char *)buffer + ret;
+		buffer_len -= ret;
+	}
+
+	return 0;
+}
+
+int rte_power_guest_channel_receive_msg(struct channel_packet *pkt,
+			unsigned int lcore_id)
+{
+	return power_guest_channel_read_msg(pkt, lcore_id);
+}
 
 void
 guest_channel_host_disconnect(unsigned int lcore_id)
diff --git a/lib/librte_power/guest_channel.h b/lib/librte_power/guest_channel.h
index 373d39898..7c385df39 100644
--- a/lib/librte_power/guest_channel.h
+++ b/lib/librte_power/guest_channel.h
@@ -68,6 +68,41 @@  int guest_channel_send_msg(struct channel_packet *pkt, unsigned int lcore_id);
 int rte_power_guest_channel_send_msg(struct channel_packet *pkt,
 			unsigned int lcore_id);
 
+/**
+ * Read a message contained in pkt over the Virtio-Serial
+ * from the host endpoint.
+ *
+ * @param pkt
+ *  Pointer to a populated struct channel_packet
+ *
+ * @param lcore_id
+ *  lcore_id.
+ *
+ * @return
+ *  - 0 on success.
+ *  - Negative on error.
+ */
+int power_guest_channel_read_msg(struct channel_packet *pkt,
+		unsigned int lcore_id);
+
+/**
+ * Receive a message contained in pkt over the Virtio-Serial
+ * from the host endpoint.
+ *
+ * @param pkt
+ *  Pointer to a populated struct channel_packet
+ *
+ * @param lcore_id
+ *  lcore_id.
+ *
+ * @return
+ *  - 0 on success.
+ *  - Negative on error.
+ */
+int __rte_experimental
+rte_power_guest_channel_receive_msg(struct channel_packet *pkt,
+			unsigned int lcore_id);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_power/rte_power_version.map b/lib/librte_power/rte_power_version.map
index 042917360..69f5ea3f4 100644
--- a/lib/librte_power/rte_power_version.map
+++ b/lib/librte_power/rte_power_version.map
@@ -44,4 +44,5 @@  EXPERIMENTAL {
 	rte_power_empty_poll_stat_update;
 	rte_power_poll_stat_fetch;
 	rte_power_poll_stat_update;
+	rte_power_guest_channel_receive_msg;
 };