1
linux/fs/nfs
Andi Kleen ef3d0fd27e vfs: do (nearly) lockless generic_file_llseek
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 <ak@linux.intel.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
2011-10-28 14:58:58 +02:00
..
blocklayout nfs: add missing prefetch.h include 2011-08-04 11:54:25 -04:00
objlayout pnfs-obj: Fix the comp_index != 0 case 2011-08-04 11:54:48 -04:00
cache_lib.c switch vfs_path_lookup() to struct path 2011-07-20 01:44:14 -04:00
cache_lib.h atomic: use <linux/atomic.h> 2011-07-26 16:49:47 -07:00
callback_proc.c NFSv4.1: Return NFS4ERR_BADSESSION to callbacks during session resets 2011-08-04 11:55:35 -04:00
callback_xdr.c NFSv4.1: Fix the callback 'highest_used_slotid' behaviour 2011-08-04 11:55:35 -04:00
callback.c NFS do not find client in NFSv4 pg_authenticate 2011-01-25 15:26:51 -05:00
callback.h NFSv4.1: Fix the callback 'highest_used_slotid' behaviour 2011-08-04 11:55:35 -04:00
client.c pnfsblock: add device operations 2011-07-31 12:18:16 -04:00
delegation.c NFSv4: Don't use the delegation->inode in nfs_mark_return_delegation() 2011-07-25 15:37:29 -04:00
delegation.h NFS: Move cl_delegations to the nfs_server struct 2011-01-06 14:57:46 -05:00
dir.c Additional readdir cookie loop information 2011-07-30 14:37:14 -04:00
direct.c atomic: use <linux/atomic.h> 2011-07-26 16:49:47 -07:00
dns_resolve.c
dns_resolve.h
file.c vfs: do (nearly) lockless generic_file_llseek 2011-10-28 14:58:58 +02:00
fscache-index.c
fscache.c FS-Cache: Add a helper to bulk uncache pages on an inode 2011-07-07 13:21:56 -07:00
fscache.h
getroot.c Merge branch 'nfs-for-2.6.39' into nfs-for-next 2011-03-24 17:03:14 -04:00
idmap.c treewide: remove duplicate includes 2011-06-20 16:08:19 +02:00
inode.c nfs_open_context doesn't need struct path either 2011-07-20 01:43:44 -04:00
internal.h NFS: Clean up - simplify the switch to read/write-through-MDS 2011-07-15 09:12:22 -04:00
iostat.h
Kconfig pnfs: Automatically select blocks & objects layouts 2011-08-11 17:51:27 -07:00
Makefile pnfsblock: add blocklayout Kconfig option, Makefile, and stubs 2011-07-31 12:18:15 -04:00
mount_clnt.c NFS: Remove redundant unlikely() 2010-12-21 11:51:23 -05:00
namespace.c NFS: Add SECINFO_NO_NAME procedure 2011-07-12 13:40:27 -04:00
nfs2xdr.c Merge branch 'bugfixes' into nfs-for-2.6.38 2011-01-10 14:48:02 -05:00
nfs3acl.c switch posix_acl_create() to umode_t * 2011-08-01 02:09:42 -04:00
nfs3proc.c switch posix_acl_create() to umode_t * 2011-08-01 02:09:42 -04:00
nfs3xdr.c NFS: Fix "kernel BUG at fs/nfs/nfs3xdr.c:1338!" 2011-01-25 15:24:47 -05:00
nfs4_fs.h NFSv4: renewd needs to be able to handle the NFS4ERR_CB_PATH_DOWN error 2011-08-24 15:07:37 -04:00
nfs4filelayout.c pnfs: save layoutcommit lwb at layout header 2011-07-31 12:18:14 -04:00
nfs4filelayout.h NFSv4.1: do not use deviceids after MDS clientid invalidation 2011-07-12 13:40:29 -04:00
nfs4filelayoutdev.c NFS: fix comment 2011-07-12 13:40:27 -04:00
nfs4namespace.c nfs: nfs_do_{ref,sub}mount() superblock argument is redundant 2011-03-16 16:48:06 -04:00
nfs4proc.c NFSv4: renewd needs to be able to handle the NFS4ERR_CB_PATH_DOWN error 2011-08-24 15:07:37 -04:00
nfs4renewd.c NFSv4: The NFSv4.0 client must send RENEW calls if it holds a delegation 2011-08-24 15:07:37 -04:00
nfs4state.c NFSv4: renewd needs to be able to handle the NFS4ERR_CB_PATH_DOWN error 2011-08-24 15:07:37 -04:00
nfs4xdr.c pnfs: cleanup_layoutcommit 2011-07-31 12:18:15 -04:00
nfsroot.c NFS: Revert NFSROOT default mount options 2011-05-27 17:42:47 -04:00
pagelist.c Merge branch 'master' into devel and apply fixup from Stephen Rothwell: 2011-07-25 14:53:52 -04:00
pnfs_dev.c NFSv4.1: do not use deviceids after MDS clientid invalidation 2011-07-12 13:40:29 -04:00
pnfs.c pnfs: cleanup_layoutcommit 2011-07-31 12:18:15 -04:00
pnfs.h NFS: Re-enable compilation of nfs with !CONFIG_NFS_V4 || !CONFIG_NFS_V4_1 2011-07-31 14:27:04 -10:00
proc.c NFS: lookup supports alternate client 2011-03-24 13:52:41 -04:00
read.c Merge branch 'master' into devel and apply fixup from Stephen Rothwell: 2011-07-25 14:53:52 -04:00
super.c VFS: Fix the remaining automounter semantics regressions 2011-09-26 19:16:46 -07:00
symlink.c
sysctl.c
unlink.c nfs: don't use d_move in nfs_async_rename_done 2011-07-25 15:00:21 -04:00
write.c NFS: Fix a typo in nfs_flush_multi 2011-09-13 17:06:57 -04:00