01 Nov, 2011

1 commit

  • The basic idea behind cross memory attach is to allow MPI programs doing
    intra-node communication to do a single copy of the message rather than a
    double copy of the message via shared memory.

    The following patch attempts to achieve this by allowing a destination
    process, given an address and size from a source process, to copy memory
    directly from the source process into its own address space via a system
    call. There is also a symmetrical ability to copy from the current
    process's address space into a destination process's address space.

    - Use of /proc/pid/mem has been considered, but there are issues with
    using it:
    - Does not allow for specifying iovecs for both src and dest, assuming
    preadv or pwritev was implemented either the area read from or
    written to would need to be contiguous.
    - Currently mem_read allows only processes who are currently
    ptrace'ing the target and are still able to ptrace the target to read
    from the target. This check could possibly be moved to the open call,
    but its not clear exactly what race this restriction is stopping
    (reason appears to have been lost)
    - Having to send the fd of /proc/self/mem via SCM_RIGHTS on unix
    domain socket is a bit ugly from a userspace point of view,
    especially when you may have hundreds if not (eventually) thousands
    of processes that all need to do this with each other
    - Doesn't allow for some future use of the interface we would like to
    consider adding in the future (see below)
    - Interestingly reading from /proc/pid/mem currently actually
    involves two copies! (But this could be fixed pretty easily)

    As mentioned previously use of vmsplice instead was considered, but has
    problems. Since you need the reader and writer working co-operatively if
    the pipe is not drained then you block. Which requires some wrapping to
    do non blocking on the send side or polling on the receive. In all to all
    communication it requires ordering otherwise you can deadlock. And in the
    example of many MPI tasks writing to one MPI task vmsplice serialises the
    copying.

    There are some cases of MPI collectives where even a single copy interface
    does not get us the performance gain we could. For example in an
    MPI_Reduce rather than copy the data from the source we would like to
    instead use it directly in a mathops (say the reduce is doing a sum) as
    this would save us doing a copy. We don't need to keep a copy of the data
    from the source. I haven't implemented this, but I think this interface
    could in the future do all this through the use of the flags - eg could
    specify the math operation and type and the kernel rather than just
    copying the data would apply the specified operation between the source
    and destination and store it in the destination.

    Although we don't have a "second user" of the interface (though I've had
    some nibbles from people who may be interested in using it for intra
    process messaging which is not MPI). This interface is something which
    hardware vendors are already doing for their custom drivers to implement
    fast local communication. And so in addition to this being useful for
    OpenMPI it would mean the driver maintainers don't have to fix things up
    when the mm changes.

    There was some discussion about how much faster a true zero copy would
    go. Here's a link back to the email with some testing I did on that:

    http://marc.info/?l=linux-mm&m=130105930902915&w=2

    There is a basic man page for the proposed interface here:

    http://ozlabs.org/~cyeoh/cma/process_vm_readv.txt

    This has been implemented for x86 and powerpc, other architecture should
    mainly (I think) just need to add syscall numbers for the process_vm_readv
    and process_vm_writev. There are 32 bit compatibility versions for
    64-bit kernels.

    For arch maintainers there are some simple tests to be able to quickly
    verify that the syscalls are working correctly here:

    http://ozlabs.org/~cyeoh/cma/cma-test-20110718.tgz

    Signed-off-by: Chris Yeoh
    Cc: Ingo Molnar
    Cc: "H. Peter Anvin"
    Cc: Thomas Gleixner
    Cc: Arnd Bergmann
    Cc: Paul Mackerras
    Cc: Benjamin Herrenschmidt
    Cc: David Howells
    Cc: James Morris
    Cc:
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Christopher Yeoh
     

28 Oct, 2011

