2006-10-30 17:34:39

by Daniel Drake

[permalink] [raw]
Subject: splice blocks indefinitely when len > 64k?

Hi,

I'm experimenting with splice and have run into some unusual behaviour.

I am using the utilities in git://brick.kernel.dk/data/git/splice.git

In splice.h, when changing SPLICE_SIZE from:

#define SPLICE_SIZE (64*1024)

to

#define SPLICE_SIZE ((64*1024)+1)

splice-cp hangs indefinitely when copying files sized 65537 bytes or
more. It hangs on the first splice() call.

Is this a bug? I'd like to be able to copy much more than 64kb on a
single splice call.

Thanks!
Daniel



2006-10-30 19:11:18

by Phillip Susi

[permalink] [raw]
Subject: Re: splice blocks indefinitely when len > 64k?

While it should not simply hang, the splice size needs to be an even
multiple of the page size.

Daniel Drake wrote:
> Hi,
>
> I'm experimenting with splice and have run into some unusual behaviour.
>
> I am using the utilities in git://brick.kernel.dk/data/git/splice.git
>
> In splice.h, when changing SPLICE_SIZE from:
>
> #define SPLICE_SIZE (64*1024)
>
> to
>
> #define SPLICE_SIZE ((64*1024)+1)
>
> splice-cp hangs indefinitely when copying files sized 65537 bytes or
> more. It hangs on the first splice() call.
>
> Is this a bug? I'd like to be able to copy much more than 64kb on a
> single splice call.
>
> Thanks!
> Daniel

2006-10-30 19:33:25

by Daniel Drake

[permalink] [raw]
Subject: Re: splice blocks indefinitely when len > 64k?

On Mon, 2006-10-30 at 14:11 -0500, Phillip Susi wrote:
> While it should not simply hang, the splice size needs to be an even
> multiple of the page size.

I don't think that is true, at least on this level. Firstly, splice-cp
does this:

#define BS SPLICE_SIZE
int this_len = min((off_t) BS, sb.st_size);
int ret = splice(in_fd, NULL, pfds[1], NULL, this_len, 0);

No considerations are made regarding page size.

Secondly, the problem still exists when I increase SPLICE_SIZE to
(128*1024)

Daniel

> Daniel Drake wrote:
> > Hi,
> >
> > I'm experimenting with splice and have run into some unusual behaviour.
> >
> > I am using the utilities in git://brick.kernel.dk/data/git/splice.git
> >
> > In splice.h, when changing SPLICE_SIZE from:
> >
> > #define SPLICE_SIZE (64*1024)
> >
> > to
> >
> > #define SPLICE_SIZE ((64*1024)+1)
> >
> > splice-cp hangs indefinitely when copying files sized 65537 bytes or
> > more. It hangs on the first splice() call.
> >
> > Is this a bug? I'd like to be able to copy much more than 64kb on a
> > single splice call.
> >
> > Thanks!
> > Daniel
>

2006-10-30 19:52:51

by Jens Axboe

[permalink] [raw]
Subject: Re: splice blocks indefinitely when len > 64k?

On Mon, Oct 30 2006, Daniel Drake wrote:
> Hi,
>
> I'm experimenting with splice and have run into some unusual behaviour.
>
> I am using the utilities in git://brick.kernel.dk/data/git/splice.git
>
> In splice.h, when changing SPLICE_SIZE from:
>
> #define SPLICE_SIZE (64*1024)
>
> to
>
> #define SPLICE_SIZE ((64*1024)+1)
>
> splice-cp hangs indefinitely when copying files sized 65537 bytes or
> more. It hangs on the first splice() call.
>
> Is this a bug? I'd like to be able to copy much more than 64kb on a
> single splice call.

You can't, internally splice is using a pipe which is currently confined
to 16 pages. The SPLICE_SIZE define isn't a suggestion in the code, it
reflects that. You could fix splice-cp to not stall on changing that,
however that still doesn't change the fact that you can only move chunks
of 64kb (on your arch) right now.

