[4/5] page-server: Split the code doing async page-read

Submitted by Pavel Emelianov on June 14, 2017, 10:15 a.m.

Details

Message ID 640aa6e1-39c4-21a8-9095-988a30848a9b@virtuozzo.com
State New
Series "Unify sync and async page-server read code"
Headers show

Commit Message

Pavel Emelianov June 14, 2017, 10:15 a.m.
This is re-requisite for the next patch.

Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
---
 criu/page-xfer.c | 45 +++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/page-xfer.c b/criu/page-xfer.c
index dd1c6d0..b4979aa 100644
--- a/criu/page-xfer.c
+++ b/criu/page-xfer.c
@@ -1072,6 +1072,16 @@  struct ps_async_read {
 
 static LIST_HEAD(async_reads);
 
+static void init_ps_async_read(struct ps_async_read *ar, void *buf,
+		int nr_pages, ps_async_read_complete complete, void *priv)
+{
+	ar->pages = buf;
+	ar->rb = 0;
+	ar->goal = sizeof(ar->pi) + nr_pages * PAGE_SIZE;
+	ar->complete = complete;
+	ar->priv = priv;
+}
+
 static int page_server_start_async_read(void *buf, int nr_pages,
 		ps_async_read_complete complete, void *priv)
 {
@@ -1081,12 +1091,7 @@  static int page_server_start_async_read(void *buf, int nr_pages,
 	if (ar == NULL)
 		return -1;
 
-	ar->pages = buf;
-	ar->rb = 0;
-	ar->goal = sizeof(ar->pi) + nr_pages * PAGE_SIZE;
-	ar->complete = complete;
-	ar->priv = priv;
-
+	init_ps_async_read(ar, buf, nr_pages, complete, priv);
 	list_add_tail(&ar->l, &async_reads);
 	return 0;
 }
@@ -1100,15 +1105,11 @@  static int page_server_start_async_read(void *buf, int nr_pages,
  * for sure the next time socket event will occur we'll get page data
  * related to info we've just received
  */
-static int page_server_async_read(struct epoll_rfd *f)
+static int page_server_read(struct ps_async_read *ar, int flags)
 {
-	struct ps_async_read *ar;
 	int ret, need;
 	void *buf;
 
-	BUG_ON(list_empty(&async_reads));
-	ar = list_first_entry(&async_reads, struct ps_async_read, l);
-
 	if (ar->rb < sizeof(ar->pi)) {
 		/* Header */
 		buf = ((void *)&ar->pi) + ar->rb;
@@ -1119,7 +1120,7 @@  static int page_server_async_read(struct epoll_rfd *f)
 		need = ar->goal - ar->rb;
 	}
 
-	ret = recv(page_server_sk, buf, need, MSG_DONTWAIT);
+	ret = recv(page_server_sk, buf, need, flags);
 	if (ret < 0) {
 		pr_perror("Error reading async data from page server");
 		return -1;
@@ -1127,17 +1128,29 @@  static int page_server_async_read(struct epoll_rfd *f)
 
 	ar->rb += ret;
 	if (ar->rb < ar->goal)
-		return 0;
+		return 1;
 
 	/*
 	 * IO complete -- notify the caller and drop the request
 	 */
 	BUG_ON(ar->rb > ar->goal);
-	ret = ar->complete((int)ar->pi.dst_id, (unsigned long)ar->pi.vaddr,
+	return ar->complete((int)ar->pi.dst_id, (unsigned long)ar->pi.vaddr,
 				(int)ar->pi.nr_pages, ar->priv);
+}
 
-	list_del(&ar->l);
-	xfree(ar);
+static int page_server_async_read(struct epoll_rfd *f)
+{
+	struct ps_async_read *ar;
+	int ret;
+
+	BUG_ON(list_empty(&async_reads));
+	ar = list_first_entry(&async_reads, struct ps_async_read, l);
+	ret = page_server_read(ar, MSG_DONTWAIT);
+	if (ret == 0) {
+		list_del(&ar->l);
+		xfree(ar);
+	} else if (ret > 0)
+		ret = 0;
 
 	return ret;
 }

Comments

Mike Rapoport June 14, 2017, 11:56 a.m.
On Wed, Jun 14, 2017 at 01:15:24PM +0300, Pavel Emelyanov wrote:
> This is re-requisite for the next patch.

*pre*-requisite? ;-)
Except that:

> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>

Acked-by: Mike Rapoport <rppt@linux.vnet.ibm.com>

> ---
>  criu/page-xfer.c | 45 +++++++++++++++++++++++++++++----------------
>  1 file changed, 29 insertions(+), 16 deletions(-)
> 
> diff --git a/criu/page-xfer.c b/criu/page-xfer.c
> index dd1c6d0..b4979aa 100644
> --- a/criu/page-xfer.c
> +++ b/criu/page-xfer.c
> @@ -1072,6 +1072,16 @@ struct ps_async_read {
>  
>  static LIST_HEAD(async_reads);
>  
> +static void init_ps_async_read(struct ps_async_read *ar, void *buf,
> +		int nr_pages, ps_async_read_complete complete, void *priv)
> +{
> +	ar->pages = buf;
> +	ar->rb = 0;
> +	ar->goal = sizeof(ar->pi) + nr_pages * PAGE_SIZE;
> +	ar->complete = complete;
> +	ar->priv = priv;
> +}
> +
>  static int page_server_start_async_read(void *buf, int nr_pages,
>  		ps_async_read_complete complete, void *priv)
>  {
> @@ -1081,12 +1091,7 @@ static int page_server_start_async_read(void *buf, int nr_pages,
>  	if (ar == NULL)
>  		return -1;
>  
> -	ar->pages = buf;
> -	ar->rb = 0;
> -	ar->goal = sizeof(ar->pi) + nr_pages * PAGE_SIZE;
> -	ar->complete = complete;
> -	ar->priv = priv;
> -
> +	init_ps_async_read(ar, buf, nr_pages, complete, priv);
>  	list_add_tail(&ar->l, &async_reads);
>  	return 0;
>  }
> @@ -1100,15 +1105,11 @@ static int page_server_start_async_read(void *buf, int nr_pages,
>   * for sure the next time socket event will occur we'll get page data
>   * related to info we've just received
>   */
> -static int page_server_async_read(struct epoll_rfd *f)
> +static int page_server_read(struct ps_async_read *ar, int flags)
>  {
> -	struct ps_async_read *ar;
>  	int ret, need;
>  	void *buf;
>  
> -	BUG_ON(list_empty(&async_reads));
> -	ar = list_first_entry(&async_reads, struct ps_async_read, l);
> -
>  	if (ar->rb < sizeof(ar->pi)) {
>  		/* Header */
>  		buf = ((void *)&ar->pi) + ar->rb;
> @@ -1119,7 +1120,7 @@ static int page_server_async_read(struct epoll_rfd *f)
>  		need = ar->goal - ar->rb;
>  	}
>  
> -	ret = recv(page_server_sk, buf, need, MSG_DONTWAIT);
> +	ret = recv(page_server_sk, buf, need, flags);
>  	if (ret < 0) {
>  		pr_perror("Error reading async data from page server");
>  		return -1;
> @@ -1127,17 +1128,29 @@ static int page_server_async_read(struct epoll_rfd *f)
>  
>  	ar->rb += ret;
>  	if (ar->rb < ar->goal)
> -		return 0;
> +		return 1;
>  
>  	/*
>  	 * IO complete -- notify the caller and drop the request
>  	 */
>  	BUG_ON(ar->rb > ar->goal);
> -	ret = ar->complete((int)ar->pi.dst_id, (unsigned long)ar->pi.vaddr,
> +	return ar->complete((int)ar->pi.dst_id, (unsigned long)ar->pi.vaddr,
>  				(int)ar->pi.nr_pages, ar->priv);
> +}
>  
> -	list_del(&ar->l);
> -	xfree(ar);
> +static int page_server_async_read(struct epoll_rfd *f)
> +{
> +	struct ps_async_read *ar;
> +	int ret;
> +
> +	BUG_ON(list_empty(&async_reads));
> +	ar = list_first_entry(&async_reads, struct ps_async_read, l);
> +	ret = page_server_read(ar, MSG_DONTWAIT);
> +	if (ret == 0) {
> +		list_del(&ar->l);
> +		xfree(ar);
> +	} else if (ret > 0)
> +		ret = 0;
>  
>  	return ret;
>  }
> -- 
> 2.1.4
> 
> _______________________________________________
> CRIU mailing list
> CRIU@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
Mike Rapoport June 14, 2017, 11:59 a.m.
One more comment, sorry.

On Wed, Jun 14, 2017 at 01:15:24PM +0300, Pavel Emelyanov wrote:
> This is re-requisite for the next patch.
> 
> Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
> ---
>  criu/page-xfer.c | 45 +++++++++++++++++++++++++++++----------------
>  1 file changed, 29 insertions(+), 16 deletions(-)
> 
> diff --git a/criu/page-xfer.c b/criu/page-xfer.c
> index dd1c6d0..b4979aa 100644
> --- a/criu/page-xfer.c
> +++ b/criu/page-xfer.c

[ ... ]

> @@ -1127,17 +1128,29 @@ static int page_server_async_read(struct epoll_rfd *f)
>  
>  	ar->rb += ret;
>  	if (ar->rb < ar->goal)
> -		return 0;
> +		return 1;
>  
>  	/*
>  	 * IO complete -- notify the caller and drop the request
>  	 */
>  	BUG_ON(ar->rb > ar->goal);
> -	ret = ar->complete((int)ar->pi.dst_id, (unsigned long)ar->pi.vaddr,
> +	return ar->complete((int)ar->pi.dst_id, (unsigned long)ar->pi.vaddr,
>  				(int)ar->pi.nr_pages, ar->priv);
> +}
>  
> -	list_del(&ar->l);
> -	xfree(ar);
> +static int page_server_async_read(struct epoll_rfd *f)
> +{
> +	struct ps_async_read *ar;
> +	int ret;
> +
> +	BUG_ON(list_empty(&async_reads));
> +	ar = list_first_entry(&async_reads, struct ps_async_read, l);
> +	ret = page_server_read(ar, MSG_DONTWAIT);
> +	if (ret == 0) {
> +		list_del(&ar->l);
> +		xfree(ar);
> +	} else if (ret > 0)
> +		ret = 0;

	if (ret > 0)
		return 0;
	if (!ret) {
		list_del(&ar->l);
		xfree(ar);
	}
  
>  	return ret;
>  }
> -- 
> 2.1.4
> 
> _______________________________________________
> CRIU mailing list
> CRIU@openvz.org
> https://lists.openvz.org/mailman/listinfo/criu