2 commits

  • Add a generic_file_llseek variant to the VFS that allows passing in
    the maximum file size of the file system, instead of always
    using maxbytes from the superblock.

    This can be used to eliminate some cut'n'paste seek code in ext4.

    Signed-off-by: Andi Kleen
    Signed-off-by: Christoph Hellwig

    Andi Kleen
     
  • The i_mutex lock use of generic _file_llseek hurts. Independent processes
    accessing the same file synchronize over a single lock, even though
    they have no need for synchronization at all.

    Under high utilization this can cause llseek to scale very poorly on larger
    systems.

    This patch does some rethinking of the llseek locking model:

    First the 64bit f_pos is not necessarily atomic without locks
    on 32bit systems. This can already cause races with read() today.
    This was discussed on linux-kernel in the past and deemed acceptable.
    The patch does not change that.

    Let's look at the different seek variants:

    SEEK_SET: Doesn't really need any locking.
    If there's a race one writer wins, the other loses.

    For 32bit the non atomic update races against read()
    stay the same. Without a lock they can also happen
    against write() now. The read() race was deemed
    acceptable in past discussions, and I think if it's
    ok for read it's ok for write too.

    => Don't need a lock.

    SEEK_END: This behaves like SEEK_SET plus it reads
    the maximum size too. Reading the maximum size would have the
    32bit atomic problem. But luckily we already have a way to read
    the maximum size without locking (i_size_read), so we
    can just use that instead.

    Without i_mutex there is no synchronization with write() anymore,
    however since the write() update is atomic on 64bit it just behaves
    like another racy SEEK_SET. On non atomic 32bit it's the same
    as SEEK_SET.

    => Don't need a lock, but need to use i_size_read()

    SEEK_CUR: This has a read-modify-write race window
    on the same file. One could argue that any application
    doing unsynchronized seeks on the same file is already broken.
    But for the sake of not adding a regression here I'm
    using the file->f_lock to synchronize this. Using this
    lock is much better than the inode mutex because it doesn't
    synchronize between processes.

    => So still need a lock, but can use a f_lock.

    This patch implements this new scheme in generic_file_llseek.
    I dropped generic_file_llseek_unlocked and changed all callers.

    Signed-off-by: Andi Kleen
    Signed-off-by: Christoph Hellwig

    Andi Kleen
     

27 Jul, 2011

1 commit


21 Jul, 2011

1 commit

  • This just gets us ready to support the SEEK_HOLE and SEEK_DATA flags. Turns out
    using fiemap in things like cp cause more problems than it solves, so lets try
    and give userspace an interface that doesn't suck. We need to match solaris
    here, and the definitions are

    *o* If /whence/ is SEEK_HOLE, the offset of the start of the
    next hole greater than or equal to the supplied offset
    is returned. The definition of a hole is provided near
    the end of the DESCRIPTION.

    *o* If /whence/ is SEEK_DATA, the file pointer is set to the
    start of the next non-hole file region greater than or
    equal to the supplied offset.

    So in the generic case the entire file is data and there is a virtual hole at
    the end. That means we will just return i_size for SEEK_HOLE and will return
    the same offset for SEEK_DATA. This is how Solaris does it so we have to do it
    the same way.

    Thanks,

    Signed-off-by: Josef Bacik
    Signed-off-by: Al Viro

    Josef Bacik
     

13 Jan, 2011

1 commit


18 Nov, 2010

1 commit


30 Oct, 2010

1 commit


26 Oct, 2010

1 commit

  • Now, rw_verify_area() checsk f_pos is negative or not. And if negative,
    returns -EINVAL.

    But, some special files as /dev/(k)mem and /proc//mem etc.. has
    negative offsets. And we can't do any access via read/write to the
    file(device).

    So introduce FMODE_UNSIGNED_OFFSET to allow negative file offsets.

    Signed-off-by: Wu Fengguang
    Signed-off-by: KAMEZAWA Hiroyuki
    Cc: Al Viro
    Cc: Heiko Carstens
    Signed-off-by: Andrew Morton
    Signed-off-by: Al Viro

    KAMEZAWA Hiroyuki
     

15 Oct, 2010

2 commits

  • All file operations now have an explicit .llseek
    operation pointer, so we can change the default
    action for future code.

    This makes changes the default from default_llseek
    to no_llseek, which always returns -ESPIPE if
    a user tries to seek on a file without a .llseek
    operation.

    The name of the default_llseek function remains
    unchanged, if anyone thinks we should change it,
    please speak up.

    Signed-off-by: Arnd Bergmann
    Cc: Christoph Hellwig
    Cc: Al Viro
    Cc: linux-fsdevel@vger.kernel.org

    Arnd Bergmann
     
  • There are currently 191 users of default_llseek.
    Nine of these are in device drivers that use the
    big kernel lock. None of these ever touch
    file->f_pos outside of llseek or file_pos_write.

    Consequently, we never rely on the BKL
    in the default_llseek function and can
    replace that with i_mutex, which is also
    used in generic_file_llseek.

    Signed-off-by: Arnd Bergmann

    Arnd Bergmann
     

