splice at OMAP3530

Hi All,

I'm trying to get the following program to run. It should copy one file using DMA (with splice).

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <asm/page.h>
#include <asm/unistd.h>

// defines from linux/pipe_fs_i.h
#define SPLICE_F_MOVE (0x01) /* move pages instead of copying */
#define SPLICE_F_MORE (0x04) /* expect more data */
#define PIPE_BUFFERS (16)

#define SPLICE_BUF_SIZE (PIPE_BUFFERS*PAGE_SIZE)

#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))

static inline int sys_splice(int fdin, loff_t *off_in,
    int fdout, loff_t *off_out, size_t len, unsigned int flags)
{
    return syscall( __NR_splice,fdin,off_in, fdout,off_out,len,flags );
}

int main( int argc, char **argv )
{
    int fd_in, fd_out, ret;
    int fd_pipe[2];
    int bytes_to_copy, bytes_copied;
    unsigned long bytes_left;
    struct stat stat_buf;

    if( argc != 3 ) {
        fprintf(stderr,"usage: %s from ton", argv[0] );
        return -1;
    }
    fd_in = open( argv[1], O_RDONLY );
    if( fd_in < 0 ) {
        perror( argv[1] );
        return -1;
    }
    fd_out = open( argv[2], O_WRONLY|O_CREAT, 0644 );
    if( fd_out < 0 ) {
        perror( argv[2] );
        return -1;
    }
    if( pipe(fd_pipe) < 0 ) {
        close( fd_out );
        close( fd_in );
        return -1;
    }
    fstat( fd_in, &stat_buf );
    bytes_left = stat_buf.st_size;

    while( bytes_left ) {
        bytes_to_copy = bytes_left <SPLICE_BUF_SIZE ?
            bytes_left:SPLICE_BUF_SIZE;
        bytes_copied=sys_splice( fd_in, NULL, fd_pipe[1],NULL,
            bytes_to_copy, SPLICE_F_MOVE|SPLICE_F_MORE );
        if( bytes_copied==-1 ) {
            perror( "splice read" );
            return -1;
        }
        bytes_left -= bytes_copied;
        while( bytes_copied ) {
            ret=sys_splice( fd_pipe[0], NULL, fd_out, NULL,
                bytes_copied, SPLICE_F_MOVE|SPLICE_F_MORE );
            if( ret==-1 ) {
                perror( "splice write" );
                return -1;
            }
            bytes_copied -= ret;
        }
    }
    close( fd_out );
    close( fd_in );
    close( fd_pipe[0] );
    close( fd_pipe[1] );
    return 0;
}

I have no problem compiling the code. But when I execute the programm, I get the error message "splice read: Invalid argument".
Does anyone know how I convice "splice" to work at my OMAP3530.

Thanks Tino.

[...]

       bytes_copied=sys_splice( fd_in, NULL, fd_pipe[1],NULL,
           bytes_to_copy, SPLICE_F_MOVE|SPLICE_F_MORE );
       if( bytes_copied==-1 ) {
           perror( "splice read" );
           return -1;
       }
       bytes_left -= bytes_copied;
       while( bytes_copied ) {
           ret=sys_splice( fd_pipe[0], NULL, fd_out, NULL,
               bytes_copied, SPLICE_F_MOVE|SPLICE_F_MORE );

I don't know anything about the splice syscalls, but it certainly
looks strange that both the buffer pointers are NULL in both calls
to sys_splice.

Look at the example here:

HTH,

Laurent

Hi All,

I'm trying to get the following program to run. It should copy one file using DMA (with splice).

<code snipped>

I have no problem compiling the code. But when I execute the programm, I get the error message "splice read: Invalid argument".
Does anyone know how I convice "splice" to work at my OMAP3530.

Thanks Tino.

I've just copied your code as-is and compiled it, running on kernel
2.6.27.rc7-omap1 (latest Angstrom) it ran fine - duplicated the file
with no errors.

I just tested it on the 2.6.22.18-omap3 kernel that I downloaded from
the Beagle Board Diagnostic Tests and it works fine on there too.

If you want to test my compiled version it can be downloaded here
http://paeryn.myby.co.uk/test_splice.bz2

Darius.