--
Jens Axboe

2006-10-30 19:53:34

by Jens Axboe

[permalink] [raw]
Subject: Re: splice blocks indefinitely when len > 64k?


Don't top post, please.

On Mon, Oct 30 2006, Phillip Susi wrote:
> While it should not simply hang, the splice size needs to be an even
> multiple of the page size.

No, that is incorrect.

--
Jens Axboe

2006-10-30 21:08:46

by Stephen Hemminger

[permalink] [raw]
Subject: Re: splice blocks indefinitely when len > 64k?

On Mon, 30 Oct 2006 20:54:27 +0100
Jens Axboe <[email protected]> wrote:

> On Mon, Oct 30 2006, Daniel Drake wrote:
> > Hi,
> >
> > I'm experimenting with splice and have run into some unusual behaviour.
> >
> > I am using the utilities in git://brick.kernel.dk/data/git/splice.git
> >
> > In splice.h, when changing SPLICE_SIZE from:
> >
> > #define SPLICE_SIZE (64*1024)
> >
> > to
> >
> > #define SPLICE_SIZE ((64*1024)+1)
> >
> > splice-cp hangs indefinitely when copying files sized 65537 bytes or
> > more. It hangs on the first splice() call.
> >
> > Is this a bug? I'd like to be able to copy much more than 64kb on a
> > single splice call.
>
> You can't, internally splice is using a pipe which is currently confined
> to 16 pages. The SPLICE_SIZE define isn't a suggestion in the code, it
> reflects that. You could fix splice-cp to not stall on changing that,
> however that still doesn't change the fact that you can only move chunks
> of 64kb (on your arch) right now.
>

It could accept larger values but only move SPLICE_SIZE, assuming
caller checked for partial completions.

--
Stephen Hemminger <[email protected]>

2006-10-31 07:25:43

by Jens Axboe

[permalink] [raw]
Subject: Re: splice blocks indefinitely when len > 64k?

On Mon, Oct 30 2006, Stephen Hemminger wrote:
> On Mon, 30 Oct 2006 20:54:27 +0100
> Jens Axboe <[email protected]> wrote:
>
> > On Mon, Oct 30 2006, Daniel Drake wrote:
> > > Hi,
> > >
> > > I'm experimenting with splice and have run into some unusual behaviour.
> > >
> > > I am using the utilities in git://brick.kernel.dk/data/git/splice.git
> > >
> > > In splice.h, when changing SPLICE_SIZE from:
> > >
> > > #define SPLICE_SIZE (64*1024)
> > >
> > > to
> > >
> > > #define SPLICE_SIZE ((64*1024)+1)
> > >
> > > splice-cp hangs indefinitely when copying files sized 65537 bytes or
> > > more. It hangs on the first splice() call.
> > >
> > > Is this a bug? I'd like to be able to copy much more than 64kb on a
> > > single splice call.
> >
> > You can't, internally splice is using a pipe which is currently confined
> > to 16 pages. The SPLICE_SIZE define isn't a suggestion in the code, it
> > reflects that. You could fix splice-cp to not stall on changing that,
> > however that still doesn't change the fact that you can only move chunks
> > of 64kb (on your arch) right now.
> >
>
> It could accept larger values but only move SPLICE_SIZE, assuming
> caller checked for partial completions.

(one more time, for the list)

The caller has to check for partial completions, it would be like
calling read(2) or write(2) and not checking the return value if you
didn't. SPLICE_SIZE is the _maximum_ amount of data that current fits in
a pipe, there's no way to ensure that you will actually be able to write
that amount - the pipe may not be empty when you begin writing, or
someone else could be filling it as well.

The initial mail said that splice-cp doesn't work when you change the
SPLICE_SIZE define, and I'm not at all surprised that this is the case.
That would be like saying program foo doesn't work when you randomly
change some define or variable in the source.

--
Jens Axboe