28 Jul, 2010

1 commit

  • fanotify, the upcoming notification system actually needs a struct path so it can
    do opens in the context of listeners, and it needs a file so it can get f_flags
    from the original process. Close was the only operation that already was passing
    a struct file to the notification hook. This patch passes a file for access,
    modify, and open as well as they are easily available to these hooks.

    Signed-off-by: Eric Paris

    Eric Paris
     

28 May, 2010

1 commit

  • This is an implementation of ->llseek useable for the rare special case
    when userspace expects the seek to succeed but the (device) file is
    actually not able to perform the seek. In this case you use noop_llseek()
    instead of falling back to the default implementation of ->llseek.

    Signed-off-by: Jan Blunck
    Cc: Frederic Weisbecker
    Cc: Christoph Hellwig
    Cc: Al Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    jan Blunck
     

25 Mar, 2010

1 commit


04 Nov, 2009

1 commit

  • sendfile(2) was reworked with the splice infrastructure, but it still
    checks f_op.sendpage() instead of f_op.splice_write() wrongly. Although
    if f_op.sendpage() exists, f_op.splice_write() always exists at the same
    time currently, the assumption will be broken in future silently. This
    patch also brings a side effect: sendfile(2) can work with any output
    file. Some security checks related to f_op are added too.

    Signed-off-by: Changli Gao
    Signed-off-by: Jens Axboe

    Changli Gao
     

24 Sep, 2009

1 commit

  • As Johannes Weiner pointed out, one of the range checks in do_sendfile
    is redundant and is already checked in rw_verify_area.

    Signed-off-by: Jeff Layton
    Reviewed-by: Johannes Weiner
    Cc: Christoph Hellwig
    Cc: Al Viro
    Cc: Robert Love
    Cc: Mandeep Singh Baines
    Signed-off-by: Andrew Morton
    Signed-off-by: Al Viro

    Jeff Layton
     

11 May, 2009

1 commit

  • If f_op->splice_read() is not implemented, fall back to a plain read.
    Use vfs_readv() to read into previously allocated pages.

    This will allow splice and functions using splice, such as the loop
    device, to work on all filesystems. This includes "direct_io" files
    in fuse which bypass the page cache.

    Signed-off-by: Miklos Szeredi
    Signed-off-by: Jens Axboe

    Miklos Szeredi
     

05 Apr, 2009

1 commit

  • Instead of always splitting the file offset into 32-bit 'high' and 'low'
    parts, just split them into the largest natural word-size - which in C
    terms is 'unsigned long'.

    This allows 64-bit architectures to avoid the unnecessary 32-bit
    shifting and masking for native format (while the compat interfaces will
    obviously always have to do it).

    This also changes the order of 'high' and 'low' to be "low first". Why?
    Because when we have it like this, the 64-bit system calls now don't use
    the "pos_high" argument at all, and it makes more sense for the native
    system call to simply match the user-mode prototype.

    This results in a much more natural calling convention, and allows the
    compiler to generate much more straightforward code. On x86-64, we now
    generate

    testq %rcx, %rcx # pos_l
    js .L122 #,
    movq %rcx, -48(%rbp) # pos_l, pos

    from the C source

    loff_t pos = pos_from_hilo(pos_h, pos_l);
    ...
    if (pos < 0)
    return -EINVAL;

    and the 'pos_h' register isn't even touched. It used to generate code
    like

    mov %r8d, %r8d # pos_low, pos_low
    salq $32, %rcx #, tmp71
    movq %r8, %rax # pos_low, pos.386
    orq %rcx, %rax # tmp71, pos.386
    js .L122 #,
    movq %rax, -48(%rbp) # pos.386, pos

    which isn't _that_ horrible, but it does show how the natural word size
    is just a more sensible interface (same arguments will hold in the user
    level glibc wrapper function, of course, so the kernel side is just half
    of the equation!)

    Note: in all cases the user code wrapper can again be the same. You can
    just do

    #define HALF_BITS (sizeof(unsigned long)*4)
    __syscall(PWRITEV, fd, iov, count, offset, (offset >> HALF_BITS) >> HALF_BITS);

    or something like that. That way the user mode wrapper will also be
    nicely passing in a zero (it won't actually have to do the shifts, the
    compiler will understand what is going on) for the last argument.

    And that is a good idea, even if nobody will necessarily ever care: if
    we ever do move to a 128-bit lloff_t, this particular system call might
    be left alone. Of course, that will be the least of our worries if we
    really ever need to care, so this may not be worth really caring about.

    [ Fixed for lost 'loff_t' cast noticed by Andrew Morton ]

    Acked-by: Gerd Hoffmann
    Cc: H. Peter Anvin
    Cc: Andrew Morton
    Cc: linux-api@vger.kernel.org
    Cc: linux-arch@vger.kernel.org
    Cc: Ingo Molnar
    Cc: Ralf Baechle >
    Cc: Al Viro
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

