[5/9] Handle vmsplice failure for read mode pre-dump

Submitted by Abhishek Dubey on Sept. 22, 2019, 4:24 a.m.

Details

Message ID 1569126298-23300-6-git-send-email-dubeyabhishek777@gmail.com
State New
Series "Series without cover letter"
Headers show

Commit Message

Abhishek Dubey Sept. 22, 2019, 4:24 a.m.
vmsplice fails to completely splice 2^k pages
from user-buffer to ppb pipes. Sometimes last
page is partially spliced.
To overcome this, page count for splicing is
kept 1 less than the size of pipe.

Signed-off-by: Abhishek Dubey <dubeyabhishek777@gmail.com>
---
 criu/page-pipe.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Patch hide | download patch | download mbox

diff --git a/criu/page-pipe.c b/criu/page-pipe.c
index a821696..e60dd85 100644
--- a/criu/page-pipe.c
+++ b/criu/page-pipe.c
@@ -40,6 +40,22 @@  static int __ppb_resize_pipe(struct page_pipe_buf *ppb, unsigned long new_size)
 	ret /= PAGE_SIZE;
 	BUG_ON(ret < ppb->pipe_size);
 
+	/*
+	 * TODO: Investigate and handle
+	 * Sometimes vmsplice fails to splice N pages(where N=2^k)
+	 * from user buffer to pipe, so restricting page-pipe
+	 * capacity to accommodate N-1 pages.
+	 * e.g. Pipe size can be 512 pages, but it's filled till
+	 * 511 pages.
+	 *
+	 * Steps to reproduce issue:
+	 * 1. Comment-out next two lines following this comment
+	 * 2. Run maps007/maps004 from transitive tests with
+	 *    --pre-dump-mode=read option
+	 */
+	if (opts.pre_dump_mode == PRE_DUMP_READ)
+		ret -= 1;
+
 	pr_debug("Grow pipe %x -> %x\n", ppb->pipe_size, ret);
 	ppb->pipe_size = ret;
 

Comments

Andrei Vagin Sept. 25, 2019, 4:27 p.m.
On Sun, Sep 22, 2019 at 09:54:54AM +0530, Abhishek Dubey wrote:
> vmsplice fails to completely splice 2^k pages
> from user-buffer to ppb pipes. Sometimes last
> page is partially spliced.
> To overcome this, page count for splicing is
> kept 1 less than the size of pipe.
> 
> Signed-off-by: Abhishek Dubey <dubeyabhishek777@gmail.com>
> ---
>  criu/page-pipe.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
> 
> diff --git a/criu/page-pipe.c b/criu/page-pipe.c
> index a821696..e60dd85 100644
> --- a/criu/page-pipe.c
> +++ b/criu/page-pipe.c
> @@ -40,6 +40,22 @@ static int __ppb_resize_pipe(struct page_pipe_buf *ppb, unsigned long new_size)
>  	ret /= PAGE_SIZE;
>  	BUG_ON(ret < ppb->pipe_size);
>  
> +	/*
> +	 * TODO: Investigate and handle
> +	 * Sometimes vmsplice fails to splice N pages(where N=2^k)
> +	 * from user buffer to pipe, so restricting page-pipe
> +	 * capacity to accommodate N-1 pages.
> +	 * e.g. Pipe size can be 512 pages, but it's filled till
> +	 * 511 pages.
> +	 *
> +	 * Steps to reproduce issue:
> +	 * 1. Comment-out next two lines following this comment
> +	 * 2. Run maps007/maps004 from transitive tests with
> +	 *    --pre-dump-mode=read option
> +	 */
> +	if (opts.pre_dump_mode == PRE_DUMP_READ)
> +		ret -= 1;

This doesn't look nice...

> +
>  	pr_debug("Grow pipe %x -> %x\n", ppb->pipe_size, ret);
>  	ppb->pipe_size = ret;
>  
> -- 
> 2.7.4
>
Abhishek Dubey Sept. 27, 2019, 9:44 a.m.
Yes, this is something for which I had no clue. So I fixed it with minor 
hack by writing 1 page less to pipe.

Fixing it will require deep debugging.

On 25/09/19 9:57 PM, Andrei Vagin wrote:
> On Sun, Sep 22, 2019 at 09:54:54AM +0530, Abhishek Dubey wrote:
>> vmsplice fails to completely splice 2^k pages
>> from user-buffer to ppb pipes. Sometimes last
>> page is partially spliced.
>> To overcome this, page count for splicing is
>> kept 1 less than the size of pipe.
>>
>> Signed-off-by: Abhishek Dubey <dubeyabhishek777@gmail.com>
>> ---
>>   criu/page-pipe.c | 16 ++++++++++++++++
>>   1 file changed, 16 insertions(+)
>>
>> diff --git a/criu/page-pipe.c b/criu/page-pipe.c
>> index a821696..e60dd85 100644
>> --- a/criu/page-pipe.c
>> +++ b/criu/page-pipe.c
>> @@ -40,6 +40,22 @@ static int __ppb_resize_pipe(struct page_pipe_buf *ppb, unsigned long new_size)
>>   	ret /= PAGE_SIZE;
>>   	BUG_ON(ret < ppb->pipe_size);
>>   
>> +	/*
>> +	 * TODO: Investigate and handle
>> +	 * Sometimes vmsplice fails to splice N pages(where N=2^k)
>> +	 * from user buffer to pipe, so restricting page-pipe
>> +	 * capacity to accommodate N-1 pages.
>> +	 * e.g. Pipe size can be 512 pages, but it's filled till
>> +	 * 511 pages.
>> +	 *
>> +	 * Steps to reproduce issue:
>> +	 * 1. Comment-out next two lines following this comment
>> +	 * 2. Run maps007/maps004 from transitive tests with
>> +	 *    --pre-dump-mode=read option
>> +	 */
>> +	if (opts.pre_dump_mode == PRE_DUMP_READ)
>> +		ret -= 1;
> This doesn't look nice...
>
>> +
>>   	pr_debug("Grow pipe %x -> %x\n", ppb->pipe_size, ret);
>>   	ppb->pipe_size = ret;
>>   
>> -- 
>> 2.7.4
>>