All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yi Yang <yang.y.yi@gmail.com>
To: axboe@suse.de
Cc: linux-kernel@vger.kernel.org
Subject: vmsplice complains bad address
Date: Fri, 25 Aug 2006 23:11:57 +0800	[thread overview]
Message-ID: <44EF133D.8050102@gmail.com> (raw)

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;
}

             reply	other threads:[~2006-08-25 15:11 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-25 15:11 Yi Yang [this message]
2006-08-25 17:14 ` vmsplice complains bad address Jens Axboe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44EF133D.8050102@gmail.com \
    --to=yang.y.yi@gmail.com \
    --cc=axboe@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.