03 Apr, 2009

1 commit

  • This patch adds preadv and pwritev system calls. These syscalls are a
    pretty straightforward combination of pread and readv (same for write).
    They are quite useful for doing vectored I/O in threaded applications.
    Using lseek+readv instead opens race windows you'll have to plug with
    locking.

    Other systems have such system calls too, for example NetBSD, check
    here: http://www.daemon-systems.org/man/preadv.2.html

    The application-visible interface provided by glibc should look like
    this to be compatible to the existing implementations in the *BSD family:

    ssize_t preadv(int d, const struct iovec *iov, int iovcnt, off_t offset);
    ssize_t pwritev(int d, const struct iovec *iov, int iovcnt, off_t offset);

    This prototype has one problem though: On 32bit archs is the (64bit)
    offset argument unaligned, which the syscall ABI of several archs doesn't
    allow to do. At least s390 needs a wrapper in glibc to handle this. As
    we'll need a wrappers in glibc anyway I've decided to push problem to
    glibc entriely and use a syscall prototype which works without
    arch-specific wrappers inside the kernel: The offset argument is
    explicitly splitted into two 32bit values.

    The patch sports the actual system call implementation and the windup in
    the x86 system call tables. Other archs follow as separate patches.

    Signed-off-by: Gerd Hoffmann
    Cc: Arnd Bergmann
    Cc: Al Viro
    Cc:
    Cc:
    Cc: Ralf Baechle
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: "H. Peter Anvin"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Gerd Hoffmann
     

14 Jan, 2009

5 commits


06 Jan, 2009

1 commit

  • This patch fixes a race condition in lseek. While it is expected that
    unpredictable behaviour may result while repositioning the offset of a
    file descriptor concurrently with reading/writing to the same file
    descriptor, this should not happen when merely *reading* the file
    descriptor's offset.

    Unfortunately, the only portable way in Unix to read a file
    descriptor's offset is lseek(fd, 0, SEEK_CUR); however executing this
    concurrently with read/write may mess up the position.

    [with fixes from akpm]

    Signed-off-by: Alain Knaff
    Signed-off-by: Andrew Morton
    Signed-off-by: Al Viro

    Alain Knaff
     

23 Oct, 2008

1 commit


03 Jul, 2008

1 commit

  • - Replace remote_llseek with generic_file_llseek_unlocked (to force compilation
    failures in all users)
    - Change all users to either use generic_file_llseek_unlocked directly or
    take the BKL around. I changed the file systems who don't use the BKL
    for anything (CIFS, GFS) to call it directly. NCPFS and SMBFS and NFS
    take the BKL, but explicitely in their own source now.

    I moved them all over in a single patch to avoid unbisectable sections.

    Open problem: 32bit kernels can corrupt fpos because its modification
    is not atomic, but they can do that anyways because there's other paths who
    modify it without BKL.

    Do we need a special lock for the pos/f_version = 0 checks?

    Trond says the NFS BKL is likely not needed, but keep it for now
    until his full audit.

    v2: Use generic_file_llseek_unlocked instead of remote_llseek_unlocked
    and factor duplicated code (suggested by hch)

    Cc: Trond.Myklebust@netapp.com
    Cc: swhiteho@redhat.com
    Cc: sfrench@samba.org
    Cc: vandrove@vc.cvut.cz

    Signed-off-by: Andi Kleen
    Signed-off-by: Andi Kleen
    Signed-off-by: Jonathan Corbet

    Andi Kleen
     

23 Apr, 2008

1 commit


09 Feb, 2008

1 commit

  • These exports (which aren't used and which are in fact dangerous to use
    because they pretty much form a security hole to use) have been marked
    _UNUSED since 2.6.24 with removal in 2.6.25. This patch is their final
    departure from the Linux kernel tree.

    Signed-off-by: Arjan van de Ven
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Arjan van de Ven
     

29 Jan, 2008

1 commit


25 Jan, 2008

1 commit


15 Nov, 2007

1 commit

  • sys_open / sys_read were used in the early 1.2 days to load firmware from
    disk inside drivers. Since 2.0 or so this was deprecated behavior, but
    several drivers still were using this. Since a few years we have a
    request_firmware() API that implements this in a nice, consistent way.
    Only some old ISA sound drivers (pre-ALSA) still straggled along for some
    time.... however with commit c2b1239a9f22f19c53543b460b24507d0e21ea0c the
    last user is now gone.

    This is a good thing, since using sys_open / sys_read etc for firmware is a
    very buggy to dangerous thing to do; these operations put an fd in the
    process file descriptor table.... which then can be tampered with from
    other threads for example. For those who don't want the firmware loader,
    filp_open()/vfs_read are the better APIs to use, without this security
    issue.

    The patch below marks sys_open and sys_read unused now that they're
    really not used anymore, and for deletion in the 2.6.25 timeframe.

    Signed-off-by: Arjan van de Ven
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Arjan van de Ven
     

10 Oct, 2007

1 commit

  • The combination of S_ISGID bit set and S_IXGRP bit unset is used to mark the
    inode as "mandatory lockable" and there's a macro for this check called
    MANDATORY_LOCK(inode). However, fs/locks.c and some filesystems still perform
    the explicit i_mode checking. Besides, Andrew pointed out, that this macro is
    buggy itself, as it dereferences the inode arg twice.

    Convert this macro into static inline function and switch its users to it,
    making the code shorter and more readable.

    The __mandatory_lock() helper is to be used in places where the IS_MANDLOCK()
    for superblock is already known to be true.

    Signed-off-by: Pavel Emelyanov
    Cc: Trond Myklebust
    Cc: "J. Bruce Fields"
    Cc: David Howells
    Cc: Eric Van Hensbergen
    Cc: Ron Minnich
    Cc: Latchesar Ionkov
    Cc: Steven Whitehouse
    Signed-off-by: Andrew Morton

    Pavel Emelyanov
     

10 Jul, 2007

3 commits


09 May, 2007

2 commits


13 Feb, 2007

1 commit

  • oprofile hunting showed a stall in rw_verify_area(), because of triple
    indirection and potential cache misses.
    (file->f_path.dentry->d_inode->i_flock)

    By moving initialization of 'struct inode' pointer before the pos/count
    sanity tests, we allow the compiler and processor to perform two loads by
    anticipation, reducing stall, without prefetch() hints. Even x86 arch has
    enough registers to not use temporary variables and not increase text size.

    I validated this patch running a bench and studied oprofile changes, and
    absolute perf of the test program.

    Results of my epoll_pipe_bench (source available on request) on a Pentium-M
    1.6 GHz machine

    Before :
    # ./epoll_pipe_bench -l 30 -t 20
    Avg: 436089 evts/sec read_count=8843037 write_count=8843040 21.218390 samples
    per call
    (best value out of 10 runs)

    After :
    # ./epoll_pipe_bench -l 30 -t 20
    Avg: 470980 evts/sec read_count=9549871 write_count=9549894 21.216694 samples
    per call
    (best value out of 10 runs)

    oprofile CPU_CLK_UNHALTED events gave a reduction from 5.3401 % to 2.5851 %
    for the rw_verify_area() function.

    Signed-off-by: Eric Dumazet
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Eric Dumazet
     

12 Feb, 2007

1 commit

  • They are fat: 4x8 bytes in task_struct.
    They are uncoditionally updated in every fork, read, write and sendfile.
    They are used only if you have some "extended acct fields feature".

    And please, please, please, read(2) knows about bytes, not characters,
    why it is called "rchar"?

    Signed-off-by: Alexey Dobriyan
    Cc: Jay Lan
    Cc: Balbir Singh
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Alexey Dobriyan