public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* vmsplice complains bad address
@ 2006-08-25 15:11 Yi Yang
  2006-08-25 17:14 ` Jens Axboe
  0 siblings, 1 reply; 2+ messages in thread
From: Yi Yang @ 2006-08-25 15:11 UTC (permalink / raw)
  To: axboe; +Cc: linux-kernel

Hi, Jens

When I tested vmsplice syscall, it always complains bad address, I don't
understand why, does vmsplice have a special reqiurement for address
alignment?

The following file is a test program which is extracted from your patch
and modified in order to adapt to the latest interface. its output is:

getpagesize = 4096
page size: 4096 bytes
vmsplice: Bad address
here: len = 4096, written = -1


/*
* Use vmsplice to fill some user memory into a pipe. vmsplice writes
* to stdout, so that must be a pipe.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/poll.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>
#include <error.h>
#include <errno.h>

//#include "splice.h"
#if defined(__i386__)
#define __NR_splice 313
#define __NR_tee 315
#define __NR_vmsplice 316
#elif defined(__x86_64__)
#define __NR_splice 275
#define __NR_tee 276
#define __NR_vmsplice 277
#elif defined(__powerpc__) || defined(__powerpc64__)
#define __NR_splice 283
#define __NR_tee 284
#define __NR_vmsplice 285
#else
#error unsupported arch
#endif

#define SPLICE_SIZE 4096
#ifndef F_SETPSZ
#define F_SETPSZ 15 /* for pipes. */
#define F_GETPSZ 16 /* for pipes. */
#endif

#define ALIGN_BUF

#ifdef ALIGN_BUF
#define ALIGN_MASK (65535) /* 64k-1, should just be PAGE_SIZE - 1 */
#define ALIGN(buf) (void *) (((unsigned long) (buf) + ALIGN_MASK) &
~ALIGN_MASK)
#else
#define ALIGN_MASK (0)
#define ALIGN(buf) (buf)
#endif

#define min(a,b) (((a)>(b))?(b):(a))

static inline int xerror(const char * str)
{
int err = errno;
perror(str);
return err;
}

static inline long vmsplice(int fd, const struct iovec *iov,
unsigned long nr_segs, unsigned int flags)
{
return syscall(__NR_vmsplice, fd, iov, nr_segs, flags);
}

int do_vmsplice(int fd, void *buffer, int len)
{
struct pollfd pfd = { .fd = fd, .events = POLLOUT, };
int written;
struct iovec v;

v.iov_base = buffer;
v.iov_len = len;

while (len) {
/*
* in a real app you'd be more clever with poll of course,
* here we are basically just blocking on output room and
* not using the free time for anything interesting.
*/
if (poll(&pfd, 1, -1) < 0)
return xerror("poll");

written = vmsplice(fd, &v, 1, 0);
printf("here: len = %d, written = %d\n", len, written);

if (written <= 0)
return xerror("vmsplice");
printf("dajdsajkdskj\n");
fprintf(stderr, "written len = %d\n", written);

len -= written;
}

return 0;
}

int main(int argc, char *argv[])
{
unsigned char *buffer;
struct stat sb;
long page_size;
int i, ret;

if (fstat(STDOUT_FILENO, &sb) < 0)
return xerror("stat");
if (!S_ISFIFO(sb.st_mode)) {
fprintf(stderr, "stdout must be a pipe\n");
return 1;
}

page_size = sysconf(_SC_PAGESIZE);
if (page_size < 0)
return xerror("_SC_PAGESIZE");

fprintf(stderr, "getpagesize = %d\n", getpagesize());
fprintf(stderr, "page size: %d bytes\n", page_size);

buffer = malloc(2 * 65536);
buffer[0]='A';
for (i = 1; i < 2 * SPLICE_SIZE; i++)
buffer[i] = (i & 0xff);

do {
/*
* vmsplice the first half of the buffer into the pipe
*/
if (do_vmsplice(STDOUT_FILENO, buffer, SPLICE_SIZE))
break;

/*
* first half is now in pipe, but we don't quite know when
* we can reuse it.
*/

/*
* vmsplice second half
*/
//if (do_vmsplice(STDOUT_FILENO, buffer + SPLICE_SIZE, SPLICE_SIZE))
// break;

/*
* We still don't know when we can reuse the second half of
* the buffer, but we do now know that all parts of the first
* half have been consumed from the pipe - so we can reuse that.
*/
} while (0);

free(buffer);

return 0;
}

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: vmsplice complains bad address
  2006-08-25 15:11 vmsplice complains bad address Yi Yang
@ 2006-08-25 17:14 ` Jens Axboe
  0 siblings, 0 replies; 2+ messages in thread
From: Jens Axboe @ 2006-08-25 17:14 UTC (permalink / raw)
  To: Yi Yang; +Cc: linux-kernel

On Fri, Aug 25 2006, Yi Yang wrote:
> Hi, Jens
> 
> When I tested vmsplice syscall, it always complains bad address, I don't
> understand why, does vmsplice have a special reqiurement for address
> alignment?
> 
> The following file is a test program which is extracted from your patch
> and modified in order to adapt to the latest interface. its output is:
> 
> getpagesize = 4096
> page size: 4096 bytes
> vmsplice: Bad address
> here: len = 4096, written = -1

First of all, please send code that is actually readable (eg indent it
and if your mailer writes lines (which it does), then attach it instead
of inlining).

What arch are you testing on? If x86-64, you have an error:

> //#include "splice.h"
> #if defined(__i386__)
> #define __NR_splice 313
> #define __NR_tee 315
> #define __NR_vmsplice 316
> #elif defined(__x86_64__)
> #define __NR_splice 275
> #define __NR_tee 276
> #define __NR_vmsplice 277

vmsplice is 278

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2006-08-25 17:12 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-25 15:11 vmsplice complains bad address Yi Yang
2006-08-25 17:14 ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox